card.php 109 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903
  1. <?php
  2. /* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (C) 2004-2020 Laurent Destailleur <eldy@users.sourceforge.net>
  4. * Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
  5. * Copyright (C) 2015-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
  6. * Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
  7. * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  21. */
  22. /**
  23. * \file htdocs/expensereport/card.php
  24. * \ingroup expensereport
  25. * \brief Page for trip and expense report card
  26. */
  27. require '../main.inc.php';
  28. require_once DOL_DOCUMENT_ROOT.'/core/class/html.formexpensereport.class.php';
  29. require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
  30. require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
  31. require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
  32. require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
  33. require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
  34. require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
  35. require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
  36. require_once DOL_DOCUMENT_ROOT.'/core/lib/expensereport.lib.php';
  37. require_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php';
  38. require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
  39. require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
  40. require_once DOL_DOCUMENT_ROOT.'/core/modules/expensereport/modules_expensereport.php';
  41. require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
  42. require_once DOL_DOCUMENT_ROOT.'/expensereport/class/paymentexpensereport.class.php';
  43. require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
  44. require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
  45. if (!empty($conf->accounting->enabled)) {
  46. require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
  47. }
  48. // Load translation files required by the page
  49. $langs->loadLangs(array("trips", "bills", "mails"));
  50. $action = GETPOST('action', 'aZ09');
  51. $cancel = GETPOST('cancel', 'alpha');
  52. $confirm = GETPOST('confirm', 'alpha');
  53. $id = GETPOST('id', 'int');
  54. $date_start = dol_mktime(0, 0, 0, GETPOST('date_debutmonth', 'int'), GETPOST('date_debutday', 'int'), GETPOST('date_debutyear', 'int'));
  55. $date_end = dol_mktime(0, 0, 0, GETPOST('date_finmonth', 'int'), GETPOST('date_finday', 'int'), GETPOST('date_finyear', 'int'));
  56. $date = dol_mktime(0, 0, 0, GETPOST('datemonth', 'int'), GETPOST('dateday', 'int'), GETPOST('dateyear', 'int'));
  57. $fk_project = GETPOST('fk_project', 'int');
  58. $vatrate = GETPOST('vatrate', 'alpha');
  59. $ref = GETPOST("ref", 'alpha');
  60. $comments = GETPOST('comments', 'restricthtml');
  61. $fk_c_type_fees = GETPOST('fk_c_type_fees', 'int');
  62. $socid = GETPOST('socid', 'int') ?GETPOST('socid', 'int') : GETPOST('socid_id', 'int');
  63. $childids = $user->getAllChildIds(1);
  64. if (! empty($conf->global->EXPENSEREPORT_PREFILL_DATES_WITH_CURRENT_MONTH)) {
  65. if (empty($date_start)) {
  66. $date_start = dol_mktime(0, 0, 0, (int) dol_print_date(dol_now(), '%m'), 1, (int) dol_print_date(dol_now(), '%Y'));
  67. }
  68. if (empty($date_end)) {
  69. // date('t') => number of days in the month, so last day of the month too
  70. $date_end = dol_mktime(0, 0, 0, (int) dol_print_date(dol_now(), '%m'), (int) date('t'), (int) dol_print_date(dol_now(), '%Y'));
  71. }
  72. }
  73. // Hack to use expensereport dir
  74. $rootfordata = DOL_DATA_ROOT;
  75. $rootforuser = DOL_DATA_ROOT;
  76. // If multicompany module is enabled, we redefine the root of data
  77. if (!empty($conf->multicompany->enabled) && !empty($conf->entity) && $conf->entity > 1) {
  78. $rootfordata .= '/'.$conf->entity;
  79. }
  80. $conf->expensereport->dir_output = $rootfordata.'/expensereport';
  81. // Define $urlwithroot
  82. $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
  83. $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
  84. //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
  85. // PDF
  86. $hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0));
  87. $hidedesc = (GETPOST('hidedesc', 'int') ? GETPOST('hidedesc', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0));
  88. $hideref = (GETPOST('hideref', 'int') ? GETPOST('hideref', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0));
  89. $object = new ExpenseReport($db);
  90. $extrafields = new ExtraFields($db);
  91. // fetch optionals attributes and labels
  92. $extrafields->fetch_name_optionals_label($object->table_element);
  93. // Load object
  94. include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once
  95. // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
  96. $hookmanager->initHooks(array('expensereportcard', 'globalcard'));
  97. $permissionnote = $user->rights->expensereport->creer; // Used by the include of actions_setnotes.inc.php
  98. $permissiondellink = $user->rights->expensereport->creer; // Used by the include of actions_dellink.inc.php
  99. $permissiontoadd = $user->rights->expensereport->creer; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
  100. $upload_dir = $conf->expensereport->dir_output.'/'.dol_sanitizeFileName($object->ref);
  101. $projectRequired = $conf->project->enabled && ! empty($conf->global->EXPENSEREPORT_PROJECT_IS_REQUIRED);
  102. $fileRequired = !empty($conf->global->EXPENSEREPORT_FILE_IS_REQUIRED);
  103. if ($object->id > 0) {
  104. // Check current user can read this expense report
  105. $canread = 0;
  106. if (!empty($user->rights->expensereport->readall)) {
  107. $canread = 1;
  108. }
  109. if (!empty($user->rights->expensereport->lire) && in_array($object->fk_user_author, $childids)) {
  110. $canread = 1;
  111. }
  112. if (!$canread) {
  113. accessforbidden();
  114. }
  115. }
  116. $candelete = 0;
  117. if (!empty($user->rights->expensereport->supprimer)) {
  118. $candelete = 1;
  119. }
  120. if ($object->statut == ExpenseReport::STATUS_DRAFT && $user->hasRight('expensereport', 'write') && in_array($object->fk_user_author, $childids)) {
  121. $candelete = 1;
  122. }
  123. // Security check
  124. if ($user->socid) {
  125. $socid = $user->socid;
  126. }
  127. $result = restrictedArea($user, 'expensereport', $object->id, 'expensereport');
  128. $permissiontoadd = $user->rights->expensereport->creer; // Used by the include of actions_dellink.inc.php
  129. /*
  130. * Actions
  131. */
  132. $parameters = array('socid' => $socid);
  133. $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
  134. if ($reshook < 0) {
  135. setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
  136. }
  137. if (empty($reshook)) {
  138. $backurlforlist = DOL_URL_ROOT.'/expensereport/list.php';
  139. if (empty($backtopage) || ($cancel && empty($id))) {
  140. if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
  141. if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
  142. $backtopage = $backurlforlist;
  143. } else {
  144. $backtopage = DOL_URL_ROOT.'/expensereport/card.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__');
  145. }
  146. }
  147. }
  148. if ($cancel) {
  149. if (!empty($backtopageforcancel)) {
  150. header("Location: ".$backtopageforcancel);
  151. exit;
  152. } elseif (!empty($backtopage)) {
  153. header("Location: ".$backtopage);
  154. exit;
  155. }
  156. $action = '';
  157. $fk_project = '';
  158. $date_start = '';
  159. $date_end = '';
  160. $date = '';
  161. $comments = '';
  162. $vatrate = '';
  163. $value_unit_ht = '';
  164. $value_unit = '';
  165. $qty = 1;
  166. $fk_c_type_fees = -1;
  167. }
  168. include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php';
  169. if (!empty(GETPOST('sendit', 'alpha'))) { // If we just submit a file
  170. if ($action == 'updateline') {
  171. $action = 'editline'; // To avoid to make the updateline now
  172. } else {
  173. $action = ''; // To avoid to make the addline now
  174. }
  175. }
  176. include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once
  177. include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once
  178. include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be include, not include_once
  179. // Action clone object
  180. if ($action == 'confirm_clone' && $confirm == 'yes' && $user->rights->expensereport->creer) {
  181. if (1 == 0 && !GETPOST('clone_content', 'alpha') && !GETPOST('clone_receivers', 'alpha')) {
  182. setEventMessages($langs->trans("NoCloneOptionsSpecified"), null, 'errors');
  183. } else {
  184. if ($object->id > 0) {
  185. // Because createFromClone modifies the object, we must clone it so that we can restore it later if it fails
  186. $orig = clone $object;
  187. $result = $object->createFromClone($user, GETPOST('fk_user_author', 'int'));
  188. if ($result > 0) {
  189. header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result);
  190. exit;
  191. } else {
  192. setEventMessages($object->error, $object->errors, 'errors');
  193. $object = $orig;
  194. $action = '';
  195. }
  196. }
  197. }
  198. }
  199. if ($action == 'confirm_delete' && GETPOST("confirm", 'alpha') == "yes" && $id > 0 && $candelete) {
  200. $object = new ExpenseReport($db);
  201. $result = $object->fetch($id);
  202. $result = $object->delete($user);
  203. if ($result >= 0) {
  204. header("Location: index.php");
  205. exit;
  206. } else {
  207. setEventMessages($object->error, $object->errors, 'errors');
  208. }
  209. }
  210. if ($action == 'add' && $user->rights->expensereport->creer) {
  211. $error = 0;
  212. $object = new ExpenseReport($db);
  213. $object->date_debut = $date_start;
  214. $object->date_fin = $date_end;
  215. $object->fk_user_author = GETPOST('fk_user_author', 'int');
  216. if (!($object->fk_user_author > 0)) {
  217. $object->fk_user_author = $user->id;
  218. }
  219. // Check that expense report is for a user inside the hierarchy, or that advanced permission for all is set
  220. if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->expensereport->creer))
  221. || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->expensereport->creer) && empty($user->rights->expensereport->writeall_advance))) {
  222. $error++;
  223. setEventMessages($langs->trans("NotEnoughPermissions"), null, 'errors');
  224. }
  225. if (!$error) {
  226. if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || empty($user->rights->expensereport->writeall_advance)) {
  227. if (!in_array($object->fk_user_author, $childids)) {
  228. $error++;
  229. setEventMessages($langs->trans("UserNotInHierachy"), null, 'errors');
  230. }
  231. }
  232. }
  233. $fuser = new User($db);
  234. $fuser->fetch($object->fk_user_author);
  235. $object->status = 1;
  236. $object->fk_c_paiement = GETPOST('fk_c_paiement', 'int');
  237. $object->fk_user_validator = GETPOST('fk_user_validator', 'int');
  238. $object->note_public = GETPOST('note_public', 'restricthtml');
  239. $object->note_private = GETPOST('note_private', 'restricthtml');
  240. // Fill array 'array_options' with data from add form
  241. if (!$error) {
  242. $ret = $extrafields->setOptionalsFromPost(null, $object);
  243. if ($ret < 0) {
  244. $error++;
  245. }
  246. }
  247. if (!$error && empty($conf->global->EXPENSEREPORT_ALLOW_OVERLAPPING_PERIODS)) {
  248. $overlappingExpenseReportID = $object->periode_existe($fuser, $object->date_debut, $object->date_fin, true);
  249. if ($overlappingExpenseReportID > 0) {
  250. $error++;
  251. setEventMessages($langs->trans("ErrorDoubleDeclaration").' <a href="'.$_SERVER['PHP_SELF'].'?id='.$overlappingExpenseReportID.'">'. $langs->trans('ShowTrip').'</a>', null, 'errors');
  252. $action = 'create';
  253. }
  254. }
  255. if (!$error) {
  256. $db->begin();
  257. $id = $object->create($user);
  258. if ($id <= 0) {
  259. $error++;
  260. }
  261. if (!$error) {
  262. $db->commit();
  263. Header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
  264. exit;
  265. } else {
  266. setEventMessages($object->error, $object->errors, 'errors');
  267. $db->rollback();
  268. $action = 'create';
  269. }
  270. }
  271. }
  272. if ($action == 'update' && $user->rights->expensereport->creer) {
  273. $object = new ExpenseReport($db);
  274. $object->fetch($id);
  275. $object->date_debut = $date_start;
  276. $object->date_fin = $date_end;
  277. if ($object->status < 3) {
  278. $object->fk_user_validator = GETPOST('fk_user_validator', 'int');
  279. }
  280. $object->fk_c_paiement = GETPOST('fk_c_paiement', 'int');
  281. $object->note_public = GETPOST('note_public', 'restricthtml');
  282. $object->note_private = GETPOST('note_private', 'restricthtml');
  283. $object->fk_user_modif = $user->id;
  284. $result = $object->update($user);
  285. if ($result > 0) {
  286. header("Location: ".$_SERVER["PHP_SELF"]."?id=".GETPOST('id', 'int'));
  287. exit;
  288. } else {
  289. setEventMessages($object->error, $object->errors, 'errors');
  290. }
  291. }
  292. if ($action == 'update_extras') {
  293. $object->oldcopy = dol_clone($object);
  294. // Fill array 'array_options' with data from update form
  295. $ret = $extrafields->setOptionalsFromPost(null, $object, GETPOST('attribute', 'restricthtml'));
  296. if ($ret < 0) {
  297. $error++;
  298. }
  299. if (!$error) {
  300. // Actions on extra fields
  301. $result = $object->insertExtraFields('EXPENSEREPORT_MODIFY');
  302. if ($result < 0) {
  303. setEventMessages($object->error, $object->errors, 'errors');
  304. $error++;
  305. }
  306. }
  307. if ($error) {
  308. $action = 'edit_extras';
  309. }
  310. }
  311. if ($action == "confirm_validate" && GETPOST("confirm", 'alpha') == "yes" && $id > 0 && $user->rights->expensereport->creer) {
  312. $error = 0;
  313. $db->begin();
  314. $object = new ExpenseReport($db);
  315. $object->fetch($id);
  316. $result = $object->setValidate($user);
  317. if ($result >= 0) {
  318. // Define output language
  319. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
  320. $outputlangs = $langs;
  321. $newlang = '';
  322. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
  323. $newlang = GETPOST('lang_id', 'aZ09');
  324. }
  325. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
  326. $newlang = $object->thirdparty->default_lang;
  327. }
  328. if (!empty($newlang)) {
  329. $outputlangs = new Translate("", $conf);
  330. $outputlangs->setDefaultLang($newlang);
  331. }
  332. $model = $object->model_pdf;
  333. $ret = $object->fetch($id); // Reload to get new records
  334. $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
  335. }
  336. } else {
  337. setEventMessages($object->error, $object->errors, 'errors');
  338. $error++;
  339. }
  340. if (!$error && $result > 0 && $object->fk_user_validator > 0) {
  341. $langs->load("mails");
  342. // TO
  343. $destinataire = new User($db);
  344. $destinataire->fetch($object->fk_user_validator);
  345. $emailTo = $destinataire->email;
  346. // FROM
  347. $expediteur = new User($db);
  348. $expediteur->fetch($object->fk_user_author);
  349. $emailFrom = $conf->global->MAIN_MAIL_EMAIL_FROM;
  350. if ($emailTo && $emailFrom) {
  351. $filename = array(); $filedir = array(); $mimetype = array();
  352. // SUBJECT
  353. $societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
  354. if (!empty($conf->global->MAIN_APPLICATION_TITLE)) {
  355. $societeName = $conf->global->MAIN_APPLICATION_TITLE;
  356. }
  357. $subject = $societeName." - ".$langs->transnoentities("ExpenseReportWaitingForApproval");
  358. // CONTENT
  359. $link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
  360. $link = '<a href="'.$link.'">'.$link.'</a>';
  361. $message = $langs->transnoentities("ExpenseReportWaitingForApprovalMessage", $expediteur->getFullName($langs), get_date_range($object->date_debut, $object->date_fin, '', $langs), $link);
  362. // Rebuild pdf
  363. /*
  364. $object->setDocModel($user,"");
  365. $resultPDF = expensereport_pdf_create($db,$id,'',"",$langs);
  366. if($resultPDF):
  367. // ATTACHMENT
  368. array_push($filename,dol_sanitizeFileName($object->ref).".pdf");
  369. array_push($filedir,$conf->expensereport->dir_output . "/" . dol_sanitizeFileName($object->ref) . "/" . dol_sanitizeFileName($object->ref).".pdf");
  370. array_push($mimetype,"application/pdf");
  371. */
  372. // PREPARE SEND
  373. $mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
  374. if ($mailfile) {
  375. // SEND
  376. $result = $mailfile->sendfile();
  377. if ($result) {
  378. $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($emailFrom, 2), $mailfile->getValidAddress($emailTo, 2));
  379. setEventMessages($mesg, null, 'mesgs');
  380. } else {
  381. $langs->load("other");
  382. if ($mailfile->error) {
  383. $mesg = '';
  384. $mesg .= $langs->trans('ErrorFailedToSendMail', $emailFrom, $emailTo);
  385. $mesg .= '<br>'.$mailfile->error;
  386. setEventMessages($mesg, null, 'errors');
  387. } else {
  388. setEventMessages('No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS', null, 'warnings');
  389. }
  390. }
  391. } else {
  392. setEventMessages($mailfile->error, $mailfile->errors, 'errors');
  393. $action = '';
  394. }
  395. } else {
  396. setEventMessages($langs->trans("NoEmailSentBadSenderOrRecipientEmail"), null, 'warnings');
  397. $action = '';
  398. }
  399. }
  400. if (!$error) {
  401. $db->commit();
  402. header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
  403. exit;
  404. } else {
  405. $db->rollback();
  406. }
  407. }
  408. if ($action == "confirm_save_from_refuse" && GETPOST("confirm", 'alpha') == "yes" && $id > 0 && $user->rights->expensereport->creer) {
  409. $object = new ExpenseReport($db);
  410. $object->fetch($id);
  411. $result = $object->set_save_from_refuse($user);
  412. if ($result > 0) {
  413. // Define output language
  414. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
  415. $outputlangs = $langs;
  416. $newlang = '';
  417. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
  418. $newlang = GETPOST('lang_id', 'aZ09');
  419. }
  420. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
  421. $newlang = $object->thirdparty->default_lang;
  422. }
  423. if (!empty($newlang)) {
  424. $outputlangs = new Translate("", $conf);
  425. $outputlangs->setDefaultLang($newlang);
  426. }
  427. $model = $object->model_pdf;
  428. $ret = $object->fetch($id); // Reload to get new records
  429. $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
  430. }
  431. }
  432. if ($result > 0) {
  433. // Send mail
  434. // TO
  435. $destinataire = new User($db);
  436. $destinataire->fetch($object->fk_user_validator);
  437. $emailTo = $destinataire->email;
  438. // FROM
  439. $expediteur = new User($db);
  440. $expediteur->fetch($object->fk_user_author);
  441. $emailFrom = $conf->global->MAIN_MAIL_EMAIL_FROM;
  442. if ($emailFrom && $emailTo) {
  443. $filename = array(); $filedir = array(); $mimetype = array();
  444. // SUBJECT
  445. $societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
  446. if (!empty($conf->global->MAIN_APPLICATION_TITLE)) {
  447. $societeName = $conf->global->MAIN_APPLICATION_TITLE;
  448. }
  449. $subject = $societeName." - ".$langs->transnoentities("ExpenseReportWaitingForReApproval");
  450. // CONTENT
  451. $link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
  452. $link = '<a href="'.$link.'">'.$link.'</a>';
  453. $dateRefusEx = explode(" ", $object->date_refuse);
  454. $message = $langs->transnoentities("ExpenseReportWaitingForReApprovalMessage", $dateRefusEx[0], $object->detail_refuse, $expediteur->getFullName($langs), $link);
  455. // Rebuild pdf
  456. /*
  457. $object->setDocModel($user,"");
  458. $resultPDF = expensereport_pdf_create($db,$object,'',"",$langs);
  459. if($resultPDF)
  460. {
  461. // ATTACHMENT
  462. $filename=array(); $filedir=array(); $mimetype=array();
  463. array_push($filename,dol_sanitizeFileName($object->ref).".pdf");
  464. array_push($filedir,$conf->expensereport->dir_output . "/" . dol_sanitizeFileName($object->ref) . "/" . dol_sanitizeFileName($object->ref_number).".pdf");
  465. array_push($mimetype,"application/pdf");
  466. }
  467. */
  468. // PREPARE SEND
  469. $mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
  470. if ($mailfile) {
  471. // SEND
  472. $result = $mailfile->sendfile();
  473. if ($result) {
  474. $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($emailFrom, 2), $mailfile->getValidAddress($emailTo, 2));
  475. setEventMessages($mesg, null, 'mesgs');
  476. header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
  477. exit;
  478. } else {
  479. $langs->load("other");
  480. if ($mailfile->error) {
  481. $mesg = '';
  482. $mesg .= $langs->trans('ErrorFailedToSendMail', $emailFrom, $emailTo);
  483. $mesg .= '<br>'.$mailfile->error;
  484. setEventMessages($mesg, null, 'errors');
  485. } else {
  486. setEventMessages('No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS', null, 'warnings');
  487. }
  488. }
  489. } else {
  490. setEventMessages($mailfile->error, $mailfile->errors, 'errors');
  491. $action = '';
  492. }
  493. } else {
  494. setEventMessages($langs->trans("NoEmailSentBadSenderOrRecipientEmail"), null, 'warnings');
  495. $action = '';
  496. }
  497. } else {
  498. setEventMessages($object->error, $object->errors, 'errors');
  499. }
  500. }
  501. // Approve
  502. if ($action == "confirm_approve" && GETPOST("confirm", 'alpha') == "yes" && $id > 0 && $user->rights->expensereport->approve) {
  503. $object = new ExpenseReport($db);
  504. $object->fetch($id);
  505. $result = $object->setApproved($user);
  506. if ($result > 0) {
  507. // Define output language
  508. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
  509. $outputlangs = $langs;
  510. $newlang = '';
  511. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
  512. $newlang = GETPOST('lang_id', 'aZ09');
  513. }
  514. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
  515. $newlang = $object->thirdparty->default_lang;
  516. }
  517. if (!empty($newlang)) {
  518. $outputlangs = new Translate("", $conf);
  519. $outputlangs->setDefaultLang($newlang);
  520. }
  521. $model = $object->model_pdf;
  522. $ret = $object->fetch($id); // Reload to get new records
  523. $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
  524. }
  525. }
  526. if ($result > 0) {
  527. // Send mail
  528. // TO
  529. $destinataire = new User($db);
  530. $destinataire->fetch($object->fk_user_author);
  531. $emailTo = $destinataire->email;
  532. // CC
  533. $emailCC = $conf->global->NDF_CC_EMAILS;
  534. if (empty($emailTo)) {
  535. $emailTo = $emailCC;
  536. }
  537. // FROM
  538. $expediteur = new User($db);
  539. $expediteur->fetch($object->fk_user_approve > 0 ? $object->fk_user_approve : $object->fk_user_validator);
  540. $emailFrom = $conf->global->MAIN_MAIL_EMAIL_FROM;
  541. if ($emailFrom && $emailTo) {
  542. $filename = array(); $filedir = array(); $mimetype = array();
  543. // SUBJECT
  544. $societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
  545. if (!empty($conf->global->MAIN_APPLICATION_TITLE)) {
  546. $societeName = $conf->global->MAIN_APPLICATION_TITLE;
  547. }
  548. $subject = $societeName." - ".$langs->transnoentities("ExpenseReportApproved");
  549. // CONTENT
  550. $link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
  551. $link = '<a href="'.$link.'">'.$link.'</a>';
  552. $message = $langs->transnoentities("ExpenseReportApprovedMessage", $object->ref, $destinataire->getFullName($langs), $expediteur->getFullName($langs), $link);
  553. // Rebuilt pdf
  554. /*
  555. $object->setDocModel($user,"");
  556. $resultPDF = expensereport_pdf_create($db,$object,'',"",$langs);
  557. if($resultPDF
  558. {
  559. // ATTACHMENT
  560. $filename=array(); $filedir=array(); $mimetype=array();
  561. array_push($filename,dol_sanitizeFileName($object->ref).".pdf");
  562. array_push($filedir, $conf->expensereport->dir_output."/".dol_sanitizeFileName($object->ref)."/".dol_sanitizeFileName($object->ref).".pdf");
  563. array_push($mimetype,"application/pdf");
  564. }
  565. */
  566. $mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
  567. if ($mailfile) {
  568. // SEND
  569. $result = $mailfile->sendfile();
  570. if ($result) {
  571. $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($emailFrom, 2), $mailfile->getValidAddress($emailTo, 2));
  572. setEventMessages($mesg, null, 'mesgs');
  573. header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
  574. exit;
  575. } else {
  576. $langs->load("other");
  577. if ($mailfile->error) {
  578. $mesg = '';
  579. $mesg .= $langs->trans('ErrorFailedToSendMail', $emailFrom, $emailTo);
  580. $mesg .= '<br>'.$mailfile->error;
  581. setEventMessages($mesg, null, 'errors');
  582. } else {
  583. setEventMessages('No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS', null, 'warnings');
  584. }
  585. }
  586. } else {
  587. setEventMessages($mailfile->error, $mailfile->errors, 'errors');
  588. $action = '';
  589. }
  590. } else {
  591. setEventMessages($langs->trans("NoEmailSentBadSenderOrRecipientEmail"), null, 'warnings');
  592. $action = '';
  593. }
  594. } else {
  595. setEventMessages($langs->trans("FailedtoSetToApprove"), null, 'warnings');
  596. $action = '';
  597. }
  598. }
  599. if ($action == "confirm_refuse" && GETPOST('confirm', 'alpha') == "yes" && $id > 0 && $user->rights->expensereport->approve) {
  600. $object = new ExpenseReport($db);
  601. $object->fetch($id);
  602. $detailRefuse = GETPOST('detail_refuse', 'alpha');
  603. $result = $object->setDeny($user, $detailRefuse);
  604. if ($result > 0) {
  605. // Define output language
  606. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
  607. $outputlangs = $langs;
  608. $newlang = '';
  609. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
  610. $newlang = GETPOST('lang_id', 'aZ09');
  611. }
  612. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
  613. $newlang = $object->thirdparty->default_lang;
  614. }
  615. if (!empty($newlang)) {
  616. $outputlangs = new Translate("", $conf);
  617. $outputlangs->setDefaultLang($newlang);
  618. }
  619. $model = $object->model_pdf;
  620. $ret = $object->fetch($id); // Reload to get new records
  621. $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
  622. }
  623. }
  624. if ($result > 0) {
  625. // Send mail
  626. // TO
  627. $destinataire = new User($db);
  628. $destinataire->fetch($object->fk_user_author);
  629. $emailTo = $destinataire->email;
  630. // FROM
  631. $expediteur = new User($db);
  632. $expediteur->fetch($object->fk_user_refuse);
  633. $emailFrom = $conf->global->MAIN_MAIL_EMAIL_FROM;
  634. if ($emailFrom && $emailTo) {
  635. $filename = array(); $filedir = array(); $mimetype = array();
  636. // SUBJECT
  637. $societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
  638. if (!empty($conf->global->MAIN_APPLICATION_TITLE)) {
  639. $societeName = $conf->global->MAIN_APPLICATION_TITLE;
  640. }
  641. $subject = $societeName." - ".$langs->transnoentities("ExpenseReportRefused");
  642. // CONTENT
  643. $link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
  644. $link = '<a href="'.$link.'">'.$link.'</a>';
  645. $message = $langs->transnoentities("ExpenseReportRefusedMessage", $object->ref, $destinataire->getFullName($langs), $expediteur->getFullName($langs), $detailRefuse, $link);
  646. // Rebuilt pdf
  647. /*
  648. $object->setDocModel($user,"");
  649. $resultPDF = expensereport_pdf_create($db,$object,'',"",$langs);
  650. if($resultPDF
  651. {
  652. // ATTACHMENT
  653. $filename=array(); $filedir=array(); $mimetype=array();
  654. array_push($filename,dol_sanitizeFileName($object->ref).".pdf");
  655. array_push($filedir, $conf->expensereport->dir_output."/".dol_sanitizeFileName($object->ref)."/".dol_sanitizeFileName($object->ref).".pdf");
  656. array_push($mimetype,"application/pdf");
  657. }
  658. */
  659. // PREPARE SEND
  660. $mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
  661. if ($mailfile) {
  662. // SEND
  663. $result = $mailfile->sendfile();
  664. if ($result) {
  665. $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($emailFrom, 2), $mailfile->getValidAddress($emailTo, 2));
  666. setEventMessages($mesg, null, 'mesgs');
  667. header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
  668. exit;
  669. } else {
  670. $langs->load("other");
  671. if ($mailfile->error) {
  672. $mesg = '';
  673. $mesg .= $langs->trans('ErrorFailedToSendMail', $emailFrom, $emailTo);
  674. $mesg .= '<br>'.$mailfile->error;
  675. setEventMessages($mesg, null, 'errors');
  676. } else {
  677. setEventMessages('No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS', null, 'warnings');
  678. }
  679. }
  680. } else {
  681. setEventMessages($mailfile->error, $mailfile->errors, 'errors');
  682. $action = '';
  683. }
  684. } else {
  685. setEventMessages($langs->trans("NoEmailSentBadSenderOrRecipientEmail"), null, 'warnings');
  686. $action = '';
  687. }
  688. } else {
  689. setEventMessages($langs->trans("FailedtoSetToDeny"), null, 'warnings');
  690. $action = '';
  691. }
  692. }
  693. //var_dump($user->id == $object->fk_user_validator);exit;
  694. if ($action == "confirm_cancel" && GETPOST('confirm', 'alpha') == "yes" && $id > 0 && $user->rights->expensereport->creer) {
  695. if (!GETPOST('detail_cancel', 'alpha')) {
  696. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Comment")), null, 'errors');
  697. } else {
  698. $object = new ExpenseReport($db);
  699. $object->fetch($id);
  700. if ($user->id == $object->fk_user_valid || $user->id == $object->fk_user_author) {
  701. $detailCancel = GETPOST('detail_cancel', 'alpha');
  702. $result = $object->set_cancel($user, $detailCancel);
  703. if ($result > 0) {
  704. // Define output language
  705. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
  706. $outputlangs = $langs;
  707. $newlang = '';
  708. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
  709. $newlang = GETPOST('lang_id', 'aZ09');
  710. }
  711. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
  712. $newlang = $object->thirdparty->default_lang;
  713. }
  714. if (!empty($newlang)) {
  715. $outputlangs = new Translate("", $conf);
  716. $outputlangs->setDefaultLang($newlang);
  717. }
  718. $model = $object->model_pdf;
  719. $ret = $object->fetch($id); // Reload to get new records
  720. $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
  721. }
  722. }
  723. if ($result > 0) {
  724. // Send mail
  725. // TO
  726. $destinataire = new User($db);
  727. $destinataire->fetch($object->fk_user_author);
  728. $emailTo = $destinataire->email;
  729. // FROM
  730. $expediteur = new User($db);
  731. $expediteur->fetch($object->fk_user_cancel);
  732. $emailFrom = $conf->global->MAIN_MAIL_EMAIL_FROM;
  733. if ($emailFrom && $emailTo) {
  734. $filename = array(); $filedir = array(); $mimetype = array();
  735. // SUBJECT
  736. $societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
  737. if (!empty($conf->global->MAIN_APPLICATION_TITLE)) {
  738. $societeName = $conf->global->MAIN_APPLICATION_TITLE;
  739. }
  740. $subject = $societeName." - ".$langs->transnoentities("ExpenseReportCanceled");
  741. // CONTENT
  742. $link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
  743. $link = '<a href="'.$link.'">'.$link.'</a>';
  744. $message = $langs->transnoentities("ExpenseReportCanceledMessage", $object->ref, $destinataire->getFullName($langs), $expediteur->getFullName($langs), $detailCancel, $link);
  745. // Rebuilt pdf
  746. /*
  747. $object->setDocModel($user,"");
  748. $resultPDF = expensereport_pdf_create($db,$object,'',"",$langs);
  749. if($resultPDF
  750. {
  751. // ATTACHMENT
  752. $filename=array(); $filedir=array(); $mimetype=array();
  753. array_push($filename,dol_sanitizeFileName($object->ref).".pdf");
  754. array_push($filedir, $conf->expensereport->dir_output."/".dol_sanitizeFileName($object->ref)."/".dol_sanitizeFileName($object->ref).".pdf");
  755. array_push($mimetype,"application/pdf");
  756. }
  757. */
  758. // PREPARE SEND
  759. $mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
  760. if ($mailfile) {
  761. // SEND
  762. $result = $mailfile->sendfile();
  763. if ($result) {
  764. $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($emailFrom, 2), $mailfile->getValidAddress($emailTo, 2));
  765. setEventMessages($mesg, null, 'mesgs');
  766. header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
  767. exit;
  768. } else {
  769. $langs->load("other");
  770. if ($mailfile->error) {
  771. $mesg = '';
  772. $mesg .= $langs->trans('ErrorFailedToSendMail', $emailFrom, $emailTo);
  773. $mesg .= '<br>'.$mailfile->error;
  774. setEventMessages($mesg, null, 'errors');
  775. } else {
  776. setEventMessages('No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS', null, 'warnings');
  777. }
  778. }
  779. } else {
  780. setEventMessages($mailfile->error, $mailfile->errors, 'errors');
  781. $action = '';
  782. }
  783. } else {
  784. setEventMessages($langs->trans("NoEmailSentBadSenderOrRecipientEmail"), null, 'warnings');
  785. $action = '';
  786. }
  787. } else {
  788. setEventMessages($langs->trans("FailedToSetToCancel"), null, 'warnings');
  789. $action = '';
  790. }
  791. } else {
  792. setEventMessages($object->error, $object->errors, 'errors');
  793. }
  794. }
  795. }
  796. if ($action == "confirm_setdraft" && GETPOST('confirm', 'alpha') == "yes" && $id > 0 && $user->rights->expensereport->creer) {
  797. $object = new ExpenseReport($db);
  798. $object->fetch($id);
  799. if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) {
  800. $result = $object->setStatut(0);
  801. if ($result > 0) {
  802. // Define output language
  803. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
  804. $outputlangs = $langs;
  805. $newlang = '';
  806. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
  807. $newlang = GETPOST('lang_id', 'aZ09');
  808. }
  809. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
  810. $newlang = $object->thirdparty->default_lang;
  811. }
  812. if (!empty($newlang)) {
  813. $outputlangs = new Translate("", $conf);
  814. $outputlangs->setDefaultLang($newlang);
  815. }
  816. $model = $object->model_pdf;
  817. $ret = $object->fetch($id); // Reload to get new records
  818. $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
  819. }
  820. }
  821. if ($result > 0) {
  822. header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
  823. exit;
  824. } else {
  825. setEventMessages($object->error, $object->errors, 'errors');
  826. }
  827. } else {
  828. setEventMessages("NOT_AUTHOR", '', 'errors');
  829. }
  830. }
  831. if ($action == 'set_unpaid' && $id > 0 && $user->rights->expensereport->to_paid) {
  832. $object = new ExpenseReport($db);
  833. $object->fetch($id);
  834. $result = $object->setUnpaid($user);
  835. if ($result > 0) {
  836. // Define output language
  837. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
  838. $outputlangs = $langs;
  839. $newlang = '';
  840. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
  841. $newlang = GETPOST('lang_id', 'aZ09');
  842. }
  843. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
  844. $newlang = $object->thirdparty->default_lang;
  845. }
  846. if (!empty($newlang)) {
  847. $outputlangs = new Translate("", $conf);
  848. $outputlangs->setDefaultLang($newlang);
  849. }
  850. $model = $object->model_pdf;
  851. $ret = $object->fetch($id); // Reload to get new records
  852. $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
  853. }
  854. }
  855. }
  856. if ($action == 'set_paid' && $id > 0 && $user->rights->expensereport->to_paid) {
  857. $object = new ExpenseReport($db);
  858. $object->fetch($id);
  859. $result = $object->setPaid($id, $user);
  860. if ($result > 0) {
  861. // Define output language
  862. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
  863. $outputlangs = $langs;
  864. $newlang = '';
  865. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
  866. $newlang = GETPOST('lang_id', 'aZ09');
  867. }
  868. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
  869. $newlang = $object->thirdparty->default_lang;
  870. }
  871. if (!empty($newlang)) {
  872. $outputlangs = new Translate("", $conf);
  873. $outputlangs->setDefaultLang($newlang);
  874. }
  875. $model = $object->model_pdf;
  876. $ret = $object->fetch($id); // Reload to get new records
  877. $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
  878. }
  879. }
  880. if ($result > 0) {
  881. // Send mail
  882. // TO
  883. $destinataire = new User($db);
  884. $destinataire->fetch($object->fk_user_author);
  885. $emailTo = $destinataire->email;
  886. // FROM
  887. $expediteur = new User($db);
  888. $expediteur->fetch($user->id);
  889. $emailFrom = $conf->global->MAIN_MAIL_EMAIL_FROM;
  890. if ($emailFrom && $emailTo) {
  891. $filename = array(); $filedir = array(); $mimetype = array();
  892. // SUBJECT
  893. $societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
  894. if (!empty($conf->global->MAIN_APPLICATION_TITLE)) {
  895. $societeName = $conf->global->MAIN_APPLICATION_TITLE;
  896. }
  897. $subject = $societeName." - ".$langs->transnoentities("ExpenseReportPaid");
  898. // CONTENT
  899. $link = $urlwithroot.'/expensereport/card.php?id='.$object->id;
  900. $link = '<a href="'.$link.'">'.$link.'</a>';
  901. $message = $langs->transnoentities("ExpenseReportPaidMessage", $object->ref, $destinataire->getFullName($langs), $expediteur->getFullName($langs), $link);
  902. // Generate pdf before attachment
  903. $object->setDocModel($user, "");
  904. $resultPDF = expensereport_pdf_create($db, $object, '', "", $langs);
  905. // PREPARE SEND
  906. $mailfile = new CMailFile($subject, $emailTo, $emailFrom, $message, $filedir, $mimetype, $filename, '', '', 0, -1);
  907. if ($mailfile) {
  908. // SEND
  909. $result = $mailfile->sendfile();
  910. if ($result) {
  911. $mesg = $langs->trans('MailSuccessfulySent', $mailfile->getValidAddress($emailFrom, 2), $mailfile->getValidAddress($emailTo, 2));
  912. setEventMessages($mesg, null, 'mesgs');
  913. header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
  914. exit;
  915. } else {
  916. $langs->load("other");
  917. if ($mailfile->error) {
  918. $mesg = '';
  919. $mesg .= $langs->trans('ErrorFailedToSendMail', $emailFrom, $emailTo);
  920. $mesg .= '<br>'.$mailfile->error;
  921. setEventMessages($mesg, null, 'errors');
  922. } else {
  923. setEventMessages('No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS', null, 'warnings');
  924. }
  925. }
  926. } else {
  927. setEventMessages($mailfile->error, $mailfile->errors, 'errors');
  928. $action = '';
  929. }
  930. } else {
  931. setEventMessages($langs->trans("NoEmailSentBadSenderOrRecipientEmail"), null, 'warnings');
  932. $action = '';
  933. }
  934. } else {
  935. setEventMessages($langs->trans("FailedToSetPaid"), null, 'warnings');
  936. $action = '';
  937. }
  938. }
  939. if ($action == "addline" && $user->rights->expensereport->creer) {
  940. $error = 0;
  941. // First save uploaded file
  942. $fk_ecm_files = 0;
  943. if (GETPOSTISSET('attachfile')) {
  944. $arrayoffiles = GETPOST('attachfile', 'array');
  945. if (is_array($arrayoffiles) && !empty($arrayoffiles[0])) {
  946. include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
  947. $entityprefix = ($conf->entity != '1') ? $conf->entity.'/' : '';
  948. $relativepath = 'expensereport/'.$object->ref.'/'.$arrayoffiles[0];
  949. $ecmfiles = new EcmFiles($db);
  950. $ecmfiles->fetch(0, '', $relativepath);
  951. $fk_ecm_files = $ecmfiles->id;
  952. }
  953. }
  954. // if VAT is not used in Dolibarr, set VAT rate to 0 because VAT rate is necessary.
  955. if (empty($vatrate)) {
  956. $vatrate = "0.000";
  957. }
  958. $tmpvat = price2num(preg_replace('/\s*\(.*\)/', '', $vatrate));
  959. $value_unit_ht = price2num(GETPOST('value_unit_ht', 'alpha'), 'MU');
  960. $value_unit = price2num(GETPOST('value_unit', 'alpha'), 'MU');
  961. if (empty($value_unit)) {
  962. $value_unit = price2num($value_unit_ht + ($value_unit_ht * $tmpvat / 100), 'MU');
  963. }
  964. $fk_c_exp_tax_cat = GETPOST('fk_c_exp_tax_cat', 'int');
  965. $qty = price2num(GETPOST('qty', 'alpha'));
  966. if (empty($qty)) {
  967. $qty = 1;
  968. }
  969. if (!($fk_c_type_fees > 0)) {
  970. $error++;
  971. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
  972. $action = '';
  973. }
  974. if ((float) $tmpvat < 0 || $tmpvat === '') {
  975. $error++;
  976. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("VAT")), null, 'errors');
  977. $action = '';
  978. }
  979. // If no date entered
  980. if (empty($date) || $date == "--") {
  981. $error++;
  982. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
  983. } elseif ($date < $object->date_debut || $date > ($object->date_fin + (24 * 3600 - 1))) {
  984. // Warning if date out of range
  985. $langs->load("errors");
  986. setEventMessages($langs->trans("WarningDateOfLineMustBeInExpenseReportRange"), null, 'warnings');
  987. }
  988. // If no price entered
  989. if ($value_unit == 0) {
  990. $error++;
  991. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("PriceUTTC")), null, 'errors');
  992. }
  993. // If no project entered
  994. if ($projectRequired && $fk_project <= 0) {
  995. $error++;
  996. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Project")), null, 'errors');
  997. }
  998. // If no file associated
  999. if ($fileRequired && $fk_ecm_files == 0) {
  1000. $error++;
  1001. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("File")), null, 'errors');
  1002. }
  1003. if (!$error) {
  1004. $type = 0; // TODO What if service ? We should take the type product/service from the type of expense report llx_c_type_fees
  1005. // Insert line
  1006. $result = $object->addline($qty, $value_unit, $fk_c_type_fees, $vatrate, $date, $comments, $fk_project, $fk_c_exp_tax_cat, $type, $fk_ecm_files);
  1007. if ($result > 0) {
  1008. $ret = $object->fetch($object->id); // Reload to get new records
  1009. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
  1010. // Define output language
  1011. $outputlangs = $langs;
  1012. $newlang = GETPOST('lang_id', 'alpha');
  1013. if (!empty($conf->global->MAIN_MULTILANGS) && empty($newlang)) {
  1014. $newlang = $object->thirdparty->default_lang;
  1015. }
  1016. if (!empty($newlang)) {
  1017. $outputlangs = new Translate("", $conf);
  1018. $outputlangs->setDefaultLang($newlang);
  1019. }
  1020. $object->generateDocument($object->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
  1021. }
  1022. unset($qty);
  1023. unset($value_unit_ht);
  1024. unset($value_unit);
  1025. unset($vatrate);
  1026. unset($comments);
  1027. unset($fk_c_type_fees);
  1028. unset($fk_project);
  1029. unset($date);
  1030. } else {
  1031. $error++;
  1032. setEventMessages($object->error, $object->errors, 'errors');
  1033. }
  1034. }
  1035. if (!$error) {
  1036. header("Location: ".$_SERVER["PHP_SELF"]."?id=".GETPOST('id', 'int'));
  1037. exit;
  1038. } else {
  1039. $action = '';
  1040. }
  1041. }
  1042. if ($action == 'confirm_delete_line' && GETPOST("confirm", 'alpha') == "yes" && $user->rights->expensereport->creer) {
  1043. $object = new ExpenseReport($db);
  1044. $object->fetch($id);
  1045. $object_ligne = new ExpenseReportLine($db);
  1046. $object_ligne->fetch(GETPOST("rowid", 'int'));
  1047. $total_ht = $object_ligne->total_ht;
  1048. $total_tva = $object_ligne->total_tva;
  1049. $result = $object->deleteline(GETPOST("rowid", 'int'), $user);
  1050. if ($result >= 0) {
  1051. if ($result > 0) {
  1052. // Define output language
  1053. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
  1054. $outputlangs = $langs;
  1055. $newlang = '';
  1056. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
  1057. $newlang = GETPOST('lang_id', 'aZ09');
  1058. }
  1059. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
  1060. $newlang = $object->thirdparty->default_lang;
  1061. }
  1062. if (!empty($newlang)) {
  1063. $outputlangs = new Translate("", $conf);
  1064. $outputlangs->setDefaultLang($newlang);
  1065. }
  1066. $model = $object->model_pdf;
  1067. $ret = $object->fetch($id); // Reload to get new records
  1068. $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
  1069. }
  1070. }
  1071. header("Location: ".$_SERVER["PHP_SELF"]."?id=".GETPOST('id', 'int'));
  1072. exit;
  1073. } else {
  1074. setEventMessages($object->error, $object->errors, 'errors');
  1075. }
  1076. }
  1077. if ($action == "updateline" && $user->rights->expensereport->creer) {
  1078. $object = new ExpenseReport($db);
  1079. $object->fetch($id);
  1080. // First save uploaded file
  1081. $fk_ecm_files = 0;
  1082. if (GETPOSTISSET('attachfile')) {
  1083. $arrayoffiles = GETPOST('attachfile', 'array');
  1084. if (is_array($arrayoffiles) && !empty($arrayoffiles[0])) {
  1085. include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
  1086. $relativepath = 'expensereport/'.$object->ref.'/'.$arrayoffiles[0];
  1087. $ecmfiles = new EcmFiles($db);
  1088. $ecmfiles->fetch(0, '', $relativepath);
  1089. $fk_ecm_files = $ecmfiles->id;
  1090. }
  1091. }
  1092. $rowid = GETPOST('rowid', 'int');
  1093. $type_fees_id = GETPOST('fk_c_type_fees', 'int');
  1094. $fk_c_exp_tax_cat = GETPOST('fk_c_exp_tax_cat', 'int');
  1095. $projet_id = $fk_project;
  1096. $comments = GETPOST('comments', 'restricthtml');
  1097. $qty = price2num(GETPOST('qty', 'alpha'));
  1098. $vatrate = GETPOST('vatrate', 'alpha');
  1099. // if VAT is not used in Dolibarr, set VAT rate to 0 because VAT rate is necessary.
  1100. if (empty($vatrate)) {
  1101. $vatrate = "0.000";
  1102. }
  1103. $tmpvat = price2num(preg_replace('/\s*\(.*\)/', '', $vatrate));
  1104. $value_unit_ht = price2num(GETPOST('value_unit_ht', 'alpha'), 'MU');
  1105. $value_unit = price2num(GETPOST('value_unit', 'alpha'), 'MU');
  1106. if (empty($value_unit)) {
  1107. $value_unit = price2num($value_unit_ht + ($value_unit_ht * $tmpvat / 100), 'MU');
  1108. }
  1109. if (!GETPOST('fk_c_type_fees', 'int') > 0) {
  1110. $error++;
  1111. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
  1112. $action = '';
  1113. }
  1114. if ((float) $tmpvat < 0 || $tmpvat == '') {
  1115. $error++;
  1116. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Vat")), null, 'errors');
  1117. $action = '';
  1118. }
  1119. // Warning if date out of range
  1120. if ($date < $object->date_debut || $date > ($object->date_fin + (24 * 3600 - 1))) {
  1121. $langs->load("errors");
  1122. setEventMessages($langs->trans("WarningDateOfLineMustBeInExpenseReportRange"), null, 'warnings');
  1123. }
  1124. // If no project entered
  1125. if ($projectRequired && $projet_id <= 0) {
  1126. $error++;
  1127. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Project")), null, 'errors');
  1128. }
  1129. if (!$error) {
  1130. // TODO Use update method of ExpenseReportLine
  1131. $result = $object->updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $id, $fk_c_exp_tax_cat, $fk_ecm_files);
  1132. if ($result >= 0) {
  1133. if ($result > 0) {
  1134. // Define output language
  1135. if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
  1136. $outputlangs = $langs;
  1137. $newlang = '';
  1138. if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
  1139. $newlang = GETPOST('lang_id', 'aZ09');
  1140. }
  1141. if ($conf->global->MAIN_MULTILANGS && empty($newlang)) {
  1142. $newlang = $object->thirdparty->default_lang;
  1143. }
  1144. if (!empty($newlang)) {
  1145. $outputlangs = new Translate("", $conf);
  1146. $outputlangs->setDefaultLang($newlang);
  1147. }
  1148. $model = $object->model_pdf;
  1149. $ret = $object->fetch($id); // Reload to get new records
  1150. $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
  1151. }
  1152. unset($qty);
  1153. unset($value_unit_ht);
  1154. unset($value_unit);
  1155. unset($vatrate);
  1156. unset($comments);
  1157. unset($fk_c_type_fees);
  1158. unset($fk_project);
  1159. unset($date);
  1160. }
  1161. //header("Location: ".$_SERVER["PHP_SELF"]."?id=".$id);
  1162. //exit;
  1163. } else {
  1164. setEventMessages($object->error, $object->errors, 'errors');
  1165. }
  1166. }
  1167. }
  1168. // Actions when printing a doc from card
  1169. include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
  1170. // Actions to send emails
  1171. $triggersendname = 'EXPENSEREPORT_SENTBYMAIL';
  1172. $autocopy = 'MAIN_MAIL_AUTOCOPY_EXPENSEREPORT_TO';
  1173. $trackid = 'exp'.$object->id;
  1174. include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
  1175. // Actions to build doc
  1176. $upload_dir = $conf->expensereport->dir_output;
  1177. include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
  1178. }
  1179. /*
  1180. * View
  1181. */
  1182. $title = $langs->trans("ExpenseReport")." - ".$langs->trans("Card");
  1183. $help_url = "EN:Module_Expense_Reports|FR:Module_Notes_de_frais";
  1184. llxHeader("", $title, $help_url);
  1185. $form = new Form($db);
  1186. $formfile = new FormFile($db);
  1187. $formproject = new FormProjets($db);
  1188. $projecttmp = new Project($db);
  1189. $paymentexpensereportstatic = new PaymentExpenseReport($db);
  1190. $bankaccountstatic = new Account($db);
  1191. $ecmfilesstatic = new EcmFiles($db);
  1192. $formexpensereport = new FormExpenseReport($db);
  1193. // Create
  1194. if ($action == 'create') {
  1195. print load_fiche_titre($langs->trans("NewTrip"), '', 'trip');
  1196. print '<form action="'.$_SERVER['PHP_SELF'].'" method="post" name="create">';
  1197. print '<input type="hidden" name="token" value="'.newToken().'">';
  1198. print '<input type="hidden" name="action" value="add">';
  1199. print dol_get_fiche_head('');
  1200. print '<table class="border centpercent">';
  1201. print '<tbody>';
  1202. // Date start
  1203. print '<tr>';
  1204. print '<td class="titlefieldcreate fieldrequired">'.$langs->trans("DateStart").'</td>';
  1205. print '<td>';
  1206. print $form->selectDate($date_start ? $date_start : -1, 'date_debut', 0, 0, 0, '', 1, 1);
  1207. print '</td>';
  1208. print '</tr>';
  1209. // Date end
  1210. print '<tr>';
  1211. print '<td class="fieldrequired">'.$langs->trans("DateEnd").'</td>';
  1212. print '<td>';
  1213. print $form->selectDate($date_end ? $date_end : -1, 'date_fin', 0, 0, 0, '', 1, 1);
  1214. print '</td>';
  1215. print '</tr>';
  1216. // User for expense report
  1217. print '<tr>';
  1218. print '<td class="fieldrequired">'.$langs->trans("User").'</td>';
  1219. print '<td>';
  1220. $defaultselectuser = $user->id;
  1221. if (GETPOST('fk_user_author', 'int') > 0) {
  1222. $defaultselectuser = GETPOST('fk_user_author', 'int');
  1223. }
  1224. $include_users = 'hierarchyme';
  1225. if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->expensereport->writeall_advance)) {
  1226. $include_users = array();
  1227. }
  1228. $s = $form->select_dolusers($defaultselectuser, "fk_user_author", 0, "", 0, $include_users, '', '0,'.$conf->entity);
  1229. print $s;
  1230. print '</td>';
  1231. print '</tr>';
  1232. // Approver
  1233. print '<tr>';
  1234. print '<td>'.$langs->trans("VALIDATOR").'</td>';
  1235. print '<td>';
  1236. $object = new ExpenseReport($db);
  1237. $include_users = $object->fetch_users_approver_expensereport();
  1238. if (empty($include_users)) {
  1239. print img_warning().' '.$langs->trans("NobodyHasPermissionToValidateExpenseReport");
  1240. } else {
  1241. $defaultselectuser = (empty($user->fk_user_expense_validator) ? $user->fk_user : $user->fk_user_expense_validator); // Will work only if supervisor has permission to approve so is inside include_users
  1242. if (!empty($conf->global->EXPENSEREPORT_DEFAULT_VALIDATOR)) {
  1243. $defaultselectuser = $conf->global->EXPENSEREPORT_DEFAULT_VALIDATOR; // Can force default approver
  1244. }
  1245. if (GETPOST('fk_user_validator', 'int') > 0) {
  1246. $defaultselectuser = GETPOST('fk_user_validator', 'int');
  1247. }
  1248. $s = $form->select_dolusers($defaultselectuser, "fk_user_validator", 1, "", ((empty($defaultselectuser) || empty($conf->global->EXPENSEREPORT_DEFAULT_VALIDATOR_UNCHANGEABLE)) ? 0 : 1), $include_users);
  1249. print $form->textwithpicto($s, $langs->trans("AnyOtherInThisListCanValidate"));
  1250. }
  1251. print '</td>';
  1252. print '</tr>';
  1253. // Payment mode
  1254. if (!empty($conf->global->EXPENSEREPORT_ASK_PAYMENTMODE_ON_CREATION)) {
  1255. print '<tr>';
  1256. print '<td>'.$langs->trans("ModePaiement").'</td>';
  1257. print '<td>';
  1258. $form->select_types_paiements('', 'fk_c_paiement');
  1259. print '</td>';
  1260. print '</tr>';
  1261. }
  1262. // Public note
  1263. $note_public = GETPOSTISSET('note_public') ? GETPOST('note_public', 'restricthtml') : '';
  1264. print '<tr>';
  1265. print '<td class="tdtop">'.$langs->trans('NotePublic').'</td>';
  1266. print '<td>';
  1267. $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, empty($conf->global->FCKEDITOR_ENABLE_NOTE_PUBLIC) ? 0 : 1, ROWS_3, '90%');
  1268. print $doleditor->Create(1);
  1269. print '</td></tr>';
  1270. // Private note
  1271. $note_private = GETPOSTISSET('note_private') ? GETPOST('note_private', 'restricthtml') : '';
  1272. if (empty($user->socid)) {
  1273. print '<tr>';
  1274. print '<td class="tdtop">'.$langs->trans('NotePrivate').'</td>';
  1275. print '<td>';
  1276. $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, empty($conf->global->FCKEDITOR_ENABLE_NOTE_PRIVATE) ? 0 : 1, ROWS_3, '90%');
  1277. print $doleditor->Create(1);
  1278. print '</td></tr>';
  1279. }
  1280. // Other attributes
  1281. $parameters = array('colspan' => ' colspan="3"', 'cols' => 3);
  1282. $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by
  1283. print $hookmanager->resPrint;
  1284. if (empty($reshook)) {
  1285. print $object->showOptionals($extrafields, 'create', $parameters);
  1286. }
  1287. print '<tbody>';
  1288. print '</table>';
  1289. print dol_get_fiche_end();
  1290. print $form->buttonsSaveCancel("AddTrip");
  1291. print '</form>';
  1292. } elseif ($id > 0 || $ref) {
  1293. $result = $object->fetch($id, $ref);
  1294. if ($result > 0) {
  1295. if (!in_array($object->fk_user_author, $user->getAllChildIds(1))) {
  1296. if (empty($user->rights->expensereport->readall) && empty($user->rights->expensereport->lire_tous)
  1297. && (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || empty($user->rights->expensereport->writeall_advance))) {
  1298. print load_fiche_titre($langs->trans('TripCard'), '', 'trip');
  1299. print '<div class="tabBar">';
  1300. print $langs->trans('NotUserRightToView');
  1301. print '</div>';
  1302. // End of page
  1303. llxFooter();
  1304. $db->close();
  1305. exit;
  1306. }
  1307. }
  1308. $head = expensereport_prepare_head($object);
  1309. if ($action == 'edit' && ($object->status < 3 || $object->status == 99)) {
  1310. print "<form name='update' action=\"".$_SERVER['PHP_SELF']."\" method=\"post\">\n";
  1311. print '<input type="hidden" name="token" value="'.newToken().'">';
  1312. print '<input type="hidden" name="id" value="'.$id.'">';
  1313. print dol_get_fiche_head($head, 'card', $langs->trans("ExpenseReport"), 0, 'trip');
  1314. if ($object->status == 99) {
  1315. print '<input type="hidden" name="action" value="updateFromRefuse">';
  1316. } else {
  1317. print '<input type="hidden" name="action" value="update">';
  1318. }
  1319. $linkback = '<a href="'.DOL_URL_ROOT.'/expensereport/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
  1320. print '<table class="border" style="width:100%;">';
  1321. print '<tr>';
  1322. print '<td>'.$langs->trans("User").'</td>';
  1323. print '<td>';
  1324. $userfee = new User($db);
  1325. if ($object->fk_user_author > 0) {
  1326. $userfee->fetch($object->fk_user_author);
  1327. print $userfee->getNomUrl(-1);
  1328. }
  1329. print '</td></tr>';
  1330. // Ref
  1331. print '<tr><td class="titlefieldcreate">'.$langs->trans("Ref").'</td><td>';
  1332. print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref', '');
  1333. print '</td></tr>';
  1334. print '<tr>';
  1335. print '<td>'.$langs->trans("DateStart").'</td>';
  1336. print '<td>';
  1337. print $form->selectDate($object->date_debut, 'date_debut');
  1338. print '</td>';
  1339. print '</tr>';
  1340. print '<tr>';
  1341. print '<td>'.$langs->trans("DateEnd").'</td>';
  1342. print '<td>';
  1343. print $form->selectDate($object->date_fin, 'date_fin');
  1344. print '</td>';
  1345. print '</tr>';
  1346. if (!empty($conf->global->EXPENSEREPORT_ASK_PAYMENTMODE_ON_CREATION)) {
  1347. print '<tr>';
  1348. print '<td>'.$langs->trans("ModePaiement").'</td>';
  1349. print '<td>';
  1350. $form->select_types_paiements($object->fk_c_paiement, 'fk_c_paiement');
  1351. print '</td>';
  1352. print '</tr>';
  1353. }
  1354. if ($object->status < 3) {
  1355. print '<tr>';
  1356. print '<td>'.$langs->trans("VALIDATOR").'</td>'; // Approbator
  1357. print '<td>';
  1358. $include_users = $object->fetch_users_approver_expensereport();
  1359. $s = $form->select_dolusers($object->fk_user_validator, "fk_user_validator", 1, "", 0, $include_users);
  1360. print $form->textwithpicto($s, $langs->trans("AnyOtherInThisListCanValidate"));
  1361. print '</td>';
  1362. print '</tr>';
  1363. } else {
  1364. print '<tr>';
  1365. print '<td>'.$langs->trans("VALIDOR").'</td>';
  1366. print '<td>';
  1367. $userfee = new User($db);
  1368. $userfee->fetch($object->fk_user_valid);
  1369. print $userfee->getNomUrl(-1);
  1370. print '</td></tr>';
  1371. }
  1372. if ($object->status == 6) {
  1373. print '<tr>';
  1374. print '<td>'.$langs->trans("AUTHORPAIEMENT").'</td>';
  1375. print '<td>';
  1376. $userfee = new User($db);
  1377. $userfee->fetch($user->id);
  1378. print $userfee->getNomUrl(-1);
  1379. print '</td></tr>';
  1380. }
  1381. // Other attributes
  1382. //$cols = 3;
  1383. //include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_edit.tpl.php';
  1384. print '</table>';
  1385. print dol_get_fiche_end();
  1386. print $form->buttonsSaveCancel("Modify");
  1387. print '</form>';
  1388. } else {
  1389. $taxlessUnitPriceDisabled = ! empty($conf->global->EXPENSEREPORT_FORCE_LINE_AMOUNTS_INCLUDING_TAXES_ONLY) ? ' disabled' : '';
  1390. print dol_get_fiche_head($head, 'card', $langs->trans("ExpenseReport"), -1, 'trip');
  1391. $formconfirm = '';
  1392. // Clone confirmation
  1393. if ($action == 'clone') {
  1394. // Create an array for form
  1395. $criteriaforfilter = 'hierarchyme';
  1396. if (!empty($user->rights->expensereport->readall)) {
  1397. $criteriaforfilter = '';
  1398. }
  1399. $formquestion = array(
  1400. 'text' => '',
  1401. array('type' => 'other', 'name' => 'fk_user_author', 'label' => $langs->trans("SelectTargetUser"), 'value' => $form->select_dolusers((GETPOST('fk_user_author', 'int') > 0 ? GETPOST('fk_user_author', 'int') : $user->id), 'fk_user_author', 0, null, 0, $criteriaforfilter, '', '0', 0, 0, '', 0, '', 'maxwidth150'))
  1402. );
  1403. // Paiement incomplet. On demande si motif = escompte ou autre
  1404. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneExpenseReport', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
  1405. }
  1406. if ($action == 'save') {
  1407. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("SaveTrip"), $langs->trans("ConfirmSaveTrip"), "confirm_validate", "", "", 1);
  1408. }
  1409. if ($action == 'save_from_refuse') {
  1410. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("SaveTrip"), $langs->trans("ConfirmSaveTrip"), "confirm_save_from_refuse", "", "", 1);
  1411. }
  1412. if ($action == 'delete') {
  1413. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("DeleteTrip"), $langs->trans("ConfirmDeleteTrip"), "confirm_delete", "", "", 1);
  1414. }
  1415. if ($action == 'validate') {
  1416. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("ValideTrip"), $langs->trans("ConfirmValideTrip"), "confirm_approve", "", "", 1);
  1417. }
  1418. if ($action == 'paid') {
  1419. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("PaidTrip"), $langs->trans("ConfirmPaidTrip"), "confirm_paid", "", "", 1);
  1420. }
  1421. if ($action == 'cancel') {
  1422. $array_input = array('text'=>$langs->trans("ConfirmCancelTrip"), array('type'=>"text", 'label'=>'<strong>'.$langs->trans("Comment").'</strong>', 'name'=>"detail_cancel", 'value'=>""));
  1423. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("Cancel"), "", "confirm_cancel", $array_input, "", 1);
  1424. }
  1425. if ($action == 'setdraft') {
  1426. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("BrouillonnerTrip"), $langs->trans("ConfirmBrouillonnerTrip"), "confirm_setdraft", "", "", 1);
  1427. }
  1428. if ($action == 'refuse') { // Deny
  1429. $array_input = array('text'=>$langs->trans("ConfirmRefuseTrip"), array('type'=>"text", 'label'=>$langs->trans("Comment"), 'name'=>"detail_refuse", 'value'=>""));
  1430. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id, $langs->trans("Deny"), '', "confirm_refuse", $array_input, "yes", 1);
  1431. }
  1432. if ($action == 'delete_line') {
  1433. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$id."&rowid=".GETPOST('rowid', 'int'), $langs->trans("DeleteLine"), $langs->trans("ConfirmDeleteLine"), "confirm_delete_line", '', 'yes', 1);
  1434. }
  1435. // Print form confirm
  1436. print $formconfirm;
  1437. // Expense report card
  1438. $linkback = '<a href="'.DOL_URL_ROOT.'/expensereport/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
  1439. $morehtmlref = '<div class="refidno">';
  1440. /*
  1441. // Ref customer
  1442. $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, $user->rights->commande->creer, 'string', '', 0, 1);
  1443. $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, $user->rights->commande->creer, 'string', '', null, null, '', 1);
  1444. // Thirdparty
  1445. $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . $soc->getNomUrl(1);
  1446. // Project
  1447. if (! empty($conf->project->enabled))
  1448. {
  1449. $langs->load("projects");
  1450. $morehtmlref.='<br>'.$langs->trans('Project') . ' ';
  1451. if ($user->rights->commande->creer)
  1452. {
  1453. if ($action != 'classify')
  1454. $morehtmlref.='<a class="editfielda" href="' . $_SERVER['PHP_SELF'] . '?action=classify&token='.newToken().'&id=' . $object->id . '">' . img_edit($langs->transnoentitiesnoconv('SetProject')) . '</a> : ';
  1455. if ($action == 'classify') {
  1456. //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
  1457. $morehtmlref.='<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
  1458. $morehtmlref.='<input type="hidden" name="action" value="classin">';
  1459. $morehtmlref.='<input type="hidden" name="token" value="'.newToken().'">';
  1460. $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
  1461. $morehtmlref.='<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
  1462. $morehtmlref.='</form>';
  1463. } else {
  1464. $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1);
  1465. }
  1466. } else {
  1467. if (! empty($object->fk_project)) {
  1468. $proj = new Project($db);
  1469. $proj->fetch($object->fk_project);
  1470. $morehtmlref.='<a href="'.DOL_URL_ROOT.'/projet/card.php?id=' . $object->fk_project . '" title="' . $langs->trans('ShowProject') . '">';
  1471. $morehtmlref.=$proj->ref;
  1472. $morehtmlref.='</a>';
  1473. } else {
  1474. $morehtmlref.='';
  1475. }
  1476. }
  1477. }*/
  1478. $morehtmlref .= '</div>';
  1479. dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
  1480. print '<div class="fichecenter">';
  1481. print '<div class="fichehalfleft">';
  1482. print '<div class="underbanner clearboth"></div>';
  1483. print '<table class="border tableforfield centpercent">';
  1484. // Author
  1485. print '<tr>';
  1486. print '<td class="titlefield">'.$langs->trans("User").'</td>';
  1487. print '<td>';
  1488. if ($object->fk_user_author > 0) {
  1489. $userauthor = new User($db);
  1490. $result = $userauthor->fetch($object->fk_user_author);
  1491. if ($result < 0) {
  1492. dol_print_error('', $userauthor->error);
  1493. } elseif ($result > 0) {
  1494. print $userauthor->getNomUrl(-1);
  1495. }
  1496. }
  1497. print '</td></tr>';
  1498. // Period
  1499. print '<tr>';
  1500. print '<td class="titlefield">'.$langs->trans("Period").'</td>';
  1501. print '<td>';
  1502. print get_date_range($object->date_debut, $object->date_fin, 'day', $langs, 0);
  1503. print '</td>';
  1504. print '</tr>';
  1505. if (!empty($conf->global->EXPENSEREPORT_ASK_PAYMENTMODE_ON_CREATION)) {
  1506. print '<tr>';
  1507. print '<td>'.$langs->trans("ModePaiement").'</td>';
  1508. print '<td>'.$object->fk_c_paiement.'</td>';
  1509. print '</tr>';
  1510. }
  1511. // Validation date
  1512. print '<tr>';
  1513. print '<td>'.$langs->trans("DATE_SAVE").'</td>';
  1514. print '<td>'.dol_print_date($object->date_valid, 'dayhour', 'tzuser');
  1515. if ($object->status == 2 && $object->hasDelay('toapprove')) {
  1516. print ' '.img_warning($langs->trans("Late").' - '.$langs->trans("ToApprove"));
  1517. }
  1518. if ($object->status == 5 && $object->hasDelay('topay')) {
  1519. print ' '.img_warning($langs->trans("Late").' - '.$langs->trans("ToPay"));
  1520. }
  1521. print '</td></tr>';
  1522. print '</tr>';
  1523. // User to inform for approval
  1524. if ($object->status <= ExpenseReport::STATUS_VALIDATED) { // informed
  1525. print '<tr>';
  1526. print '<td>'.$langs->trans("VALIDATOR").'</td>'; // approver
  1527. print '<td>';
  1528. if ($object->fk_user_validator > 0) {
  1529. $userfee = new User($db);
  1530. $result = $userfee->fetch($object->fk_user_validator);
  1531. if ($result > 0) {
  1532. print $userfee->getNomUrl(-1);
  1533. }
  1534. if (empty($userfee->email) || !isValidEmail($userfee->email)) {
  1535. $langs->load("errors");
  1536. print img_warning($langs->trans("ErrorBadEMail", $userfee->email));
  1537. }
  1538. }
  1539. print '</td></tr>';
  1540. } elseif ($object->status == ExpenseReport::STATUS_CANCELED) {
  1541. print '<tr>';
  1542. print '<td>'.$langs->trans("CANCEL_USER").'</span></td>';
  1543. print '<td>';
  1544. if ($object->fk_user_cancel > 0) {
  1545. $userfee = new User($db);
  1546. $result = $userfee->fetch($object->fk_user_cancel);
  1547. if ($result > 0) {
  1548. print $userfee->getNomUrl(-1);
  1549. }
  1550. }
  1551. print '</td></tr>';
  1552. print '<tr>';
  1553. print '<td>'.$langs->trans("MOTIF_CANCEL").'</td>';
  1554. print '<td>'.$object->detail_cancel.'</td></tr>';
  1555. print '</tr>';
  1556. print '<tr>';
  1557. print '<td>'.$langs->trans("DATE_CANCEL").'</td>';
  1558. print '<td>'.dol_print_date($object->date_cancel, 'dayhour', 'tzuser').'</td></tr>';
  1559. print '</tr>';
  1560. } else {
  1561. print '<tr>';
  1562. print '<td>'.$langs->trans("ApprovedBy").'</td>';
  1563. print '<td>';
  1564. if ($object->fk_user_approve > 0) {
  1565. $userapp = new User($db);
  1566. $result = $userapp->fetch($object->fk_user_approve);
  1567. if ($result > 0) {
  1568. print $userapp->getNomUrl(-1);
  1569. }
  1570. }
  1571. print '</td></tr>';
  1572. print '<tr>';
  1573. print '<td>'.$langs->trans("DateApprove").'</td>';
  1574. print '<td>'.dol_print_date($object->date_approve, 'dayhour', 'tzuser').'</td></tr>';
  1575. print '</tr>';
  1576. }
  1577. if ($object->status == 99 || !empty($object->detail_refuse)) {
  1578. print '<tr>';
  1579. print '<td>'.$langs->trans("REFUSEUR").'</td>';
  1580. print '<td>';
  1581. $userfee = new User($db);
  1582. $result = $userfee->fetch($object->fk_user_refuse);
  1583. if ($result > 0) {
  1584. print $userfee->getNomUrl(-1);
  1585. }
  1586. print '</td></tr>';
  1587. print '<tr>';
  1588. print '<td>'.$langs->trans("DATE_REFUS").'</td>';
  1589. print '<td>'.dol_print_date($object->date_refuse, 'dayhour', 'tzuser');
  1590. if ($object->detail_refuse) {
  1591. print ' - '.$object->detail_refuse;
  1592. }
  1593. print '</td>';
  1594. print '</tr>';
  1595. }
  1596. if ($object->status == $object::STATUS_CLOSED) {
  1597. /* TODO this fields are not yet filled
  1598. print '<tr>';
  1599. print '<td>'.$langs->trans("AUTHORPAIEMENT").'</td>';
  1600. print '<td>';
  1601. $userfee=new User($db);
  1602. $userfee->fetch($object->fk_user_paid);
  1603. print $userfee->getNomUrl(-1);
  1604. print '</td></tr>';
  1605. print '<tr>';
  1606. print '<td>'.$langs->trans("DATE_PAIEMENT").'</td>';
  1607. print '<td>'.$object->date_paiement.'</td></tr>';
  1608. print '</tr>';
  1609. */
  1610. }
  1611. // Other attributes
  1612. $cols = 2;
  1613. include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
  1614. print '</table>';
  1615. print '</div>';
  1616. print '<div class="fichehalfright">';
  1617. print '<div class="underbanner clearboth"></div>';
  1618. print '<table class="border tableforfield centpercent">';
  1619. // Amount
  1620. print '<tr>';
  1621. print '<td class="titlefieldmiddle">'.$langs->trans("AmountHT").'</td>';
  1622. print '<td class="nowrap amountcard">'.price($object->total_ht, 1, '', 1, - 1, - 1, $conf->currency).'</td>';
  1623. $rowspan = 5;
  1624. if ($object->status <= ExpenseReport::STATUS_VALIDATED) {
  1625. $rowspan++;
  1626. } elseif ($object->status == ExpenseReport::STATUS_CANCELED) {
  1627. $rowspan += 2;
  1628. } else {
  1629. $rowspan += 2;
  1630. }
  1631. if ($object->status == ExpenseReport::STATUS_REFUSED || !empty($object->detail_refuse)) {
  1632. $rowspan += 2;
  1633. }
  1634. if ($object->status == ExpenseReport::STATUS_CLOSED) {
  1635. $rowspan += 2;
  1636. }
  1637. print "</td>";
  1638. print '</tr>';
  1639. print '<tr>';
  1640. print '<td>'.$langs->trans("AmountVAT").'</td>';
  1641. print '<td class="nowrap amountcard">'.price($object->total_tva, 1, '', 1, -1, -1, $conf->currency).'</td>';
  1642. print '</tr>';
  1643. // Amount Local Taxes
  1644. if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) { // Localtax1
  1645. print '<tr><td>'.$langs->transcountry("AmountLT1", $mysoc->country_code).'</td>';
  1646. print '<td class="valuefield">'.price($object->total_localtax1, 1, '', 1, -1, -1, $conf->currency).'</td></tr>';
  1647. }
  1648. if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) { // Localtax2 IRPF
  1649. print '<tr><td>'.$langs->transcountry("AmountLT2", $mysoc->country_code).'</td>';
  1650. print '<td class="valuefield">'.price($object->total_localtax2, 1, '', 1, -1, -1, $conf->currency).'</td></tr>';
  1651. }
  1652. print '<tr>';
  1653. print '<td>'.$langs->trans("AmountTTC").'</td>';
  1654. print '<td class="nowrap amountcard">'.price($object->total_ttc, 1, '', 1, -1, -1, $conf->currency).'</td>';
  1655. print '</tr>';
  1656. // List of payments already done
  1657. $nbcols = 3;
  1658. $nbrows = 0;
  1659. if (!empty($conf->banque->enabled)) {
  1660. $nbrows++;
  1661. $nbcols++;
  1662. }
  1663. print '<table class="noborder paymenttable centpercent">';
  1664. print '<tr class="liste_titre">';
  1665. print '<td class="liste_titre">'.$langs->trans('Payments').'</td>';
  1666. print '<td class="liste_titre">'.$langs->trans('Date').'</td>';
  1667. print '<td class="liste_titre">'.$langs->trans('Type').'</td>';
  1668. if (!empty($conf->banque->enabled)) {
  1669. print '<td class="liste_titre right">'.$langs->trans('BankAccount').'</td>';
  1670. }
  1671. print '<td class="liste_titre right">'.$langs->trans('Amount').'</td>';
  1672. print '<td class="liste_titre" width="18">&nbsp;</td>';
  1673. print '</tr>';
  1674. // Payments already done (from payment on this expensereport)
  1675. $sql = "SELECT p.rowid, p.num_payment, p.datep as dp, p.amount, p.fk_bank,";
  1676. $sql .= "c.code as payment_code, c.libelle as payment_type,";
  1677. $sql .= "ba.rowid as baid, ba.ref as baref, ba.label, ba.number as banumber, ba.account_number, ba.fk_accountancy_journal";
  1678. $sql .= " FROM ".MAIN_DB_PREFIX."expensereport as e, ".MAIN_DB_PREFIX."payment_expensereport as p";
  1679. $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as c ON p.fk_typepayment = c.id";
  1680. $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid';
  1681. $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid';
  1682. $sql .= " WHERE e.rowid = ".((int) $id);
  1683. $sql .= " AND p.fk_expensereport = e.rowid";
  1684. $sql .= ' AND e.entity IN ('.getEntity('expensereport').')';
  1685. $sql .= " ORDER BY dp";
  1686. $resql = $db->query($sql);
  1687. if ($resql) {
  1688. $num = $db->num_rows($resql);
  1689. $i = 0; $totalpaid = 0;
  1690. while ($i < $num) {
  1691. $objp = $db->fetch_object($resql);
  1692. $paymentexpensereportstatic->id = $objp->rowid;
  1693. $paymentexpensereportstatic->datep = $db->jdate($objp->dp);
  1694. $paymentexpensereportstatic->ref = $objp->rowid;
  1695. $paymentexpensereportstatic->num_payment = $objp->num_payment;
  1696. $paymentexpensereportstatic->type_code = $objp->payment_code;
  1697. $paymentexpensereportstatic->type_label = $objp->payment_type;
  1698. print '<tr class="oddseven">';
  1699. print '<td>';
  1700. print $paymentexpensereportstatic->getNomUrl(1);
  1701. print '</td>';
  1702. print '<td>'.dol_print_date($db->jdate($objp->dp), 'day')."</td>\n";
  1703. $labeltype = $langs->trans("PaymentType".$objp->payment_code) != ("PaymentType".$objp->payment_code) ? $langs->trans("PaymentType".$objp->payment_code) : $objp->payment_type;
  1704. print "<td>".$labeltype.' '.$objp->num_payment."</td>\n";
  1705. // Bank account
  1706. if (!empty($conf->banque->enabled)) {
  1707. $bankaccountstatic->id = $objp->baid;
  1708. $bankaccountstatic->ref = $objp->baref;
  1709. $bankaccountstatic->label = $objp->baref;
  1710. $bankaccountstatic->number = $objp->banumber;
  1711. if (!empty($conf->accounting->enabled)) {
  1712. $bankaccountstatic->account_number = $objp->account_number;
  1713. $accountingjournal = new AccountingJournal($db);
  1714. $accountingjournal->fetch($objp->fk_accountancy_journal);
  1715. $bankaccountstatic->accountancy_journal = $accountingjournal->getNomUrl(0, 1, 1, '', 1);
  1716. }
  1717. print '<td class="right">';
  1718. if ($bankaccountstatic->id) {
  1719. print $bankaccountstatic->getNomUrl(1, 'transactions');
  1720. }
  1721. print '</td>';
  1722. }
  1723. print '<td class="right">'.price($objp->amount)."</td>";
  1724. print '<td></td>';
  1725. print "</tr>";
  1726. $totalpaid += $objp->amount;
  1727. $i++;
  1728. }
  1729. if (!is_null($totalpaid)) {
  1730. $totalpaid = price2num($totalpaid); // Round $totalpaid to fix floating problem after addition into loop
  1731. }
  1732. $remaintopay = price2num($object->total_ttc - $totalpaid);
  1733. $resteapayeraffiche = $remaintopay;
  1734. $cssforamountpaymentcomplete = 'amountpaymentcomplete';
  1735. if ($object->status == ExpenseReport::STATUS_REFUSED) {
  1736. $cssforamountpaymentcomplete = 'amountpaymentneutral';
  1737. $resteapayeraffiche = 0;
  1738. } elseif ($object->paid == 0) {
  1739. $cssforamountpaymentcomplete = 'amountpaymentneutral';
  1740. }
  1741. print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans("AlreadyPaid").':</td><td class="right">'.price($totalpaid).'</td><td></td></tr>';
  1742. print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans("AmountExpected").':</td><td class="right">'.price($object->total_ttc).'</td><td></td></tr>';
  1743. print '<tr><td colspan="'.$nbcols.'" class="right">'.$langs->trans("RemainderToPay").':</td>';
  1744. print '<td class="right'.($resteapayeraffiche ? ' amountremaintopay' : (' '.$cssforamountpaymentcomplete)).'">'.price($resteapayeraffiche).'</td><td></td></tr>';
  1745. $db->free($resql);
  1746. } else {
  1747. dol_print_error($db);
  1748. }
  1749. print "</table>";
  1750. print '</div>';
  1751. print '</div>';
  1752. print '<div class="clearboth"></div><br>';
  1753. print '<div style="clear: both;"></div>';
  1754. $actiontouse = 'updateline';
  1755. if (($object->status == 0 || $object->status == 99) && $action != 'editline') {
  1756. $actiontouse = 'addline';
  1757. }
  1758. print '<form name="expensereport" action="'.$_SERVER["PHP_SELF"].'" enctype="multipart/form-data" method="post" >';
  1759. print '<input type="hidden" name="token" value="'.newToken().'">';
  1760. print '<input type="hidden" name="action" value="'.$actiontouse.'">';
  1761. print '<input type="hidden" name="id" value="'.$object->id.'">';
  1762. print '<input type="hidden" name="fk_expensereport" value="'.$object->id.'" />';
  1763. print '<div class="div-table-responsive-no-min">';
  1764. print '<table id="tablelines" class="noborder centpercent">';
  1765. if (!empty($object->lines)) {
  1766. $i = 0; $total = 0;
  1767. print '<tr class="liste_titre headerexpensereportdet">';
  1768. print '<td class="center linecollinenb">'.$langs->trans('LineNb').'</td>';
  1769. //print '<td class="center">'.$langs->trans('Piece').'</td>';
  1770. print '<td class="center linecoldate">'.$langs->trans('Date').'</td>';
  1771. if (!empty($conf->project->enabled)) {
  1772. print '<td class="minwidth100imp linecolproject">'.$langs->trans('Project').'</td>';
  1773. }
  1774. print '<td class="center linecoltype">'.$langs->trans('Type').'</td>';
  1775. if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
  1776. print '<td class="center linecolcarcategory">'.$langs->trans('CarCategory').'</td>';
  1777. }
  1778. print '<td class="center linecoldescription">'.$langs->trans('Description').'</td>';
  1779. print '<td class="right linecolvat">'.$langs->trans('VAT').'</td>';
  1780. print '<td class="right linecolpriceuht">'.$langs->trans('PriceUHT').'</td>';
  1781. print '<td class="right linecolpriceuttc">'.$langs->trans('PriceUTTC').'</td>';
  1782. print '<td class="right linecolqty">'.$langs->trans('Qty').'</td>';
  1783. if ($action != 'editline') {
  1784. print '<td class="right linecolamountht">'.$langs->trans('AmountHT').'</td>';
  1785. print '<td class="right linecolamountttc">'.$langs->trans('AmountTTC').'</td>';
  1786. }
  1787. // Picture
  1788. print '<td>';
  1789. print '</td>';
  1790. // Information if theres a rule restriction
  1791. print '<td>';
  1792. print '</td>';
  1793. // Ajout des boutons de modification/suppression
  1794. if (($object->status < 2 || $object->status == 99) && $user->rights->expensereport->creer) {
  1795. print '<td class="right"></td>';
  1796. }
  1797. print '</tr>';
  1798. foreach ($object->lines as &$line) {
  1799. $numline = $i + 1;
  1800. if ($action != 'editline' || $line->rowid != GETPOST('rowid', 'int')) {
  1801. print '<tr class="oddeven linetr" data-id="'.$line->id.'">';
  1802. // Num
  1803. print '<td class="center linecollinenb">';
  1804. print $numline;
  1805. print '</td>';
  1806. // Date
  1807. print '<td class="center linecoldate">'.dol_print_date($db->jdate($line->date), 'day').'</td>';
  1808. // Project
  1809. if (!empty($conf->project->enabled)) {
  1810. print '<td class="center dateproject">';
  1811. if ($line->fk_project > 0) {
  1812. $projecttmp->id = $line->fk_project;
  1813. $projecttmp->ref = $line->projet_ref;
  1814. $projecttmp->title = $line->projet_title;
  1815. print $projecttmp->getNomUrl(1);
  1816. }
  1817. print '</td>';
  1818. }
  1819. $titlealt = '';
  1820. if (!empty($conf->accounting->enabled)) {
  1821. require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
  1822. $accountingaccount = new AccountingAccount($db);
  1823. $resaccountingaccount = $accountingaccount->fetch(0, $line->type_fees_accountancy_code, 1);
  1824. //$titlealt .= '<span class="opacitymedium">';
  1825. $titlealt .= $langs->trans("AccountancyCode").': ';
  1826. if ($resaccountingaccount > 0) {
  1827. $titlealt .= $accountingaccount->account_number;
  1828. } else {
  1829. $titlealt .= $langs->trans("NotFound");
  1830. }
  1831. //$titlealt .= '</span>';
  1832. }
  1833. // Type of fee
  1834. print '<td class="center linecoltype" title="'.dol_escape_htmltag($titlealt).'">';
  1835. $labeltype = ($langs->trans(($line->type_fees_code)) == $line->type_fees_code ? $line->type_fees_libelle : $langs->trans($line->type_fees_code));
  1836. print $labeltype;
  1837. print '</td>';
  1838. // IK
  1839. if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
  1840. print '<td class="fk_c_exp_tax_cat linecoltaxcat">';
  1841. $exp_tax_cat_label = dol_getIdFromCode($db, $line->fk_c_exp_tax_cat, 'c_exp_tax_cat', 'rowid', 'label');
  1842. print $langs->trans($exp_tax_cat_label);
  1843. print '</td>';
  1844. }
  1845. // Comment
  1846. print '<td class="left linecolcomment">'.dol_nl2br($line->comments).'</td>';
  1847. // VAT rate
  1848. print '<td class="right linecolvatrate">'.vatrate($line->vatrate.($line->vat_src_code ? ' ('.$line->vat_src_code.')' : ''), true).'</td>';
  1849. // Unit price HT
  1850. print '<td class="right linecolunitht">';
  1851. if (!empty($line->value_unit_ht)) {
  1852. print price($line->value_unit_ht);
  1853. } else {
  1854. $tmpvat = price2num(preg_replace('/\s*\(.*\)/', '', $line->vatrate));
  1855. $pricenettoshow = price2num($line->value_unit / (1 + $tmpvat / 100), 'MU');
  1856. print price($pricenettoshow);
  1857. }
  1858. print '</td>';
  1859. print '<td class="right linecolunitttc">'.price($line->value_unit).'</td>';
  1860. print '<td class="right linecolqty">'.dol_escape_htmltag($line->qty).'</td>';
  1861. if ($action != 'editline') {
  1862. print '<td class="right linecoltotalht">'.price($line->total_ht).'</td>';
  1863. print '<td class="right linecoltotalttc">'.price($line->total_ttc).'</td>';
  1864. }
  1865. // Column with preview
  1866. print '<td class="center linecolpreview">';
  1867. if ($line->fk_ecm_files > 0) {
  1868. $modulepart = 'expensereport';
  1869. $maxheightmini = 32;
  1870. $result = $ecmfilesstatic->fetch($line->fk_ecm_files);
  1871. if ($result > 0) {
  1872. $relativepath = preg_replace('/expensereport\//', '', $ecmfilesstatic->filepath);
  1873. $fileinfo = pathinfo($ecmfilesstatic->filepath.'/'.$ecmfilesstatic->filename);
  1874. if (image_format_supported($fileinfo['basename']) > 0) {
  1875. $minifile = getImageFileNameForSize($fileinfo['basename'], '_mini'); // For new thumbs using same ext (in lower case howerver) than original
  1876. if (!dol_is_file($conf->expensereport->dir_output.'/'.$relativepath.'/'.$minifile)) {
  1877. $minifile = getImageFileNameForSize($fileinfo['basename'], '_mini', '.png'); // For backward compatibility of old thumbs that were created with filename in lower case and with .png extension
  1878. }
  1879. //print $file['path'].'/'.$minifile.'<br>';
  1880. $urlforhref = getAdvancedPreviewUrl($modulepart, $relativepath.'/'.$fileinfo['filename'].'.'.strtolower($fileinfo['extension']), 1, '&entity='.(!empty($object->entity) ? $object->entity : $conf->entity));
  1881. if (empty($urlforhref)) {
  1882. $urlforhref = DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.(!empty($object->entity) ? $object->entity : $conf->entity).'&file='.urlencode($relativepath.$fileinfo['filename'].'.'.strtolower($fileinfo['extension']));
  1883. print '<a href="'.$urlforhref.'" class="aphoto" target="_blank" rel="noopener noreferrer">';
  1884. } else {
  1885. print '<a href="'.$urlforhref['url'].'" class="'.$urlforhref['css'].'" target="'.$urlforhref['target'].'" mime="'.$urlforhref['mime'].'">';
  1886. }
  1887. print '<img class="photo" height="'.$maxheightmini.'" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$modulepart.'&entity='.(!empty($object->entity) ? $object->entity : $conf->entity).'&file='.urlencode($relativepath.'/'.$minifile).'" title="">';
  1888. print '</a>';
  1889. } else {
  1890. $modulepart = 'expensereport';
  1891. $thumbshown = 0;
  1892. if (preg_match('/\.pdf$/i', $ecmfilesstatic->filename)) {
  1893. $filepdf = $conf->expensereport->dir_output.'/'.$relativepath.'/'.$ecmfilesstatic->filename;
  1894. $fileimage = $conf->expensereport->dir_output.'/'.$relativepath.'/'.$ecmfilesstatic->filename.'_preview.png';
  1895. $relativepathimage = $relativepath.'/'.$ecmfilesstatic->filename.'_preview.png';
  1896. $pdfexists = file_exists($filepdf);
  1897. if ($pdfexists) {
  1898. // Conversion du PDF en image png si fichier png non existant
  1899. if (!file_exists($fileimage) || (filemtime($fileimage) < filemtime($filepdf))) {
  1900. if (empty($conf->global->MAIN_DISABLE_PDF_THUMBS)) { // If you experience trouble with pdf thumb generation and imagick, you can disable here.
  1901. include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
  1902. $ret = dol_convert_file($filepdf, 'png', $fileimage, '0'); // Convert first page of PDF into a file _preview.png
  1903. if ($ret < 0) {
  1904. $error++;
  1905. }
  1906. }
  1907. }
  1908. }
  1909. if ($pdfexists && !$error) {
  1910. $heightforphotref = 70;
  1911. if (!empty($conf->dol_optimize_smallscreen)) {
  1912. $heightforphotref = 60;
  1913. }
  1914. // If the preview file is found
  1915. if (file_exists($fileimage)) {
  1916. $thumbshown = 1;
  1917. $urlforhref = getAdvancedPreviewUrl($modulepart, $relativepath.'/'.$fileinfo['filename'].'.'.strtolower($fileinfo['extension']), 1, '&entity='.(!empty($object->entity) ? $object->entity : $conf->entity));
  1918. print '<a href="'.$urlforhref['url'].'" class="'.$urlforhref['css'].'" target="'.$urlforhref['target'].'" mime="'.$urlforhref['mime'].'">';
  1919. print '<img height="'.$heightforphotref.'" class="photo photowithmargin photowithborder" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart=apercu'.$modulepart.'&amp;file='.urlencode($relativepathimage).'">';
  1920. print '</a>';
  1921. }
  1922. }
  1923. }
  1924. if (!$thumbshown) {
  1925. print img_mime($ecmfilesstatic->filename);
  1926. }
  1927. }
  1928. }
  1929. }
  1930. print '</td>';
  1931. print '<td class="nowrap right linecolwarning">';
  1932. print !empty($line->rule_warning_message) ? img_warning(html_entity_decode($line->rule_warning_message)) : '&nbsp;';
  1933. print '</td>';
  1934. // Ajout des boutons de modification/suppression
  1935. if (($object->status < ExpenseReport::STATUS_VALIDATED || $object->status == ExpenseReport::STATUS_REFUSED) && $user->rights->expensereport->creer) {
  1936. print '<td class="nowrap right linecolaction">';
  1937. print '<a class="editfielda reposition paddingrightonly" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=editline&token='.newToken().'&rowid='.$line->rowid.'">';
  1938. print img_edit();
  1939. print '</a> &nbsp; ';
  1940. print '<a class="paddingrightonly" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete_line&token='.newToken().'&rowid='.$line->rowid.'">';
  1941. print img_delete();
  1942. print '</a>';
  1943. print '</td>';
  1944. }
  1945. print '</tr>';
  1946. }
  1947. if ($action == 'editline' && $line->rowid == GETPOST('rowid', 'int')) {
  1948. // Add line with link to add new file or attach line to an existing file
  1949. $colspan = 11;
  1950. if (!empty($conf->project->enabled)) {
  1951. $colspan++;
  1952. }
  1953. if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
  1954. $colspan++;
  1955. }
  1956. print '<!-- line of expense report -->'."\n";
  1957. print '<tr class="tredited">';
  1958. print '<td class="center">';
  1959. print $numline;
  1960. print '</td>';
  1961. print '<td colspan="'.($colspan - 1).'" class="liste_titre"> ';
  1962. print '<a href="" class="commonlink auploadnewfilenow reposition">'.$langs->trans("UploadANewFileNow");
  1963. print img_picto($langs->trans("UploadANewFileNow"), 'chevron-down', '', false, 0, 0, '', 'marginleftonly');
  1964. print '</a>';
  1965. if (empty($conf->global->EXPENSEREPORT_DISABLE_ATTACHMENT_ON_LINES)) {
  1966. print ' &nbsp; - &nbsp; <a href="" class="commonlink aattachtodoc reposition">'.$langs->trans("AttachTheNewLineToTheDocument");
  1967. print img_picto($langs->trans("AttachTheNewLineToTheDocument"), 'chevron-down', '', false, 0, 0, '', 'marginleftonly');
  1968. print '</a>';
  1969. }
  1970. print '<!-- Code to open/close section to submit or link files in edit mode -->'."\n";
  1971. print '<script type="text/javascript">'."\n";
  1972. print '$(document).ready(function() {
  1973. $( ".auploadnewfilenow" ).click(function() {
  1974. jQuery(".truploadnewfilenow").toggle();
  1975. jQuery(".trattachnewfilenow").hide();
  1976. return false;
  1977. });
  1978. $( ".aattachtodoc" ).click(function() {
  1979. jQuery(".trattachnewfilenow").toggle();
  1980. jQuery(".truploadnewfilenow").hide();
  1981. return false;
  1982. });';
  1983. if (is_array(GETPOST('attachfile', 'array')) && count(GETPOST('attachfile', 'array'))) {
  1984. print 'jQuery(".trattachnewfilenow").toggle();'."\n";
  1985. }
  1986. print '
  1987. jQuery("form[name=\"expensereport\"]").submit(function() {
  1988. if (jQuery(".truploadnewfilenow").is(":hidden")) {
  1989. jQuery("input[name=\"sendit\"]").val("");
  1990. }
  1991. });
  1992. ';
  1993. print '
  1994. });
  1995. ';
  1996. print '</script>'."\n";
  1997. print '</td></tr>';
  1998. $filenamelinked = '';
  1999. if ($line->fk_ecm_files > 0) {
  2000. $result = $ecmfilesstatic->fetch($line->fk_ecm_files);
  2001. if ($result > 0) {
  2002. $filenamelinked = $ecmfilesstatic->filename;
  2003. }
  2004. }
  2005. $tredited = 'tredited';
  2006. include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_addfile.tpl.php';
  2007. include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_linktofile.tpl.php';
  2008. print '<tr class="oddeven tredited">';
  2009. print '<td></td>';
  2010. // Select date
  2011. print '<td class="center">';
  2012. print $form->selectDate($line->date, 'date');
  2013. print '</td>';
  2014. // Select project
  2015. if (!empty($conf->project->enabled)) {
  2016. print '<td>';
  2017. $formproject->select_projects(-1, $line->fk_project, 'fk_project', 0, 0, $projectRequired ? 0 : 1, 1, 0, 0, 0, '', 0, 0, 'maxwidth300');
  2018. print '</td>';
  2019. }
  2020. // Select type
  2021. print '<td class="center">';
  2022. print $formexpensereport->selectTypeExpenseReport($line->fk_c_type_fees, 'fk_c_type_fees');
  2023. print '</td>';
  2024. if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
  2025. print '<td class="fk_c_exp_tax_cat">';
  2026. $params = array('fk_expense' => $object->id, 'fk_expense_det' => $line->rowid, 'date' => $line->dates);
  2027. print $form->selectExpenseCategories($line->fk_c_exp_tax_cat, 'fk_c_exp_tax_cat', 1, array(), 'fk_c_type_fees', $userauthor->default_c_exp_tax_cat, $params);
  2028. print '</td>';
  2029. }
  2030. // Add comments
  2031. print '<td>';
  2032. print '<textarea name="comments" class="flat_ndf centpercent">'.dol_escape_htmltag($line->comments, 0, 1).'</textarea>';
  2033. print '</td>';
  2034. // VAT
  2035. $selectedvat = price2num($line->vatrate).($line->vat_src_code ? ' ('.$line->vat_src_code.')' : '');
  2036. print '<td class="right">';
  2037. print $form->load_tva('vatrate', (GETPOSTISSET("vatrate") ? GETPOST("vatrate") : $selectedvat), $mysoc, '', 0, 0, '', false, 1);
  2038. print '</td>';
  2039. // Unit price
  2040. print '<td class="right">';
  2041. print '<input type="text" min="0" class="right maxwidth50" id="value_unit_ht" name="value_unit_ht" value="'.dol_escape_htmltag(price2num($line->value_unit_ht)).'"'.$taxlessUnitPriceDisabled.' />';
  2042. print '</td>';
  2043. // Unit price with tax
  2044. print '<td class="right">';
  2045. print '<input type="text" min="0" class="right maxwidth50" id="value_unit" name="value_unit" value="'.dol_escape_htmltag(price2num($line->value_unit)).'" />';
  2046. print '</td>';
  2047. // Quantity
  2048. print '<td class="right">';
  2049. print '<input type="text" min="0" class="input_qty right maxwidth50" name="qty" value="'.dol_escape_htmltag($line->qty).'" />'; // We must be able to enter decimal qty
  2050. print '</td>';
  2051. //print '<td class="right">'.$langs->trans('AmountHT').'</td>';
  2052. //print '<td class="right">'.$langs->trans('AmountTTC').'</td>';
  2053. // Picture
  2054. print '<td class="center">';
  2055. //print $line->fk_ecm_files;
  2056. print '</td>';
  2057. // Information if theres a rule restriction
  2058. print '<td class="center">';
  2059. print '</td>';
  2060. print '<td>';
  2061. print '<input type="hidden" name="rowid" value="'.$line->rowid.'">';
  2062. print $form->buttonsSaveCancel('Save', 'Cancel', array(), 0, 'small');
  2063. print '</td>';
  2064. print '</tr>';
  2065. }
  2066. $i++;
  2067. }
  2068. }
  2069. // Add a new line
  2070. if (($object->status == ExpenseReport::STATUS_DRAFT || $object->status == ExpenseReport::STATUS_REFUSED) && $action != 'editline' && $user->rights->expensereport->creer) {
  2071. $colspan = 12;
  2072. if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
  2073. $colspan++;
  2074. }
  2075. if (!empty($conf->project->enabled)) {
  2076. $colspan++;
  2077. }
  2078. if ($action != 'editline') {
  2079. $colspan++;
  2080. }
  2081. $nbFiles = $nbLinks = 0;
  2082. $arrayoffiles = array();
  2083. if (empty($conf->global->EXPENSEREPORT_DISABLE_ATTACHMENT_ON_LINES)) {
  2084. require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
  2085. require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
  2086. require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
  2087. $upload_dir = $conf->expensereport->dir_output."/".dol_sanitizeFileName($object->ref);
  2088. $arrayoffiles = dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png|'.preg_quote(dol_sanitizeFileName($object->ref.'.pdf'), '/').')$');
  2089. $nbFiles = count($arrayoffiles);
  2090. $nbLinks = Link::count($db, $object->element, $object->id);
  2091. }
  2092. // Add line with link to add new file or attach to an existing file
  2093. print '<tr class="liste_titre">';
  2094. print '<td colspan="'.$colspan.'" class="liste_titre expensereportautoload">';
  2095. print '<a href="" class="commonlink auploadnewfilenow reposition">'.$langs->trans("UploadANewFileNow");
  2096. print img_picto($langs->trans("UploadANewFileNow"), 'chevron-down', '', false, 0, 0, '', 'marginleftonly');
  2097. print '</a>';
  2098. if (empty($conf->global->EXPENSEREPORT_DISABLE_ATTACHMENT_ON_LINES)) {
  2099. print ' &nbsp; - &nbsp; <a href="" class="commonlink aattachtodoc reposition">'.$langs->trans("AttachTheNewLineToTheDocument");
  2100. print img_picto($langs->trans("AttachTheNewLineToTheDocument"), 'chevron-down', '', false, 0, 0, '', 'marginleftonly');
  2101. print '</a>';
  2102. }
  2103. print '<!-- Code to open/close section to submit or link files in the form to add new line -->'."\n";
  2104. print '<script type="text/javascript">'."\n";
  2105. print '$(document).ready(function() {
  2106. $( ".auploadnewfilenow" ).click(function() {
  2107. console.log("We click on toggle of auploadnewfilenow");
  2108. jQuery(".truploadnewfilenow").toggle();
  2109. jQuery(".trattachnewfilenow").hide();
  2110. if (jQuery(".truploadnewfilenow").is(":hidden")) {
  2111. jQuery("input[name=\"sendit\"]").prop("name", "senditdisabled");
  2112. } else {
  2113. jQuery("input[name=\"senditdisabled\"]").prop("name", "sendit");
  2114. }
  2115. return false;
  2116. });
  2117. $( ".aattachtodoc" ).click(function() {
  2118. console.log("We click on toggle of aattachtodoc");
  2119. jQuery(".trattachnewfilenow").toggle();
  2120. jQuery(".truploadnewfilenow").hide();
  2121. return false;
  2122. });'."\n";
  2123. if (is_array(GETPOST('attachfile', 'array')) && count(GETPOST('attachfile', 'array')) && $action != 'updateline') {
  2124. print 'jQuery(".trattachnewfilenow").show();'."\n";
  2125. }
  2126. print '
  2127. jQuery("form[name=\"expensereport\"]").submit(function() {
  2128. if (jQuery(".truploadnewfilenow").is(":hidden")) {
  2129. /* When section to send file is not expanded, we disable the button sendit that submit form to add a new file, so button to submit line will work. */
  2130. jQuery("input[name=\"sendit\"]").val("");
  2131. jQuery("input[name=\"sendit\"]").prop("name", "senditdisabled");
  2132. } else {
  2133. jQuery("input[name=\"senditdisabled\"]").prop("name", "sendit");
  2134. }
  2135. });
  2136. ';
  2137. print '
  2138. });
  2139. ';
  2140. print '</script>'."\n";
  2141. print '</td></tr>';
  2142. include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_linktofile.tpl.php';
  2143. include DOL_DOCUMENT_ROOT.'/expensereport/tpl/expensereport_addfile.tpl.php';
  2144. print '<tr class="liste_titre expensereportcreate">';
  2145. print '<td></td>';
  2146. print '<td class="center expensereportcreatedate">'.$langs->trans('Date').'</td>';
  2147. if (!empty($conf->project->enabled)) {
  2148. print '<td class="minwidth100imp">'.$form->textwithpicto($langs->trans('Project'), $langs->trans("ClosedProjectsAreHidden")).'</td>';
  2149. }
  2150. print '<td class="center expensereportcreatetype">'.$langs->trans('Type').'</td>';
  2151. if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
  2152. print '<td>'.$langs->trans('CarCategory').'</td>';
  2153. }
  2154. print '<td class="right expensereportcreatedescription">'.$langs->trans('Description').'</td>';
  2155. print '<td class="right expensereportcreatevat">'.$langs->trans('VAT').'</td>';
  2156. print '<td class="right expensereportcreatepriceuth">'.$langs->trans('PriceUHT').'</td>';
  2157. print '<td class="right expensereportcreatepricettc">'.$langs->trans('PriceUTTC').'</td>';
  2158. print '<td class="right expensereportcreateqty">'.$langs->trans('Qty').'</td>';
  2159. print '<td></td>';
  2160. print '<td></td>';
  2161. print '<td></td>';
  2162. print '<td></td>';
  2163. print '<td></td>';
  2164. print '</tr>';
  2165. print '<tr class="oddeven nohover">';
  2166. // Line number
  2167. print '<td></td>';
  2168. // Select date
  2169. print '<td class="center inputdate">';
  2170. print $form->selectDate($date ? $date : -1, 'date', 0, 0, 0, '', 1, 1);
  2171. print '</td>';
  2172. // Select project
  2173. if (!empty($conf->project->enabled)) {
  2174. print '<td class="inputproject">';
  2175. $formproject->select_projects(-1, $fk_project, 'fk_project', 0, 0, $projectRequired ? 0 : 1, -1, 0, 0, 0, '', 0, 0, 'maxwidth300');
  2176. print '</td>';
  2177. }
  2178. // Select type
  2179. print '<td class="center inputtype">';
  2180. print $formexpensereport->selectTypeExpenseReport($fk_c_type_fees, 'fk_c_type_fees', 1);
  2181. print '</td>';
  2182. if (!empty($conf->global->MAIN_USE_EXPENSE_IK)) {
  2183. print '<td class="fk_c_exp_tax_cat">';
  2184. $params = array('fk_expense' => $object->id);
  2185. print $form->selectExpenseCategories('', 'fk_c_exp_tax_cat', 1, array(), 'fk_c_type_fees', $userauthor->default_c_exp_tax_cat, $params, 0);
  2186. print '</td>';
  2187. }
  2188. // Add comments
  2189. print '<td class="inputcomment">';
  2190. print '<textarea class="flat_ndf centpercent" name="comments" rows="'.ROWS_2.'">'.dol_escape_htmltag($comments, 0, 1).'</textarea>';
  2191. print '</td>';
  2192. // Select VAT
  2193. print '<td class="right inputvat">';
  2194. $defaultvat = -1;
  2195. if (!empty($conf->global->EXPENSEREPORT_NO_DEFAULT_VAT)) {
  2196. $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS = 'none';
  2197. }
  2198. print $form->load_tva('vatrate', ($vatrate != '' ? $vatrate : $defaultvat), $mysoc, '', 0, 0, '', false, 1);
  2199. print '</td>';
  2200. // Unit price net
  2201. print '<td class="right inputpricenet">';
  2202. print '<input type="text" class="right maxwidth50" id="value_unit_ht" name="value_unit_ht" value="'.dol_escape_htmltag($value_unit_ht).'"'.$taxlessUnitPriceDisabled.' />';
  2203. print '</td>';
  2204. // Unit price with tax
  2205. print '<td class="right inputtax">';
  2206. print '<input type="text" class="right maxwidth50" id="value_unit" name="value_unit" value="'.dol_escape_htmltag($value_unit).'">';
  2207. print '</td>';
  2208. // Quantity
  2209. print '<td class="right inputqty">';
  2210. print '<input type="text" min="0" class=" input_qty right maxwidth50" name="qty" value="'.dol_escape_htmltag($qty ? $qty : 1).'">'; // We must be able to enter decimal qty
  2211. print '</td>';
  2212. // Picture
  2213. print '<td></td>';
  2214. if ($action != 'editline') {
  2215. print '<td class="right"></td>';
  2216. print '<td class="right"></td>';
  2217. }
  2218. print '<td class="center inputbuttons">';
  2219. print $form->buttonsSaveCancel("Add", '', '', 1);
  2220. print '</td>';
  2221. print '</tr>';
  2222. } // Fin si c'est payé/validé
  2223. print '</table>';
  2224. print '</div>';
  2225. print '<script>
  2226. /* JQuery for product free or predefined select */
  2227. jQuery(document).ready(function() {
  2228. jQuery("#value_unit_ht").keyup(function(event) {
  2229. console.log(event.which); // discard event tag and arrows
  2230. if (event.which != 9 && (event.which < 37 ||event.which > 40) && jQuery("#value_unit_ht").val() != "") {
  2231. jQuery("#value_unit").val("");
  2232. }
  2233. });
  2234. jQuery("#value_unit").keyup(function(event) {
  2235. console.log(event.which); // discard event tag and arrows
  2236. if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#value_unit").val() != "") {
  2237. jQuery("#value_unit_ht").val("");
  2238. }
  2239. });
  2240. ';
  2241. if (! empty($conf->global->MAIN_USE_EXPENSE_IK)) {
  2242. print '
  2243. /* unit price coéf calculation */
  2244. jQuery(".input_qty, #fk_c_type_fees, #select_fk_c_exp_tax_cat, #vatrate ").change(function(event) {
  2245. let type_fee = jQuery("#fk_c_type_fees").find(":selected").val();
  2246. let tax_cat = jQuery("#select_fk_c_exp_tax_cat").find(":selected").val();
  2247. let tva = jQuery("#vatrate").find(":selected").val();
  2248. let qty = jQuery(".input_qty").val();
  2249. let path = "'.dol_buildpath("/expensereport/ajax/ajaxik.php", 1) .'";
  2250. path += "?fk_c_exp_tax_cat="+tax_cat;
  2251. path +="&fk_expense="+'.$object->id.';
  2252. path += "&vatrate="+tva;
  2253. path += "&qty="+qty;
  2254. if (type_fee == 4) { // frais_kilométriques
  2255. if (tax_cat == "" || parseInt(tax_cat) <= 0){
  2256. return ;
  2257. }
  2258. jQuery.ajax({
  2259. url: path
  2260. ,async:false
  2261. ,dataType:"json"
  2262. ,success:function(response) {
  2263. if (response.response_status == "success"){';
  2264. if (!empty($conf->global->EXPENSEREPORT_FORCE_LINE_AMOUNTS_INCLUDING_TAXES_ONLY)) {
  2265. print '
  2266. jQuery("#value_unit").val(parseFloat(response.data) * (100 + parseFloat(tva)) / 100);
  2267. jQuery("#value_unit").trigger("change");
  2268. ';
  2269. } else {
  2270. print '
  2271. jQuery("#value_unit_ht").val(response.data);
  2272. jQuery("#value_unit_ht").trigger("change");
  2273. jQuery("#value_unit").val("");
  2274. ';
  2275. }
  2276. print '
  2277. } else if(response.response_status == "error" && response.errorMessage != undefined && response.errorMessage.length > 0 ){
  2278. $.jnotify(response.errorMessage, "error", {timeout: 0, type: "error"},{ remove: function (){} } );
  2279. }
  2280. },
  2281. });
  2282. }
  2283. /*console.log(event.which); // discard event tag and arrows
  2284. if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#value_unit").val() != "") {
  2285. jQuery("#value_unit_ht").val("");
  2286. }*/
  2287. });
  2288. ';
  2289. }
  2290. print '
  2291. });
  2292. </script>';
  2293. print '</form>';
  2294. print dol_get_fiche_end();
  2295. }
  2296. } else {
  2297. dol_print_error($db);
  2298. }
  2299. } else {
  2300. print 'Record not found';
  2301. llxFooter();
  2302. exit(1);
  2303. }
  2304. /*
  2305. * Action bar
  2306. */
  2307. print '<div class="tabsAction">';
  2308. if ($action != 'create' && $action != 'edit' && $action != 'editline') {
  2309. $object = new ExpenseReport($db);
  2310. $object->fetch($id, $ref);
  2311. // Send
  2312. if (empty($user->socid)) {
  2313. if ($object->status > ExpenseReport::STATUS_DRAFT) {
  2314. //if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->expensereport->expensereport_advance->send)) {
  2315. print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&mode=init#formmailbeforetitle">'.$langs->trans('SendMail').'</a></div>';
  2316. //} else
  2317. // print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#">' . $langs->trans('SendMail') . '</a></div>';
  2318. }
  2319. }
  2320. /* Si l'état est "Brouillon"
  2321. * ET user à droit "creer/supprimer"
  2322. * ET fk_user_author == user courant
  2323. * Afficher : "Enregistrer" / "Modifier" / "Supprimer"
  2324. */
  2325. if ($user->rights->expensereport->creer && $object->status == ExpenseReport::STATUS_DRAFT) {
  2326. if (in_array($object->fk_user_author, $user->getAllChildIds(1)) || !empty($user->rights->expensereport->writeall_advance)) {
  2327. // Modify
  2328. print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=edit&token='.newToken().'&id='.$object->id.'">'.$langs->trans('Modify').'</a></div>';
  2329. // Validate
  2330. if (count($object->lines) > 0) {
  2331. print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=save&token='.newToken().'&id='.$object->id.'">'.$langs->trans('ValidateAndSubmit').'</a></div>';
  2332. }
  2333. }
  2334. }
  2335. /* Si l'état est "Refusée"
  2336. * ET user à droit "creer/supprimer"
  2337. * ET fk_user_author == user courant
  2338. * Afficher : "Enregistrer" / "Modifier" / "Supprimer"
  2339. */
  2340. if ($user->rights->expensereport->creer && $object->status == ExpenseReport::STATUS_REFUSED) {
  2341. if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) {
  2342. // Modify
  2343. print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=edit&token='.newToken().'&id='.$object->id.'">'.$langs->trans('Modify').'</a></div>';
  2344. // setdraft (le statut refusée est identique à brouillon)
  2345. //print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=brouillonner&id='.$id.'">'.$langs->trans('ReOpen').'</a>';
  2346. // Enregistrer depuis le statut "Refusée"
  2347. print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=save_from_refuse&token='.newToken().'&id='.$object->id.'">'.$langs->trans('ValidateAndSubmit').'</a></div>';
  2348. }
  2349. }
  2350. if ($user->rights->expensereport->to_paid && $object->status == ExpenseReport::STATUS_APPROVED) {
  2351. if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) {
  2352. // setdraft
  2353. print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=setdraft&token='.newToken().'&id='.$object->id.'">'.$langs->trans('SetToDraft').'</a></div>';
  2354. }
  2355. }
  2356. /* Si l'état est "En attente d'approbation"
  2357. * ET user à droit de "approve"
  2358. * ET fk_user_validator == user courant
  2359. * Afficher : "Valider" / "Refuser" / "Supprimer"
  2360. */
  2361. if ($object->status == ExpenseReport::STATUS_VALIDATED) {
  2362. if (in_array($object->fk_user_author, $user->getAllChildIds(1))) {
  2363. // set draft
  2364. print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=setdraft&token='.newToken().'&id='.$object->id.'">'.$langs->trans('SetToDraft').'</a></div>';
  2365. }
  2366. }
  2367. if ($user->rights->expensereport->approve && $object->status == ExpenseReport::STATUS_VALIDATED) {
  2368. //if($object->fk_user_validator==$user->id)
  2369. //{
  2370. // Validate
  2371. print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=validate&id='.$object->id.'">'.$langs->trans('Approve').'</a></div>';
  2372. // Deny
  2373. print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=refuse&id='.$object->id.'">'.$langs->trans('Deny').'</a></div>';
  2374. //}
  2375. if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) {
  2376. // Cancel
  2377. print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=cancel&id='.$object->id.'">'.$langs->trans("Cancel").'</a></div>';
  2378. }
  2379. }
  2380. // If status is Approved
  2381. // ---------------------
  2382. if ($user->rights->expensereport->approve && $object->status == ExpenseReport::STATUS_APPROVED) {
  2383. print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=refuse&id='.$object->id.'">'.$langs->trans('Deny').'</a></div>';
  2384. }
  2385. // If bank module is used
  2386. if ($user->rights->expensereport->to_paid && !empty($conf->banque->enabled) && $object->status == ExpenseReport::STATUS_APPROVED) {
  2387. // Pay
  2388. if ($remaintopay == 0) {
  2389. print '<div class="inline-block divButAction"><span class="butActionRefused classfortooltip" title="'.$langs->trans("DisabledBecauseRemainderToPayIsZero").'">'.$langs->trans('DoPayment').'</span></div>';
  2390. } else {
  2391. print '<div class="inline-block divButAction"><a class="butAction" href="'.DOL_URL_ROOT.'/expensereport/payment/payment.php?id='.$object->id.'&amp;action=create">'.$langs->trans('DoPayment').'</a></div>';
  2392. }
  2393. }
  2394. // If bank module is not used
  2395. if (($user->rights->expensereport->to_paid || empty($conf->banque->enabled)) && $object->status == ExpenseReport::STATUS_APPROVED) {
  2396. //if ((round($remaintopay) == 0 || empty($conf->banque->enabled)) && $object->paid == 0)
  2397. if ($object->paid == 0) {
  2398. print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=set_paid&token='.newToken().'">'.$langs->trans("ClassifyPaid")."</a></div>";
  2399. }
  2400. }
  2401. if ($user->rights->expensereport->creer && ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) && $object->status == ExpenseReport::STATUS_APPROVED) {
  2402. // Cancel
  2403. print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=cancel&token='.newToken().'&id='.$object->id.'">'.$langs->trans("Cancel").'</a></div>';
  2404. }
  2405. // TODO Replace this. It should be SetUnpaid and should go back to status unpaid not canceled.
  2406. if (($user->rights->expensereport->approve || $user->rights->expensereport->to_paid) && $object->status == ExpenseReport::STATUS_CLOSED) {
  2407. // Cancel
  2408. print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=cancel&token='.newToken().'&id='.$object->id.'">'.$langs->trans("Cancel").'</a></div>';
  2409. }
  2410. if ($user->rights->expensereport->to_paid && $object->paid && $object->status == ExpenseReport::STATUS_CLOSED) {
  2411. // Set unpaid
  2412. print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=set_unpaid&token='.newToken().'&id='.$object->id.'">'.$langs->trans('ClassifyUnPaid').'</a></div>';
  2413. }
  2414. // Clone
  2415. if ($user->rights->expensereport->creer) {
  2416. print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=clone&token='.newToken().'">'.$langs->trans("ToClone").'</a></div>';
  2417. }
  2418. /* If draft, validated, cancel, and user can create, he can always delete its card before it is approved */
  2419. if ($user->rights->expensereport->creer && $user->id == $object->fk_user_author && $object->status < ExpenseReport::STATUS_APPROVED) {
  2420. // Delete
  2421. print '<div class="inline-block divButAction"><a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&id='.$object->id.'">'.$langs->trans('Delete').'</a></div>';
  2422. } elseif ($candelete && $object->status != ExpenseReport::STATUS_CLOSED) {
  2423. // Delete
  2424. print '<div class="inline-block divButAction"><a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&id='.$object->id.'">'.$langs->trans('Delete').'</a></div>';
  2425. }
  2426. $parameters = array();
  2427. $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
  2428. }
  2429. print '</div>';
  2430. // Select mail models is same action as presend
  2431. if (GETPOST('modelselected', 'alpha')) {
  2432. $action = 'presend';
  2433. }
  2434. if ($action != 'presend') {
  2435. /*
  2436. * Generate documents
  2437. */
  2438. print '<div class="fichecenter"><div class="fichehalfleft">';
  2439. print '<a name="builddoc"></a>'; // ancre
  2440. if ($user->rights->expensereport->creer && $action != 'create' && $action != 'edit') {
  2441. $filename = dol_sanitizeFileName($object->ref);
  2442. $filedir = $conf->expensereport->dir_output."/".dol_sanitizeFileName($object->ref);
  2443. $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
  2444. $genallowed = $user->rights->expensereport->creer;
  2445. $delallowed = $user->rights->expensereport->creer;
  2446. $var = true;
  2447. print $formfile->showdocuments('expensereport', $filename, $filedir, $urlsource, $genallowed, $delallowed);
  2448. $somethingshown = $formfile->numoffiles;
  2449. }
  2450. // Disabled for expensereport, there is no thirdparty on expensereport, so nothing to define the list of other object we can suggest to link to
  2451. /*
  2452. if ($action != 'create' && $action != 'edit' && ($id || $ref))
  2453. {
  2454. $linktoelem = $form->showLinkToObjectBlock($object, null, array('expensereport'));
  2455. $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
  2456. }
  2457. */
  2458. print '</div><div class="fichehalfright">';
  2459. // List of actions on element
  2460. include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
  2461. $formactions = new FormActions($db);
  2462. $somethingshown = $formactions->showactions($object, 'expensereport', null);
  2463. print '</div></div>';
  2464. }
  2465. // Presend form
  2466. $modelmail = 'expensereport';
  2467. $defaulttopic = 'SendExpenseReportRef';
  2468. $diroutput = $conf->expensereport->dir_output;
  2469. $trackid = 'exp'.$object->id;
  2470. include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
  2471. llxFooter();
  2472. $db->close();