card.php 107 KB

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