list.php 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925
  1. <?php
  2. /* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (C) 2004-2017 Laurent Destailleur <eldy@users.sourceforge.net>
  4. * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
  5. * Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
  6. * Copyright (C) 2015 Alexandre Spangaro <aspangaro@open-dsi.fr>
  7. * Copyright (C) 2018 Ferran Marcet <fmarcet@2byte.es>
  8. * Copyright (C) 2018 Charlene Benke <charlie@patas-monkey.com>
  9. * Copyright (C) 2019 Juanjo Menent <jmenent@2byte.es>
  10. * Copyright (C) 2019-2021 Frédéric France <frederic.france@netlogic.fr>
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation; either version 3 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  24. */
  25. /**
  26. * \file htdocs/expensereport/list.php
  27. * \ingroup expensereport
  28. * \brief list of expense reports
  29. */
  30. require '../main.inc.php';
  31. require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
  32. require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
  33. require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
  34. require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
  35. require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
  36. require_once DOL_DOCUMENT_ROOT.'/core/class/html.formexpensereport.class.php';
  37. require_once DOL_DOCUMENT_ROOT.'/core/lib/usergroups.lib.php';
  38. require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport_ik.class.php';
  39. // Load translation files required by the page
  40. $langs->loadLangs(array('companies', 'users', 'trips'));
  41. $action = GETPOST('action', 'aZ09');
  42. $massaction = GETPOST('massaction', 'alpha');
  43. $show_files = GETPOST('show_files', 'int');
  44. $confirm = GETPOST('confirm', 'alpha');
  45. $cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button
  46. $toselect = GETPOST('toselect', 'array');
  47. $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'expensereportlist';
  48. $childids = $user->getAllChildIds(1);
  49. // Security check
  50. $socid = GETPOST('socid', 'int');
  51. if ($user->socid) {
  52. $socid = $user->socid;
  53. }
  54. $result = restrictedArea($user, 'expensereport', '', '');
  55. $id = GETPOST('id', 'int');
  56. // If we are on the view of a specific user
  57. if ($id > 0) {
  58. $canread = 0;
  59. if ($id == $user->id) {
  60. $canread = 1;
  61. }
  62. if (!empty($user->rights->expensereport->readall)) {
  63. $canread = 1;
  64. }
  65. if (!empty($user->rights->expensereport->lire) && in_array($id, $childids)) {
  66. $canread = 1;
  67. }
  68. if (!$canread) {
  69. accessforbidden();
  70. }
  71. }
  72. $diroutputmassaction = $conf->expensereport->dir_output.'/temp/massgeneration/'.$user->id;
  73. // Load variable for pagination
  74. $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
  75. $sortfield = GETPOST('sortfield', 'aZ09comma');
  76. $sortorder = GETPOST('sortorder', 'aZ09comma');
  77. $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
  78. if (empty($page) || $page == -1) {
  79. $page = 0;
  80. } // If $page is not defined, or '' or -1
  81. $offset = $limit * $page;
  82. $pageprev = $page - 1;
  83. $pagenext = $page + 1;
  84. if (!$sortorder) {
  85. $sortorder = "DESC";
  86. }
  87. if (!$sortfield) {
  88. $sortfield = "d.date_debut";
  89. }
  90. $sall = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'));
  91. $search_ref = GETPOST('search_ref', 'alpha');
  92. $search_user = GETPOST('search_user', 'int');
  93. $search_amount_ht = GETPOST('search_amount_ht', 'alpha');
  94. $search_amount_vat = GETPOST('search_amount_vat', 'alpha');
  95. $search_amount_ttc = GETPOST('search_amount_ttc', 'alpha');
  96. $search_status = (GETPOST('search_status', 'intcomma') != '' ?GETPOST('search_status', 'intcomma') : GETPOST('statut', 'intcomma'));
  97. $search_date_startday = GETPOST('search_date_startday', 'int');
  98. $search_date_startmonth = GETPOST('search_date_startmonth', 'int');
  99. $search_date_startyear = GETPOST('search_date_startyear', 'int');
  100. $search_date_startendday = GETPOST('search_date_startendday', 'int');
  101. $search_date_startendmonth = GETPOST('search_date_startendmonth', 'int');
  102. $search_date_startendyear = GETPOST('search_date_startendyear', 'int');
  103. $search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear); // Use tzserver
  104. $search_date_startend = dol_mktime(23, 59, 59, $search_date_startendmonth, $search_date_startendday, $search_date_startendyear);
  105. $search_date_endday = GETPOST('search_date_endday', 'int');
  106. $search_date_endmonth = GETPOST('search_date_endmonth', 'int');
  107. $search_date_endyear = GETPOST('search_date_endyear', 'int');
  108. $search_date_endendday = GETPOST('search_date_endendday', 'int');
  109. $search_date_endendmonth = GETPOST('search_date_endendmonth', 'int');
  110. $search_date_endendyear = GETPOST('search_date_endendyear', 'int');
  111. $search_date_end = dol_mktime(0, 0, 0, $search_date_endmonth, $search_date_endday, $search_date_endyear); // Use tzserver
  112. $search_date_endend = dol_mktime(23, 59, 59, $search_date_endendmonth, $search_date_endendday, $search_date_endendyear);
  113. $optioncss = GETPOST('optioncss', 'alpha');
  114. if ($search_status == '') {
  115. $search_status = -1;
  116. }
  117. if ($search_user == '') {
  118. $search_user = -1;
  119. }
  120. // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
  121. $object = new ExpenseReport($db);
  122. $hookmanager->initHooks(array('expensereportlist'));
  123. $extrafields = new ExtraFields($db);
  124. // fetch optionals attributes and labels
  125. $extrafields->fetch_name_optionals_label($object->table_element);
  126. $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
  127. // List of fields to search into when doing a "search in all"
  128. $fieldstosearchall = array(
  129. 'd.ref'=>'Ref',
  130. 'd.note_public'=>"NotePublic",
  131. 'u.lastname'=>'EmployeeLastname',
  132. 'u.firstname'=>"EmployeeFirstname",
  133. 'u.login'=>"Login",
  134. );
  135. if (empty($user->socid)) {
  136. $fieldstosearchall["d.note_private"] = "NotePrivate";
  137. }
  138. $arrayfields = array(
  139. 'd.ref'=>array('label'=>$langs->trans("Ref"), 'checked'=>1),
  140. 'user'=>array('label'=>$langs->trans("User"), 'checked'=>1),
  141. 'd.date_debut'=>array('label'=>$langs->trans("DateStart"), 'checked'=>1),
  142. 'd.date_fin'=>array('label'=>$langs->trans("DateEnd"), 'checked'=>1),
  143. 'd.date_valid'=>array('label'=>$langs->trans("DateValidation"), 'checked'=>1),
  144. 'd.date_approve'=>array('label'=>$langs->trans("DateApprove"), 'checked'=>1),
  145. 'd.total_ht'=>array('label'=>$langs->trans("AmountHT"), 'checked'=>1),
  146. 'd.total_vat'=>array('label'=>$langs->trans("AmountVAT"), 'checked'=>1),
  147. 'd.total_ttc'=>array('label'=>$langs->trans("AmountTTC"), 'checked'=>1),
  148. 'd.date_create'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
  149. 'd.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500),
  150. 'd.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000),
  151. );
  152. // Extra fields
  153. include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
  154. $canedituser = (!empty($user->admin) || $user->rights->user->user->creer);
  155. $objectuser = new User($db);
  156. /*
  157. * Actions
  158. */
  159. if (GETPOST('cancel', 'alpha')) {
  160. $action = 'list'; $massaction = '';
  161. }
  162. if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
  163. $massaction = '';
  164. }
  165. $parameters = array('socid'=>$socid);
  166. $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
  167. if ($reshook < 0) {
  168. setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
  169. }
  170. if (empty($reshook)) {
  171. // Selection of new fields
  172. include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
  173. // Purge search criteria
  174. if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
  175. $search_ref = "";
  176. $search_user = "";
  177. $search_amount_ht = "";
  178. $search_amount_vat = "";
  179. $search_amount_ttc = "";
  180. $search_status = "";
  181. $search_date_startday = '';
  182. $search_date_startmonth = '';
  183. $search_date_startyear = '';
  184. $search_date_startendday = '';
  185. $search_date_startendmonth = '';
  186. $search_date_startendyear = '';
  187. $search_date_start = '';
  188. $search_date_startend = '';
  189. $search_date_endday = '';
  190. $search_date_endmonth = '';
  191. $search_date_endyear = '';
  192. $search_date_endendday = '';
  193. $search_date_endendmonth = '';
  194. $search_date_endendyear = '';
  195. $search_date_end = '';
  196. $search_date_endend = '';
  197. $toselect = array();
  198. $search_array_options = array();
  199. }
  200. if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
  201. || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
  202. $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation
  203. }
  204. // Mass actions
  205. $objectclass = 'ExpenseReport';
  206. $objectlabel = 'ExpenseReport';
  207. $permissiontoread = $user->rights->expensereport->lire;
  208. $permissiontodelete = $user->rights->expensereport->supprimer;
  209. $uploaddir = $conf->expensereport->dir_output;
  210. include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
  211. }
  212. /*
  213. * View
  214. */
  215. $form = new Form($db);
  216. $formother = new FormOther($db);
  217. $formfile = new FormFile($db);
  218. $formexpensereport = new FormExpenseReport($db);
  219. $fuser = new User($db);
  220. $title = $langs->trans("ListOfTrips");
  221. llxHeader('', $title);
  222. $max_year = 5;
  223. $min_year = 10;
  224. // Get current user id
  225. $user_id = $user->id;
  226. if ($id > 0) {
  227. // Charge utilisateur edite
  228. $fuser->fetch($id, '', '', 1);
  229. $fuser->getrights();
  230. $user_id = $fuser->id;
  231. $search_user = $user_id;
  232. }
  233. $sql = "SELECT d.rowid, d.ref, d.fk_user_author, d.total_ht, d.total_tva, d.total_ttc, d.fk_statut as status,";
  234. $sql .= " d.date_debut, d.date_fin, d.date_create, d.tms as date_modif, d.date_valid, d.date_approve, d.note_private, d.note_public,";
  235. $sql .= " u.rowid as id_user, u.firstname, u.lastname, u.login, u.email, u.statut, u.photo";
  236. // Add fields from extrafields
  237. if (!empty($extrafields->attributes[$object->table_element]['label'])) {
  238. foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
  239. $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
  240. }
  241. }
  242. // Add fields from hooks
  243. $parameters = array();
  244. $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook
  245. $sql .= $hookmanager->resPrint;
  246. $sql .= " FROM ".MAIN_DB_PREFIX."expensereport as d";
  247. if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
  248. $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (d.rowid = ef.fk_object)";
  249. }
  250. $sql .= ", ".MAIN_DB_PREFIX."user as u";
  251. $sql .= " WHERE d.fk_user_author = u.rowid AND d.entity IN (".getEntity('expensereport').")";
  252. // Search all
  253. if (!empty($sall)) {
  254. $sql .= natural_search(array_keys($fieldstosearchall), $sall);
  255. }
  256. // Ref
  257. if (!empty($search_ref)) {
  258. $sql .= natural_search('d.ref', $search_ref);
  259. }
  260. // Date Start
  261. if ($search_date_start) {
  262. $sql .= " AND d.date_debut >= '".$db->idate($search_date_start)."'";
  263. }
  264. if ($search_date_startend) {
  265. $sql .= " AND d.date_debut <= '".$db->idate($search_date_startend)."'";
  266. }
  267. // Date End
  268. if ($search_date_end) {
  269. $sql .= " AND d.date_fin >= '".$db->idate($search_date_end)."'";
  270. }
  271. if ($search_date_endend) {
  272. $sql .= " AND d.date_fin <= '".$db->idate($search_date_endend)."'";
  273. }
  274. if ($search_amount_ht != '') {
  275. $sql .= natural_search('d.total_ht', $search_amount_ht, 1);
  276. }
  277. if ($search_amount_ttc != '') {
  278. $sql .= natural_search('d.total_ttc', $search_amount_ttc, 1);
  279. }
  280. // User
  281. if ($search_user != '' && $search_user >= 0) {
  282. $sql .= " AND u.rowid = '".$db->escape($search_user)."'";
  283. }
  284. // Status
  285. if ($search_status != '' && $search_status >= 0) {
  286. $sql .= " AND d.fk_statut IN (".$db->sanitize($search_status).")";
  287. }
  288. // RESTRICT RIGHTS
  289. if (empty($user->rights->expensereport->readall) && empty($user->rights->expensereport->lire_tous)
  290. && (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || empty($user->rights->expensereport->writeall_advance))) {
  291. $sql .= " AND d.fk_user_author IN (".$db->sanitize(join(',', $childids)).")\n";
  292. }
  293. // Add where from extra fields
  294. include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
  295. // Add where from hooks
  296. $parameters = array();
  297. $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
  298. $sql .= $hookmanager->resPrint;
  299. $sql .= $db->order($sortfield, $sortorder);
  300. // Count total nb of records
  301. $nbtotalofrecords = '';
  302. if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
  303. $result = $db->query($sql);
  304. $nbtotalofrecords = $db->num_rows($result);
  305. if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
  306. $page = 0;
  307. $offset = 0;
  308. }
  309. }
  310. $sql .= $db->plimit($limit + 1, $offset);
  311. //print $sql;
  312. $resql = $db->query($sql);
  313. if ($resql) {
  314. $num = $db->num_rows($resql);
  315. $arrayofselected = is_array($toselect) ? $toselect : array();
  316. $param = '';
  317. if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
  318. $param .= '&contextpage='.urlencode($contextpage);
  319. }
  320. if ($limit > 0 && $limit != $conf->liste_limit) {
  321. $param .= '&limit='.urlencode($limit);
  322. }
  323. if ($sall) {
  324. $param .= "&sall=".urlencode($sall);
  325. }
  326. if ($search_ref) {
  327. $param .= "&search_ref=".urlencode($search_ref);
  328. }
  329. // Start date
  330. if ($search_date_startday) {
  331. $param .= '&search_date_startday='.urlencode($search_date_startday);
  332. }
  333. if ($search_date_startmonth) {
  334. $param .= '&search_date_startmonth='.urlencode($search_date_startmonth);
  335. }
  336. if ($search_date_startyear) {
  337. $param .= '&search_date_startyear='.urlencode($search_date_startyear);
  338. }
  339. if ($search_date_startendday) {
  340. $param .= '&search_date_startendday='.urlencode($search_date_startendday);
  341. }
  342. if ($search_date_startendmonth) {
  343. $param .= '&search_date_startendmonth='.urlencode($search_date_startendmonth);
  344. }
  345. if ($search_date_startendyear) {
  346. $param .= '&search_date_startendyear='.urlencode($search_date_startendyear);
  347. }
  348. // End date
  349. if ($search_date_endday) {
  350. $param .= '&search_date_endday='.urlencode($search_date_endday);
  351. }
  352. if ($search_date_endmonth) {
  353. $param .= '&search_date_endmonth='.urlencode($search_date_endmonth);
  354. }
  355. if ($search_date_endyear) {
  356. $param .= '&search_date_endyear='.urlencode($search_date_endyear);
  357. }
  358. if ($search_date_endendday) {
  359. $param .= '&search_date_endendday='.urlencode($search_date_endendday);
  360. }
  361. if ($search_date_endendmonth) {
  362. $param .= '&search_date_endendmonth='.urlencode($search_date_endendmonth);
  363. }
  364. if ($search_date_endendyear) {
  365. $param .= '&search_date_endendyear='.urlencode($search_date_endendyear);
  366. }
  367. if ($search_user) {
  368. $param .= "&search_user=".urlencode($search_user);
  369. }
  370. if ($search_amount_ht) {
  371. $param .= "&search_amount_ht=".urlencode($search_amount_ht);
  372. }
  373. if ($search_amount_ttc) {
  374. $param .= "&search_amount_ttc=".urlencode($search_amount_ttc);
  375. }
  376. if ($search_status >= 0) {
  377. $param .= "&search_status=".urlencode($search_status);
  378. }
  379. if ($optioncss != '') {
  380. $param .= '&optioncss='.urlencode($optioncss);
  381. }
  382. // Add $param from extra fields
  383. include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
  384. // List of mass actions available
  385. $arrayofmassactions = array(
  386. 'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"),
  387. 'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
  388. 'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
  389. );
  390. if ($user->rights->expensereport->supprimer) {
  391. $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
  392. }
  393. if (in_array($massaction, array('presend', 'predelete'))) {
  394. $arrayofmassactions = array();
  395. }
  396. $massactionbutton = $form->selectMassAction('', $arrayofmassactions);
  397. // Lines of title fields
  398. print '<form id="searchFormList" action="'.$_SERVER["PHP_SELF"].'" method="POST">'."\n";
  399. if ($optioncss != '') {
  400. print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
  401. }
  402. print '<input type="hidden" name="token" value="'.newToken().'">';
  403. print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
  404. print '<input type="hidden" name="action" value="'.($action == 'edit' ? 'update' : 'list').'">';
  405. print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
  406. print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
  407. print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
  408. if ($id > 0) {
  409. print '<input type="hidden" name="id" value="'.$id.'">';
  410. }
  411. if ($id > 0) { // For user tab
  412. $title = $langs->trans("User");
  413. $linkback = '<a href="'.DOL_URL_ROOT.'/user/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
  414. $head = user_prepare_head($fuser);
  415. print dol_get_fiche_head($head, 'expensereport', $title, -1, 'user');
  416. dol_banner_tab($fuser, 'id', $linkback, $user->rights->user->user->lire || $user->admin);
  417. print dol_get_fiche_end();
  418. if ($action != 'edit') {
  419. print '<div class="tabsAction">';
  420. $childids = $user->getAllChildIds(1);
  421. $canedit = ((in_array($user_id, $childids) && $user->rights->expensereport->creer)
  422. || ($conf->global->MAIN_USE_ADVANCED_PERMS && $user->rights->expensereport->writeall_advance));
  423. // Buttons for actions
  424. if ($canedit) {
  425. print '<a href="'.DOL_URL_ROOT.'/expensereport/card.php?action=create&fk_user_author='.$fuser->id.'" class="butAction">'.$langs->trans("AddTrip").'</a>';
  426. } else {
  427. print '<a href="#" class="butActionRefused" title="'.$langs->trans("NotEnoughPermission").'">'.$langs->trans("AddTrip").'</a>';
  428. }
  429. print '</div>';
  430. } else {
  431. print $form->buttonsSaveCancel("Save", '');
  432. }
  433. } else {
  434. $title = $langs->trans("ListTripsAndExpenses");
  435. $url = DOL_URL_ROOT.'/expensereport/card.php?action=create';
  436. if (!empty($socid)) {
  437. $url .= '&socid='.$socid;
  438. }
  439. $newcardbutton = dolGetButtonTitle($langs->trans('NewTrip'), '', 'fa fa-plus-circle', $url, '', $user->rights->expensereport->creer);
  440. print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'trip', 0, $newcardbutton, '', $limit, 0, 0, 1);
  441. }
  442. $topicmail = "SendExpenseReport";
  443. $modelmail = "expensereport";
  444. $objecttmp = new ExpenseReport($db);
  445. $trackid = 'exp'.$object->id;
  446. include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
  447. if ($sall) {
  448. foreach ($fieldstosearchall as $key => $val) {
  449. $fieldstosearchall[$key] = $langs->trans($val);
  450. }
  451. print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $sall).join(', ', $fieldstosearchall).'</div>';
  452. }
  453. $moreforfilter = '';
  454. $parameters = array();
  455. $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
  456. if (empty($reshook)) {
  457. $moreforfilter .= $hookmanager->resPrint;
  458. } else {
  459. $moreforfilter = $hookmanager->resPrint;
  460. }
  461. if (!empty($moreforfilter)) {
  462. print '<div class="liste_titre liste_titre_bydiv centpercent">';
  463. print $moreforfilter;
  464. print '</div>';
  465. }
  466. $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
  467. $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
  468. $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
  469. print '<div class="div-table-responsive">';
  470. print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
  471. // Filters
  472. print '<tr class="liste_titre_filter">';
  473. if (!empty($arrayfields['d.ref']['checked'])) {
  474. print '<td class="liste_titre" align="left">';
  475. print '<input class="flat" size="15" type="text" name="search_ref" value="'.$search_ref.'">';
  476. print '</td>';
  477. }
  478. // User
  479. if (!empty($arrayfields['user']['checked'])) {
  480. if ($user->rights->expensereport->readall || $user->rights->expensereport->lire_tous) {
  481. print '<td class="liste_titre maxwidthonspartphone" align="left">';
  482. print $form->select_dolusers($search_user, 'search_user', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth200');
  483. print '</td>';
  484. } else {
  485. print '<td class="liste_titre">&nbsp;</td>';
  486. }
  487. }
  488. // Date start
  489. if (!empty($arrayfields['d.date_debut']['checked'])) {
  490. print '<td class="liste_titre" align="center">';
  491. print '<div class="nowrap">';
  492. print $form->selectDate($search_date_start ? $search_date_start : -1, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
  493. print '</div>';
  494. print '<div class="nowrap">';
  495. print $form->selectDate($search_date_startend ? $search_date_startend : -1, 'search_date_startend', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
  496. print '</div>';
  497. print '</td>';
  498. }
  499. // Date end
  500. if (!empty($arrayfields['d.date_fin']['checked'])) {
  501. print '<td class="liste_titre" align="center">';
  502. print '<div class="nowrap">';
  503. print $form->selectDate($search_date_end ? $search_date_end : -1, 'search_date_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
  504. print '</div>';
  505. print '<div class="nowrap">';
  506. print $form->selectDate($search_date_endend ? $search_date_endend : -1, 'search_date_endend', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
  507. print '</div>';
  508. print '</td>';
  509. }
  510. // Date valid
  511. if (!empty($arrayfields['d.date_valid']['checked'])) {
  512. print '<td class="liste_titre" align="center">';
  513. //print '<input class="flat" type="text" size="1" maxlength="2" name="month_end" value="'.$month_end.'">';
  514. //print $formother->selectyear($year_end,'year_end',1, $min_year, $max_year);
  515. print '</td>';
  516. }
  517. // Date approve
  518. if (!empty($arrayfields['d.date_approve']['checked'])) {
  519. print '<td class="liste_titre" align="center">';
  520. //print '<input class="flat" type="text" size="1" maxlength="2" name="month_end" value="'.$month_end.'">';
  521. //print $formother->selectyear($year_end,'year_end',1, $min_year, $max_year);
  522. print '</td>';
  523. }
  524. // Amount with no tax
  525. if (!empty($arrayfields['d.total_ht']['checked'])) {
  526. print '<td class="liste_titre right"><input class="flat" type="text" size="5" name="search_amount_ht" value="'.$search_amount_ht.'"></td>';
  527. }
  528. if (!empty($arrayfields['d.total_vat']['checked'])) {
  529. print '<td class="liste_titre right"><input class="flat" type="text" size="5" name="search_amount_vat" value="'.$search_amount_vat.'"></td>';
  530. }
  531. // Amount with all taxes
  532. if (!empty($arrayfields['d.total_ttc']['checked'])) {
  533. print '<td class="liste_titre right"><input class="flat" type="text" size="5" name="search_amount_ttc" value="'.$search_amount_ttc.'"></td>';
  534. }
  535. // Extra fields
  536. include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
  537. // Fields from hook
  538. $parameters = array('arrayfields'=>$arrayfields);
  539. $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook
  540. print $hookmanager->resPrint;
  541. // Date creation
  542. if (!empty($arrayfields['d.date_create']['checked'])) {
  543. print '<td class="liste_titre">';
  544. print '</td>';
  545. }
  546. // Date modification
  547. if (!empty($arrayfields['d.tms']['checked'])) {
  548. print '<td class="liste_titre">';
  549. print '</td>';
  550. }
  551. // Status
  552. if (!empty($arrayfields['d.fk_statut']['checked'])) {
  553. print '<td class="liste_titre right">';
  554. $formexpensereport->selectExpensereportStatus($search_status, 'search_status', 1, 1);
  555. print '</td>';
  556. }
  557. // Action column
  558. print '<td class="liste_titre maxwidthsearch">';
  559. $searchpicto = $form->showFilterButtons();
  560. print $searchpicto;
  561. print '</td>';
  562. print "</tr>\n";
  563. print '<tr class="liste_titre">';
  564. if (!empty($arrayfields['d.ref']['checked'])) {
  565. print_liste_field_titre($arrayfields['d.ref']['label'], $_SERVER["PHP_SELF"], "d.ref", "", $param, '', $sortfield, $sortorder);
  566. }
  567. if (!empty($arrayfields['user']['checked'])) {
  568. print_liste_field_titre($arrayfields['user']['label'], $_SERVER["PHP_SELF"], "u.lastname", "", $param, '', $sortfield, $sortorder);
  569. }
  570. if (!empty($arrayfields['d.date_debut']['checked'])) {
  571. print_liste_field_titre($arrayfields['d.date_debut']['label'], $_SERVER["PHP_SELF"], "d.date_debut", "", $param, 'align="center"', $sortfield, $sortorder);
  572. }
  573. if (!empty($arrayfields['d.date_fin']['checked'])) {
  574. print_liste_field_titre($arrayfields['d.date_fin']['label'], $_SERVER["PHP_SELF"], "d.date_fin", "", $param, 'align="center"', $sortfield, $sortorder);
  575. }
  576. if (!empty($arrayfields['d.date_valid']['checked'])) {
  577. print_liste_field_titre($arrayfields['d.date_valid']['label'], $_SERVER["PHP_SELF"], "d.date_valid", "", $param, 'align="center"', $sortfield, $sortorder);
  578. }
  579. if (!empty($arrayfields['d.date_approve']['checked'])) {
  580. print_liste_field_titre($arrayfields['d.date_approve']['label'], $_SERVER["PHP_SELF"], "d.date_approve", "", $param, 'align="center"', $sortfield, $sortorder);
  581. }
  582. if (!empty($arrayfields['d.total_ht']['checked'])) {
  583. print_liste_field_titre($arrayfields['d.total_ht']['label'], $_SERVER["PHP_SELF"], "d.total_ht", "", $param, 'align="right"', $sortfield, $sortorder);
  584. }
  585. if (!empty($arrayfields['d.total_vat']['checked'])) {
  586. print_liste_field_titre($arrayfields['d.total_vat']['label'], $_SERVER["PHP_SELF"], "d.total_tva", "", $param, 'align="right"', $sortfield, $sortorder);
  587. }
  588. if (!empty($arrayfields['d.total_ttc']['checked'])) {
  589. print_liste_field_titre($arrayfields['d.total_ttc']['label'], $_SERVER["PHP_SELF"], "d.total_ttc", "", $param, 'align="right"', $sortfield, $sortorder);
  590. }
  591. // Extra fields
  592. include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
  593. // Hook fields
  594. $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder);
  595. $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook
  596. print $hookmanager->resPrint;
  597. if (!empty($arrayfields['d.date_create']['checked'])) {
  598. print_liste_field_titre($arrayfields['d.date_create']['label'], $_SERVER["PHP_SELF"], "d.date_create", "", $param, 'align="center" class="nowrap"', $sortfield, $sortorder);
  599. }
  600. if (!empty($arrayfields['d.tms']['checked'])) {
  601. print_liste_field_titre($arrayfields['d.tms']['label'], $_SERVER["PHP_SELF"], "d.tms", "", $param, 'align="center" class="nowrap"', $sortfield, $sortorder);
  602. }
  603. if (!empty($arrayfields['d.fk_statut']['checked'])) {
  604. print_liste_field_titre($arrayfields['d.fk_statut']['label'], $_SERVER["PHP_SELF"], "d.fk_statut", "", $param, 'align="right"', $sortfield, $sortorder);
  605. }
  606. print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', 'align="center"', $sortfield, $sortorder, 'maxwidthsearch ');
  607. print "</tr>\n";
  608. $total_total_ht = 0;
  609. $total_total_ttc = 0;
  610. $total_total_tva = 0;
  611. $expensereportstatic = new ExpenseReport($db);
  612. $usertmp = new User($db);
  613. if ($num > 0) {
  614. $i = 0;
  615. $totalarray = array();
  616. $totalarray['nbfield'] = 0;
  617. $totalarray['val'] = array();
  618. $totalarray['val']['d.total_ht'] = 0;
  619. $totalarray['val']['d.total_tva'] = 0;
  620. $totalarray['val']['d.total_ttc'] = 0;
  621. $totalarray['totalizable'] = array();
  622. while ($i < min($num, $limit)) {
  623. $obj = $db->fetch_object($resql);
  624. $expensereportstatic->id = $obj->rowid;
  625. $expensereportstatic->ref = $obj->ref;
  626. $expensereportstatic->status = $obj->status;
  627. $expensereportstatic->date_debut = $db->jdate($obj->date_debut);
  628. $expensereportstatic->date_fin = $db->jdate($obj->date_fin);
  629. $expensereportstatic->date_create = $db->jdate($obj->date_create);
  630. $expensereportstatic->date_modif = $db->jdate($obj->date_modif);
  631. $expensereportstatic->date_valid = $db->jdate($obj->date_valid);
  632. $expensereportstatic->date_approve = $db->jdate($obj->date_approve);
  633. $expensereportstatic->note_private = $obj->note_private;
  634. $expensereportstatic->note_public = $obj->note_public;
  635. print '<tr class="oddeven">';
  636. // Ref
  637. if (!empty($arrayfields['d.ref']['checked'])) {
  638. print '<td>';
  639. print '<table class="nobordernopadding"><tr class="nocellnopadd">';
  640. print '<td class="nobordernopadding nowrap">';
  641. print $expensereportstatic->getNomUrl(1);
  642. print '</td>';
  643. // Warning late icon and note
  644. print '<td class="nobordernopadding nowrap">';
  645. if ($expensereportstatic->status == 2 && $expensereportstatic->hasDelay('toappove')) {
  646. print img_warning($langs->trans("Late"));
  647. }
  648. if ($expensereportstatic->status == 5 && $expensereportstatic->hasDelay('topay')) {
  649. print img_warning($langs->trans("Late"));
  650. }
  651. if (!empty($obj->note_private) || !empty($obj->note_public)) {
  652. print ' <span class="note">';
  653. print '<a href="'.DOL_URL_ROOT.'/expensereport/note.php?id='.$obj->rowid.'">'.img_picto($langs->trans("ViewPrivateNote"), 'object_generic').'</a>';
  654. print '</span>';
  655. }
  656. print '</td>';
  657. print '<td width="16" class="nobordernopadding hideonsmartphone right">';
  658. $filename = dol_sanitizeFileName($obj->ref);
  659. $filedir = $conf->expensereport->dir_output.'/'.dol_sanitizeFileName($obj->ref);
  660. $urlsource = $_SERVER['PHP_SELF'].'?id='.$obj->rowid;
  661. print $formfile->getDocumentsLink($expensereportstatic->element, $filename, $filedir);
  662. print '</td>';
  663. print '</tr></table>';
  664. print '</td>';
  665. if (!$i) {
  666. $totalarray['nbfield']++;
  667. }
  668. }
  669. // User
  670. if (!empty($arrayfields['user']['checked'])) {
  671. print '<td class="left">';
  672. $usertmp->id = $obj->id_user;
  673. $usertmp->lastname = $obj->lastname;
  674. $usertmp->firstname = $obj->firstname;
  675. $usertmp->login = $obj->login;
  676. $usertmp->statut = $obj->statut;
  677. $usertmp->photo = $obj->photo;
  678. $usertmp->email = $obj->email;
  679. print $usertmp->getNomUrl(-1);
  680. print '</td>';
  681. if (!$i) {
  682. $totalarray['nbfield']++;
  683. }
  684. }
  685. // Start date
  686. if (!empty($arrayfields['d.date_debut']['checked'])) {
  687. print '<td class="center">'.($obj->date_debut > 0 ? dol_print_date($db->jdate($obj->date_debut), 'day') : '').'</td>';
  688. if (!$i) {
  689. $totalarray['nbfield']++;
  690. }
  691. }
  692. // End date
  693. if (!empty($arrayfields['d.date_fin']['checked'])) {
  694. print '<td class="center">'.($obj->date_fin > 0 ? dol_print_date($db->jdate($obj->date_fin), 'day') : '').'</td>';
  695. if (!$i) {
  696. $totalarray['nbfield']++;
  697. }
  698. }
  699. // Date validation
  700. if (!empty($arrayfields['d.date_valid']['checked'])) {
  701. print '<td class="center">'.($obj->date_valid > 0 ? dol_print_date($db->jdate($obj->date_valid), 'day') : '').'</td>';
  702. if (!$i) {
  703. $totalarray['nbfield']++;
  704. }
  705. }
  706. // Date approval
  707. if (!empty($arrayfields['d.date_approve']['checked'])) {
  708. print '<td class="center">'.($obj->date_approve > 0 ? dol_print_date($db->jdate($obj->date_approve), 'day') : '').'</td>';
  709. if (!$i) {
  710. $totalarray['nbfield']++;
  711. }
  712. }
  713. // Amount HT
  714. if (!empty($arrayfields['d.total_ht']['checked'])) {
  715. print '<td class="right">'.price($obj->total_ht)."</td>\n";
  716. if (!$i) {
  717. $totalarray['nbfield']++;
  718. }
  719. if (!$i) {
  720. $totalarray['pos'][$totalarray['nbfield']] = 'd.total_ht';
  721. }
  722. $totalarray['val']['d.total_ht'] += $obj->total_ht;
  723. }
  724. // Amount VAT
  725. if (!empty($arrayfields['d.total_vat']['checked'])) {
  726. print '<td class="right">'.price($obj->total_tva)."</td>\n";
  727. if (!$i) {
  728. $totalarray['nbfield']++;
  729. }
  730. if (!$i) {
  731. $totalarray['pos'][$totalarray['nbfield']] = 'd.total_tva';
  732. }
  733. $totalarray['val']['d.total_tva'] += $obj->total_tva;
  734. }
  735. // Amount TTC
  736. if (!empty($arrayfields['d.total_ttc']['checked'])) {
  737. print '<td class="right">'.price($obj->total_ttc)."</td>\n";
  738. if (!$i) {
  739. $totalarray['nbfield']++;
  740. }
  741. if (!$i) {
  742. $totalarray['pos'][$totalarray['nbfield']] = 'd.total_ttc';
  743. }
  744. $totalarray['val']['d.total_ttc'] += $obj->total_ttc;
  745. }
  746. // Extra fields
  747. include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
  748. // Fields from hook
  749. $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray);
  750. $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook
  751. print $hookmanager->resPrint;
  752. // Date creation
  753. if (!empty($arrayfields['d.date_create']['checked'])) {
  754. print '<td class="nowrap center">';
  755. print dol_print_date($db->jdate($obj->date_create), 'dayhour');
  756. print '</td>';
  757. if (!$i) {
  758. $totalarray['nbfield']++;
  759. }
  760. }
  761. // Date modification
  762. if (!empty($arrayfields['d.tms']['checked'])) {
  763. print '<td class="nowrap center">';
  764. print dol_print_date($db->jdate($obj->date_modif), 'dayhour');
  765. print '</td>';
  766. if (!$i) {
  767. $totalarray['nbfield']++;
  768. }
  769. }
  770. // Status
  771. if (!empty($arrayfields['d.fk_statut']['checked'])) {
  772. print '<td class="nowrap right">'.$expensereportstatic->getLibStatut(5).'</td>';
  773. if (!$i) {
  774. $totalarray['nbfield']++;
  775. }
  776. }
  777. // Action column
  778. print '<td class="nowrap center">';
  779. if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
  780. $selected = 0;
  781. if (in_array($obj->rowid, $arrayofselected)) {
  782. $selected = 1;
  783. }
  784. print '<input id="cb'.$obj->rowid.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected ? ' checked="checked"' : '').'>';
  785. }
  786. print '</td>';
  787. if (!$i) {
  788. $totalarray['nbfield']++;
  789. }
  790. print "</tr>\n";
  791. $total_total_ht = $total_total_ht + $obj->total_ht;
  792. $total_total_tva = $total_total_tva + $obj->total_tva;
  793. $total_total_ttc = $total_total_ttc + $obj->total_ttc;
  794. $i++;
  795. }
  796. } else {
  797. $colspan = 1;
  798. foreach ($arrayfields as $key => $val) {
  799. if (!empty($val['checked'])) {
  800. $colspan++;
  801. }
  802. }
  803. print '<tr><td colspan="'.$colspan.'" class="opacitymedium">'.$langs->trans("NoRecordFound").'</td></tr>';
  804. }
  805. // Show total line
  806. include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
  807. $db->free($resql);
  808. $parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql);
  809. $reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters); // Note that $action and $object may have been modified by hook
  810. print $hookmanager->resPrint;
  811. print '</table>'."\n";
  812. print '</div>';
  813. print '</form>'."\n";
  814. if (empty($id)) {
  815. $hidegeneratedfilelistifempty = 1;
  816. if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
  817. $hidegeneratedfilelistifempty = 0;
  818. }
  819. // Show list of available documents
  820. $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
  821. $urlsource .= str_replace('&amp;', '&', $param);
  822. $filedir = $diroutputmassaction;
  823. $genallowed = $user->rights->expensereport->lire;
  824. $delallowed = $user->rights->expensereport->creer;
  825. print $formfile->showdocuments('massfilesarea_expensereport', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty);
  826. }
  827. } else {
  828. dol_print_error($db);
  829. }
  830. // End of page
  831. llxFooter();
  832. $db->close();