card.php 108 KB

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