expensereport.class.php 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956
  1. <?php
  2. /* Copyright (C) 2011 Dimitri Mouillard <dmouillard@teclib.com>
  3. * Copyright (C) 2015 Laurent Destailleur <eldy@users.sourceforge.net>
  4. * Copyright (C) 2015 Alexandre Spangaro <aspangaro.dolibarr@gmail.com>
  5. * Copyright (C) 2016 Ferran Marcet <fmarcet@2byte.es>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. /**
  21. * \file htdocs/expensereport/class/expensereport.class.php
  22. * \ingroup expensereport
  23. * \brief File to manage Expense Reports
  24. */
  25. require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php';
  26. /**
  27. * Class to manage Trips and Expenses
  28. */
  29. class ExpenseReport extends CommonObject
  30. {
  31. var $element='expensereport';
  32. var $table_element='expensereport';
  33. var $table_element_line = 'expensereport_det';
  34. var $fk_element = 'fk_expensereport';
  35. var $lignes=array();
  36. var $date_debut;
  37. var $date_fin;
  38. var $fk_user_validator;
  39. var $status;
  40. var $fk_statut; // -- 1=draft, 2=validated (attente approb), 4=canceled, 5=approved, 6=payed, 99=denied
  41. var $fk_c_paiement;
  42. var $paid;
  43. var $user_author_infos;
  44. var $user_validator_infos;
  45. var $fk_typepayment;
  46. var $num_payment;
  47. var $code_paiement;
  48. var $code_statut;
  49. // ACTIONS
  50. // Create
  51. var $date_create;
  52. var $fk_user_author;
  53. // Update
  54. var $date_modif;
  55. var $fk_user_modif;
  56. // Refus
  57. var $date_refuse;
  58. var $detail_refuse;
  59. var $fk_user_refuse;
  60. // Annulation
  61. var $date_cancel;
  62. var $detail_cancel;
  63. var $fk_user_cancel;
  64. // Validation
  65. var $date_valid;
  66. var $fk_user_valid;
  67. var $user_valid_infos;
  68. // Approve
  69. var $date_approve;
  70. var $fk_user_approve;
  71. // Paiement
  72. var $user_paid_infos;
  73. /*
  74. END ACTIONS
  75. */
  76. /**
  77. * Constructor
  78. *
  79. * @param DoliDB $db Handler acces base de donnees
  80. */
  81. function __construct($db)
  82. {
  83. $this->db = $db;
  84. $this->total_ht = 0;
  85. $this->total_ttc = 0;
  86. $this->total_tva = 0;
  87. $this->modepaymentid = 0;
  88. // List of language codes for status
  89. $this->statuts_short = array(0 => 'Draft', 2 => 'Validated', 4 => 'Canceled', 5 => 'Approved', 6 => 'Paid', 99 => 'Refused');
  90. $this->statuts = array(0 => 'Draft', 2 => 'ValidatedWaitingApproval', 4 => 'Canceled', 5 => 'Approved', 6 => 'Paid', 99 => 'Refused');
  91. $this->statuts_logo = array(0 => 'statut0', 2 => 'statut1', 4 => 'statut5', 5 => 'statut3', 6 => 'statut6', 99 => 'statut8');
  92. return 1;
  93. }
  94. /**
  95. * Create object in database
  96. *
  97. * @param User $user User that create
  98. * @return int <0 if KO, >0 if OK
  99. */
  100. function create($user)
  101. {
  102. global $conf;
  103. $now = dol_now();
  104. $this->db->begin();
  105. $sql = "INSERT INTO ".MAIN_DB_PREFIX.$this->table_element." (";
  106. $sql.= "ref";
  107. $sql.= ",total_ht";
  108. $sql.= ",total_ttc";
  109. $sql.= ",total_tva";
  110. $sql.= ",date_debut";
  111. $sql.= ",date_fin";
  112. $sql.= ",date_create";
  113. $sql.= ",fk_user_author";
  114. $sql.= ",fk_user_validator";
  115. $sql.= ",fk_user_modif";
  116. $sql.= ",fk_statut";
  117. $sql.= ",fk_c_paiement";
  118. $sql.= ",paid";
  119. $sql.= ",note_public";
  120. $sql.= ",note_private";
  121. $sql.= ",entity";
  122. $sql.= ") VALUES(";
  123. $sql.= "'(PROV)'";
  124. $sql.= ", ".$this->total_ht;
  125. $sql.= ", ".$this->total_ttc;
  126. $sql.= ", ".$this->total_tva;
  127. $sql.= ", '".$this->db->idate($this->date_debut)."'";
  128. $sql.= ", '".$this->db->idate($this->date_fin)."'";
  129. $sql.= ", '".$this->db->idate($now)."'";
  130. $sql.= ", ".($user->id > 0 ? $user->id:"null");
  131. $sql.= ", ".($this->fk_user_validator > 0 ? $this->fk_user_validator:"null");
  132. $sql.= ", ".($this->fk_user_modif > 0 ? $this->fk_user_modif:"null");
  133. $sql.= ", ".($this->fk_statut > 1 ? $this->fk_statut:0);
  134. $sql.= ", ".($this->modepaymentid?$this->modepaymentid:"null");
  135. $sql.= ", 0";
  136. $sql.= ", ".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null");
  137. $sql.= ", ".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null");
  138. $sql.= ", ".$conf->entity;
  139. $sql.= ")";
  140. dol_syslog(get_class($this)."::create sql=".$sql, LOG_DEBUG);
  141. $result = $this->db->query($sql);
  142. if ($result)
  143. {
  144. $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element);
  145. $this->ref='(PROV'.$this->id.')';
  146. $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element." SET ref='".$this->ref."' WHERE rowid=".$this->id;
  147. dol_syslog(get_class($this)."::create sql=".$sql);
  148. $resql=$this->db->query($sql);
  149. if (!$resql) $error++;
  150. foreach ($this->lignes as $i => $val)
  151. {
  152. $newndfline=new ExpenseReportLine($this->db);
  153. $newndfline=$this->lignes[$i];
  154. $newndfline->fk_expensereport=$this->id;
  155. if ($result >= 0)
  156. {
  157. $result=$newndfline->insert();
  158. }
  159. if ($result < 0)
  160. {
  161. $error++;
  162. break;
  163. }
  164. }
  165. if (! $error)
  166. {
  167. $result=$this->update_price();
  168. if ($result > 0)
  169. {
  170. $this->db->commit();
  171. return $this->id;
  172. }
  173. else
  174. {
  175. $this->db->rollback();
  176. return -3;
  177. }
  178. }
  179. else
  180. {
  181. dol_syslog(get_class($this)."::create error ".$this->error, LOG_ERR);
  182. $this->db->rollback();
  183. return -2;
  184. }
  185. }
  186. else
  187. {
  188. $this->error=$this->db->error()." sql=".$sql;
  189. $this->db->rollback();
  190. return -1;
  191. }
  192. }
  193. /**
  194. * update
  195. *
  196. * @param User $user User making change
  197. * @return int <0 if KO, >0 if OK
  198. */
  199. function update($user)
  200. {
  201. global $langs;
  202. $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET";
  203. $sql.= " total_ht = ".$this->total_ht;
  204. $sql.= " , total_ttc = ".$this->total_ttc;
  205. $sql.= " , total_tva = ".$this->total_tva;
  206. $sql.= " , date_debut = '".$this->db->idate($this->date_debut)."'";
  207. $sql.= " , date_fin = '".$this->db->idate($this->date_fin)."'";
  208. $sql.= " , fk_user_author = ".($user->id > 0 ? "'".$user->id."'":"null");
  209. $sql.= " , fk_user_validator = ".($this->fk_user_validator > 0 ? $this->fk_user_validator:"null");
  210. $sql.= " , fk_user_valid = ".($this->fk_user_valid > 0 ? $this->fk_user_valid:"null");
  211. $sql.= " , fk_user_modif = ".($this->fk_user_modif > 0 ? $this->fk_user_modif:"null");
  212. $sql.= " , fk_statut = ".($this->fk_statut >= 0 ? $this->fk_statut:'0');
  213. $sql.= " , fk_c_paiement = ".($this->fk_c_paiement > 0 ? $this->fk_c_paiement:"null");
  214. $sql.= " , note_public = ".(!empty($this->note_public)?"'".$this->db->escape($this->note_public)."'":"''");
  215. $sql.= " , note_private = ".(!empty($this->note_private)?"'".$this->db->escape($this->note_private)."'":"''");
  216. $sql.= " , detail_refuse = ".(!empty($this->detail_refuse)?"'".$this->db->escape($this->detail_refuse)."'":"''");
  217. $sql.= " WHERE rowid = ".$this->id;
  218. dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG);
  219. $result = $this->db->query($sql);
  220. if ($result)
  221. {
  222. return 1;
  223. }
  224. else
  225. {
  226. $this->error=$this->db->error();
  227. return -1;
  228. }
  229. }
  230. /**
  231. * Load an object from database
  232. *
  233. * @param int $id Id
  234. * @param string $ref Ref
  235. * @return int <0 if KO, >0 if OK
  236. */
  237. function fetch($id, $ref='')
  238. {
  239. global $conf;
  240. $sql = "SELECT d.rowid, d.ref, d.note_public, d.note_private,"; // DEFAULT
  241. $sql.= " d.detail_refuse, d.detail_cancel, d.fk_user_refuse, d.fk_user_cancel,"; // ACTIONS
  242. $sql.= " d.date_refuse, d.date_cancel,"; // ACTIONS
  243. $sql.= " d.total_ht, d.total_ttc, d.total_tva,"; // TOTAUX (int)
  244. $sql.= " d.date_debut, d.date_fin, d.date_create, d.tms as date_modif, d.date_valid, d.date_approve,"; // DATES (datetime)
  245. $sql.= " d.fk_user_author, d.fk_user_modif, d.fk_user_validator,";
  246. $sql.= " d.fk_user_valid, d.fk_user_approve,";
  247. $sql.= " d.fk_statut as status, d.fk_c_paiement,";
  248. $sql.= " dp.libelle as libelle_paiement, dp.code as code_paiement"; // INNER JOIN paiement
  249. $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." as d LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as dp ON d.fk_c_paiement = dp.id";
  250. if ($ref) $sql.= " WHERE d.ref = '".$this->db->escape($ref)."'";
  251. else $sql.= " WHERE d.rowid = ".$id;
  252. $sql.= $restrict;
  253. dol_syslog(get_class($this)."::fetch sql=".$sql, LOG_DEBUG);
  254. $resql = $this->db->query($sql) ;
  255. if ($resql)
  256. {
  257. $obj = $this->db->fetch_object($resql);
  258. if ($obj)
  259. {
  260. $this->id = $obj->rowid;
  261. $this->ref = $obj->ref;
  262. $this->total_ht = $obj->total_ht;
  263. $this->total_tva = $obj->total_tva;
  264. $this->total_ttc = $obj->total_ttc;
  265. $this->note_public = $obj->note_public;
  266. $this->note_private = $obj->note_private;
  267. $this->detail_refuse = $obj->detail_refuse;
  268. $this->detail_cancel = $obj->detail_cancel;
  269. $this->date_debut = $this->db->jdate($obj->date_debut);
  270. $this->date_fin = $this->db->jdate($obj->date_fin);
  271. $this->date_valid = $this->db->jdate($obj->date_valid);
  272. $this->date_approve = $this->db->jdate($obj->date_approve);
  273. $this->date_create = $this->db->jdate($obj->date_create);
  274. $this->date_modif = $this->db->jdate($obj->date_modif);
  275. $this->date_refuse = $this->db->jdate($obj->date_refuse);
  276. $this->date_cancel = $this->db->jdate($obj->date_cancel);
  277. $this->fk_user_author = $obj->fk_user_author;
  278. $this->fk_user_modif = $obj->fk_user_modif;
  279. $this->fk_user_validator = $obj->fk_user_validator;
  280. $this->fk_user_valid = $obj->fk_user_valid;
  281. $this->fk_user_refuse = $obj->fk_user_refuse;
  282. $this->fk_user_cancel = $obj->fk_user_cancel;
  283. $this->fk_user_approve = $obj->fk_user_approve;
  284. $user_author = new User($this->db);
  285. if ($this->fk_user_author > 0) $user_author->fetch($this->fk_user_author);
  286. $this->user_author_infos = dolGetFirstLastname($user_author->firstname, $user_author->lastname);
  287. $user_approver = new User($this->db);
  288. if ($this->fk_user_validator > 0) $user_approver->fetch($this->fk_user_validator);
  289. $this->user_validator_infos = dolGetFirstLastname($user_approver->firstname, $user_approver->lastname);
  290. $this->fk_statut = $obj->status;
  291. $this->status = $obj->status;
  292. $this->fk_c_paiement = $obj->fk_c_paiement;
  293. $this->paid = $obj->paid;
  294. if ($this->fk_statut==5 || $this->fk_statut==6)
  295. {
  296. $user_valid = new User($this->db);
  297. if ($this->fk_user_valid > 0) $user_valid->fetch($this->fk_user_valid);
  298. $this->user_valid_infos = dolGetFirstLastname($user_valid->firstname, $user_valid->lastname);
  299. }
  300. $this->libelle_statut = $obj->libelle_statut;
  301. $this->libelle_paiement = $obj->libelle_paiement;
  302. $this->code_statut = $obj->code_statut;
  303. $this->code_paiement = $obj->code_paiement;
  304. $this->lignes = array(); // deprecated
  305. $this->lines = array();
  306. $result=$this->fetch_lines();
  307. return $result;
  308. }
  309. else
  310. {
  311. return 0;
  312. }
  313. }
  314. else
  315. {
  316. $this->error=$this->db->lasterror();
  317. return -1;
  318. }
  319. }
  320. /**
  321. * Classify the expense report as paid
  322. *
  323. * @param int $id Id of expense report
  324. * @param user $fuser User making change
  325. * @return int <0 if KO, >0 if OK
  326. */
  327. function set_paid($id, $fuser)
  328. {
  329. $sql = "UPDATE ".MAIN_DB_PREFIX."expensereport";
  330. $sql.= " SET fk_statut = 6, paid=1";
  331. $sql.= " WHERE rowid = ".$id." AND fk_statut = 5";
  332. dol_syslog(get_class($this)."::set_paid sql=".$sql, LOG_DEBUG);
  333. $resql=$this->db->query($sql);
  334. if ($resql)
  335. {
  336. if ($this->db->affected_rows($resql))
  337. {
  338. return 1;
  339. }
  340. else
  341. {
  342. return 0;
  343. }
  344. }
  345. else
  346. {
  347. dol_print_error($this->db);
  348. return -1;
  349. }
  350. }
  351. /**
  352. * Returns the label status
  353. *
  354. * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto
  355. * @return string Label
  356. */
  357. function getLibStatut($mode=0)
  358. {
  359. return $this->LibStatut($this->status,$mode);
  360. }
  361. /**
  362. * Returns the label of a statut
  363. *
  364. * @param int $status id statut
  365. * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto
  366. * @return string Label
  367. */
  368. function LibStatut($status,$mode=0)
  369. {
  370. global $langs;
  371. if ($mode == 0)
  372. return $langs->transnoentities($this->statuts[$status]);
  373. if ($mode == 1)
  374. return $langs->transnoentities($this->statuts_short[$status]);
  375. if ($mode == 2)
  376. return img_picto($langs->transnoentities($this->statuts_short[$status]), $this->statuts_logo[$status]).' '.$langs->transnoentities($this->statuts_short[$status]);
  377. if ($mode == 3)
  378. return img_picto($langs->transnoentities($this->statuts_short[$status]), $this->statuts_logo[$status]);
  379. if ($mode == 4)
  380. return img_picto($langs->transnoentities($this->statuts_short[$status]),$this->statuts_logo[$status]).' '.$langs->transnoentities($this->statuts[$status]);
  381. if ($mode == 5)
  382. return '<span class="hideonsmartphone">'.$langs->transnoentities($this->statuts_short[$status]).' </span>'.img_picto($langs->transnoentities($this->statuts_short[$status]),$this->statuts_logo[$status]);
  383. }
  384. /**
  385. * Load information on object
  386. *
  387. * @param int $id Id of object
  388. * @return void
  389. */
  390. function info($id)
  391. {
  392. global $conf;
  393. $sql = "SELECT f.rowid,";
  394. $sql.= " f.date_create as datec,";
  395. $sql.= " f.tms as date_modification,";
  396. $sql.= " f.date_valid as datev,";
  397. $sql.= " f.date_approve as datea,";
  398. $sql.= " f.fk_user_author as fk_user_creation,";
  399. $sql.= " f.fk_user_modif as fk_user_modification,";
  400. $sql.= " f.fk_user_valid,";
  401. $sql.= " f.fk_user_approve";
  402. $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as f";
  403. $sql.= " WHERE f.rowid = ".$id;
  404. $sql.= " AND f.entity = ".$conf->entity;
  405. $resql = $this->db->query($sql);
  406. if ($resql)
  407. {
  408. if ($this->db->num_rows($resql))
  409. {
  410. $obj = $this->db->fetch_object($resql);
  411. $this->id = $obj->rowid;
  412. $this->date_creation = $this->db->jdate($obj->datec);
  413. $this->date_modification = $this->db->jdate($obj->date_modification);
  414. $this->date_validation = $this->db->jdate($obj->datev);
  415. $this->date_approbation = $this->db->jdate($obj->datea);
  416. $cuser = new User($this->db);
  417. $cuser->fetch($obj->fk_user_author);
  418. $this->user_creation = $cuser;
  419. if ($obj->fk_user_creation)
  420. {
  421. $cuser = new User($this->db);
  422. $cuser->fetch($obj->fk_user_creation);
  423. $this->user_creation = $cuser;
  424. }
  425. if ($obj->fk_user_valid)
  426. {
  427. $vuser = new User($this->db);
  428. $vuser->fetch($obj->fk_user_valid);
  429. $this->user_validation = $vuser;
  430. }
  431. if ($obj->fk_user_modification)
  432. {
  433. $muser = new User($this->db);
  434. $muser->fetch($obj->fk_user_modification);
  435. $this->user_modification = $muser;
  436. }
  437. if ($obj->fk_user_approve)
  438. {
  439. $auser = new User($this->db);
  440. $auser->fetch($obj->fk_user_approve);
  441. $this->user_approve = $auser;
  442. }
  443. }
  444. $this->db->free($resql);
  445. }
  446. else
  447. {
  448. dol_print_error($this->db);
  449. }
  450. }
  451. /**
  452. * Initialise an instance with random values.
  453. * Used to build previews or test instances.
  454. * id must be 0 if object instance is a specimen.
  455. *
  456. * @return void
  457. */
  458. function initAsSpecimen()
  459. {
  460. global $user,$langs,$conf;
  461. $now=dol_now();
  462. // Initialise parametres
  463. $this->id=0;
  464. $this->ref = 'SPECIMEN';
  465. $this->specimen=1;
  466. $this->date_create = $now;
  467. $this->date_debut = $now;
  468. $this->date_fin = $now;
  469. $this->date_approve = $now;
  470. $this->status = 5;
  471. $this->fk_statut = 5;
  472. $this->fk_user_author = $user->id;
  473. $this->fk_user_valid = $user->id;
  474. $this->fk_user_approve = $user->id;
  475. $this->fk_user_validator = $user->id;
  476. $this->note_private='Private note';
  477. $this->note_public='SPECIMEN';
  478. $nbp = 5;
  479. $xnbp = 0;
  480. while ($xnbp < $nbp)
  481. {
  482. $line=new ExpenseReportLine($this->db);
  483. $line->comments=$langs->trans("Comment")." ".$xnbp;
  484. $line->date=($now-3600*(1+$xnbp));
  485. $line->total_ht=100;
  486. $line->total_tva=20;
  487. $line->total_ttc=120;
  488. $line->qty=1;
  489. $line->vatrate=20;
  490. $line->value_unit=120;
  491. $line->fk_expensereport=0;
  492. $line->type_fees_code='TRA';
  493. $line->projet_ref = 'ABC';
  494. $this->lines[$xnbp]=$line;
  495. $xnbp++;
  496. $this->total_ht+=$line->total_ht;
  497. $this->total_tva+=$line->total_tva;
  498. $this->total_ttc+=$line->total_ttc;
  499. }
  500. }
  501. /**
  502. * fetch_line_by_project
  503. *
  504. * @param int $projectid Project id
  505. * @param User $user User
  506. * @return int <0 if KO, >0 if OK
  507. */
  508. function fetch_line_by_project($projectid,$user='')
  509. {
  510. global $conf,$db,$langs;
  511. $langs->load('trips');
  512. if($user->rights->expensereport->lire) {
  513. $sql = "SELECT de.fk_expensereport, de.date, de.comments, de.total_ht, de.total_ttc";
  514. $sql.= " FROM ".MAIN_DB_PREFIX."expensereport_det as de";
  515. $sql.= " WHERE de.fk_projet = ".$projectid;
  516. dol_syslog(get_class($this)."::fetch sql=".$sql, LOG_DEBUG);
  517. $result = $db->query($sql) ;
  518. if ($result)
  519. {
  520. $num = $db->num_rows($result);
  521. $i = 0;
  522. $total_HT = 0;
  523. $total_TTC = 0;
  524. while ($i < $num)
  525. {
  526. $objp = $db->fetch_object($result);
  527. $sql2 = "SELECT d.rowid, d.fk_user_author, d.ref, d.fk_statut";
  528. $sql2.= " FROM ".MAIN_DB_PREFIX."expensereport as d";
  529. $sql2.= " WHERE d.rowid = '".$objp->fk_expensereport."'";
  530. $result2 = $db->query($sql2);
  531. $obj = $db->fetch_object($result2);
  532. $objp->fk_user_author = $obj->fk_user_author;
  533. $objp->ref = $obj->ref;
  534. $objp->fk_c_expensereport_status = $obj->fk_statut;
  535. $objp->rowid = $obj->rowid;
  536. $total_HT = $total_HT + $objp->total_ht;
  537. $total_TTC = $total_TTC + $objp->total_ttc;
  538. $author = new User($db);
  539. $author->fetch($objp->fk_user_author);
  540. print '<tr>';
  541. print '<td><a href="'.DOL_URL_ROOT.'/expensereport/card.php?id='.$objp->rowid.'">'.$objp->ref_num.'</a></td>';
  542. print '<td align="center">'.dol_print_date($objp->date,'day').'</td>';
  543. print '<td>'.$author->getNomUrl().'</td>';
  544. print '<td>'.$objp->comments.'</td>';
  545. print '<td align="right">'.price($objp->total_ht).'</td>';
  546. print '<td align="right">'.price($objp->total_ttc).'</td>';
  547. print '<td align="right">';
  548. switch($objp->fk_c_expensereport_status) {
  549. case 4:
  550. print img_picto($langs->trans('StatusOrderCanceled'),'statut5');
  551. break;
  552. case 1:
  553. print $langs->trans('Draft').' '.img_picto($langs->trans('Draft'),'statut0');
  554. break;
  555. case 2:
  556. print $langs->trans('TripForValid').' '.img_picto($langs->trans('TripForValid'),'statut3');
  557. break;
  558. case 5:
  559. print $langs->trans('TripForPaid').' '.img_picto($langs->trans('TripForPaid'),'statut3');
  560. break;
  561. case 6:
  562. print $langs->trans('TripPaid').' '.img_picto($langs->trans('TripPaid'),'statut4');
  563. break;
  564. }
  565. /*
  566. if ($status==4) return img_picto($langs->trans('StatusOrderCanceled'),'statut5');
  567. if ($status==1) return img_picto($langs->trans('StatusOrderDraft'),'statut0');
  568. if ($status==2) return img_picto($langs->trans('StatusOrderValidated'),'statut1');
  569. if ($status==2) return img_picto($langs->trans('StatusOrderOnProcess'),'statut3');
  570. if ($status==5) return img_picto($langs->trans('StatusOrderToBill'),'statut4');
  571. if ($status==6) return img_picto($langs->trans('StatusOrderOnProcess'),'statut6');
  572. */
  573. print '</td>';
  574. print '</tr>';
  575. $i++;
  576. }
  577. print '<tr class="liste_total"><td colspan="4">'.$langs->trans("Number").': '.$i.'</td>';
  578. print '<td align="right" width="100">'.$langs->trans("TotalHT").' : '.price($total_HT).'</td>';
  579. print '<td align="right" width="100">'.$langs->trans("TotalTTC").' : '.price($total_TTC).'</td>';
  580. print '<td>&nbsp;</td>';
  581. print '</tr>';
  582. }
  583. else
  584. {
  585. $this->error=$db->error();
  586. return -1;
  587. }
  588. }
  589. }
  590. /**
  591. * recalculer
  592. * TODO Replace this with call to update_price if not already done
  593. *
  594. * @param int $id Id of expense report
  595. * @return int <0 if KO, >0 if OK
  596. */
  597. function recalculer($id)
  598. {
  599. $sql = 'SELECT tt.total_ht, tt.total_ttc, tt.total_tva';
  600. $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line.' as tt';
  601. $sql.= ' WHERE tt.'.$this->fk_element.' = '.$id;
  602. $total_ht = 0; $total_tva = 0; $total_ttc = 0;
  603. dol_syslog('ExpenseReport::recalculer sql='.$sql,LOG_DEBUG);
  604. $result = $this->db->query($sql);
  605. if($result)
  606. {
  607. $num = $this->db->num_rows($result);
  608. $i = 0;
  609. while ($i < $num):
  610. $objp = $this->db->fetch_object($result);
  611. $total_ht+=$objp->total_ht;
  612. $total_tva+=$objp->total_tva;
  613. $i++;
  614. endwhile;
  615. $total_ttc = $total_ht + $total_tva;
  616. $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET";
  617. $sql.= " total_ht = ".$total_ht;
  618. $sql.= " , total_ttc = ".$total_ttc;
  619. $sql.= " , total_tva = ".$total_tva;
  620. $sql.= " WHERE rowid = ".$id;
  621. $result = $this->db->query($sql);
  622. if($result):
  623. $this->db->free($result);
  624. return 1;
  625. else:
  626. $this->error=$this->db->error();
  627. dol_syslog('ExpenseReport::recalculer: Error '.$this->error,LOG_ERR);
  628. return -3;
  629. endif;
  630. }
  631. else
  632. {
  633. $this->error=$this->db->error();
  634. dol_syslog('ExpenseReport::recalculer: Error '.$this->error,LOG_ERR);
  635. return -3;
  636. }
  637. }
  638. /**
  639. * fetch_lines
  640. *
  641. * @return int <0 if OK, >0 if KO
  642. */
  643. function fetch_lines()
  644. {
  645. $this->lines=array();
  646. $sql = ' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date,';
  647. $sql.= ' de.'.$this->fk_element.', de.fk_c_type_fees, de.fk_projet, de.tva_tx,';
  648. $sql.= ' de.total_ht, de.total_tva, de.total_ttc,';
  649. $sql.= ' ctf.code as code_type_fees, ctf.label as libelle_type_fees,';
  650. $sql.= ' p.ref as ref_projet, p.title as title_projet';
  651. $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line.' as de';
  652. $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON de.fk_c_type_fees = ctf.id';
  653. $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as p ON de.fk_projet = p.rowid';
  654. $sql.= ' WHERE de.'.$this->fk_element.' = '.$this->id;
  655. dol_syslog('ExpenseReport::fetch_lines sql='.$sql, LOG_DEBUG);
  656. $resql = $this->db->query($sql);
  657. if ($resql)
  658. {
  659. $num = $this->db->num_rows($resql);
  660. $i = 0;
  661. while ($i < $num)
  662. {
  663. $objp = $this->db->fetch_object($resql);
  664. $deplig = new ExpenseReportLine($this->db);
  665. $deplig->rowid = $objp->rowid;
  666. $deplig->comments = $objp->comments;
  667. $deplig->qty = $objp->qty;
  668. $deplig->value_unit = $objp->value_unit;
  669. $deplig->date = $objp->date;
  670. $deplig->fk_expensereport = $objp->fk_expensereport;
  671. $deplig->fk_c_type_fees = $objp->fk_c_type_fees;
  672. $deplig->fk_projet = $objp->fk_projet;
  673. $deplig->total_ht = $objp->total_ht;
  674. $deplig->total_tva = $objp->total_tva;
  675. $deplig->total_ttc = $objp->total_ttc;
  676. $deplig->type_fees_code = empty($objp->code_type_fees)?'TF_OTHER':$objp->code_type_fees;
  677. $deplig->type_fees_libelle = $objp->libelle_type_fees;
  678. $deplig->tva_tx = $objp->tva_tx;
  679. $deplig->vatrate = $objp->tva_tx;
  680. $deplig->projet_ref = $objp->ref_projet;
  681. $deplig->projet_title = $objp->title_projet;
  682. $this->lignes[$i] = $deplig;
  683. $this->lines[$i] = $deplig;
  684. $i++;
  685. }
  686. $this->db->free($resql);
  687. return 1;
  688. }
  689. else
  690. {
  691. $this->error=$this->db->lasterror();
  692. dol_syslog('ExpenseReport::fetch_lines: Error '.$this->error, LOG_ERR);
  693. return -3;
  694. }
  695. }
  696. /**
  697. * delete
  698. *
  699. * @param int $rowid Id to delete (optional)
  700. * @param User $fuser User that delete
  701. * @return int <0 if KO, >0 if OK
  702. */
  703. function delete($rowid=0, User $fuser=null)
  704. {
  705. global $user,$langs,$conf;
  706. if (! $rowid) $rowid=$this->id;
  707. $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element_line.' WHERE '.$this->fk_element.' = '.$rowid;
  708. if ($this->db->query($sql))
  709. {
  710. $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE rowid = '.$rowid;
  711. $resql=$this->db->query($sql);
  712. if ($resql)
  713. {
  714. $this->db->commit();
  715. return 1;
  716. }
  717. else
  718. {
  719. $this->error=$this->db->error()." sql=".$sql;
  720. dol_syslog("ExpenseReport.class::delete ".$this->error, LOG_ERR);
  721. $this->db->rollback();
  722. return -6;
  723. }
  724. }
  725. else
  726. {
  727. $this->error=$this->db->error()." sql=".$sql;
  728. dol_syslog("ExpenseReport.class::delete ".$this->error, LOG_ERR);
  729. $this->db->rollback();
  730. return -4;
  731. }
  732. }
  733. /**
  734. * Set to status validate
  735. *
  736. * @param User $fuser User
  737. * @return int <0 if KO, >0 if OK
  738. */
  739. function setValidate($fuser)
  740. {
  741. global $conf,$langs;
  742. $this->oldref = $this->ref;
  743. $expld_car = (empty($conf->global->NDF_EXPLODE_CHAR))?"-":$conf->global->NDF_EXPLODE_CHAR;
  744. // Sélection de la date de début de la NDF
  745. $sql = 'SELECT date_debut';
  746. $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element;
  747. $sql.= ' WHERE rowid = '.$this->id;
  748. $result = $this->db->query($sql);
  749. $objp = $this->db->fetch_object($result);
  750. $this->date_debut = $this->db->jdate($objp->date_debut);
  751. $update_number_int = false;
  752. // Create next ref if ref is PROVxx
  753. // Rename directory if dir was a temporary ref
  754. if (preg_match('/^[\(]?PROV/i', $this->ref))
  755. {
  756. // Sélection du numéro de ref suivant
  757. $ref_next = $this->getNextNumRef();
  758. $ref_number_int = ($this->ref+1)-1;
  759. $update_number_int = true;
  760. // Création du ref_number suivant
  761. if($ref_next)
  762. {
  763. $prefix="ER";
  764. if (! empty($conf->global->EXPENSE_REPORT_PREFIX)) $prefix=$conf->global->EXPENSE_REPORT_PREFIX;
  765. $this->ref = strtoupper($fuser->login).$expld_car.$prefix.$this->ref.$expld_car.dol_print_date($this->date_debut,'%y%m%d');
  766. }
  767. require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
  768. // We rename directory in order to avoid losing the attachments
  769. $oldref = dol_sanitizeFileName($this->oldref);
  770. $newref = dol_sanitizeFileName($this->ref);
  771. $dirsource = $conf->expensereport->dir_output.'/'.$oldref;
  772. $dirdest = $conf->expensereport->dir_output.'/'.$newref;
  773. if (file_exists($dirsource))
  774. {
  775. dol_syslog(get_class($this)."::valid() rename dir ".$dirsource." into ".$dirdest);
  776. if (@rename($dirsource, $dirdest))
  777. {
  778. dol_syslog("Rename ok");
  779. // Rename docs starting with $oldref with $newref
  780. $listoffiles=dol_dir_list($conf->expensereport->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref,'/'));
  781. foreach($listoffiles as $fileentry)
  782. {
  783. $dirsource=$fileentry['name'];
  784. $dirdest=preg_replace('/^'.preg_quote($oldref,'/').'/',$newref, $dirsource);
  785. $dirsource=$fileentry['path'].'/'.$dirsource;
  786. $dirdest=$fileentry['path'].'/'.$dirdest;
  787. @rename($dirsource, $dirdest);
  788. }
  789. }
  790. }
  791. }
  792. if ($this->fk_statut != 2)
  793. {
  794. $now = dol_now();
  795. $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
  796. $sql.= " SET ref = '".$this->ref."', fk_statut = 2, fk_user_valid = ".$fuser->id.", date_valid='".$this->db->idate($now)."'";
  797. if ($update_number_int) {
  798. $sql.= ", ref_number_int = ".$ref_number_int;
  799. }
  800. $sql.= ' WHERE rowid = '.$this->id;
  801. $resql=$this->db->query($sql);
  802. if ($resql)
  803. {
  804. return 1;
  805. }
  806. else
  807. {
  808. $this->error=$this->db->lasterror();
  809. return -1;
  810. }
  811. }
  812. else
  813. {
  814. dol_syslog(get_class($this)."::set_save expensereport already with save status", LOG_WARNING);
  815. }
  816. }
  817. /**
  818. * set_save_from_refuse
  819. *
  820. * @param User $fuser User
  821. * @return int <0 if KO, >0 if OK
  822. */
  823. function set_save_from_refuse($fuser)
  824. {
  825. global $conf,$langs;
  826. // Sélection de la date de début de la NDF
  827. $sql = 'SELECT date_debut';
  828. $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element;
  829. $sql.= ' WHERE rowid = '.$this->id;
  830. $result = $this->db->query($sql);
  831. $objp = $this->db->fetch_object($result);
  832. $this->date_debut = $this->db->jdate($objp->date_debut);
  833. if ($this->fk_statut != 2)
  834. {
  835. $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
  836. $sql.= " SET fk_statut = 2";
  837. $sql.= ' WHERE rowid = '.$this->id;
  838. dol_syslog(get_class($this)."::set_save_from_refuse sql=".$sql, LOG_DEBUG);
  839. if ($this->db->query($sql))
  840. {
  841. return 1;
  842. }
  843. else
  844. {
  845. $this->error=$this->db->lasterror();
  846. return -1;
  847. }
  848. }
  849. else
  850. {
  851. dol_syslog(get_class($this)."::set_save_from_refuse expensereport already with save status", LOG_WARNING);
  852. }
  853. }
  854. /**
  855. * Set status to approved
  856. *
  857. * @param User $fuser User
  858. * @return int <0 if KO, >0 if OK
  859. */
  860. function setApproved($fuser)
  861. {
  862. $now=dol_now();
  863. // date approval
  864. $this->date_approve = $this->db->idate($now);
  865. if ($this->fk_statut != 5)
  866. {
  867. $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
  868. $sql.= " SET ref = '".$this->ref."', fk_statut = 5, fk_user_approve = ".$fuser->id.",";
  869. $sql.= " date_approve='".$this->date_approve."'";
  870. $sql.= ' WHERE rowid = '.$this->id;
  871. if ($this->db->query($sql))
  872. {
  873. return 1;
  874. }
  875. else
  876. {
  877. $this->error=$this->db->lasterror();
  878. return -1;
  879. }
  880. }
  881. else
  882. {
  883. dol_syslog(get_class($this)."::set_valide expensereport already with valide status", LOG_WARNING);
  884. }
  885. }
  886. /**
  887. * setDeny
  888. *
  889. * @param User $fuser User
  890. * @param Details $details Details
  891. */
  892. function setDeny($fuser,$details)
  893. {
  894. $now = dol_now();
  895. // date de refus
  896. if ($this->fk_statut != 99)
  897. {
  898. $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
  899. $sql.= " SET ref = '".$this->ref."', fk_statut = 99, fk_user_refuse = ".$fuser->id.",";
  900. $sql.= " date_refuse='".$this->db->idate($now)."',";
  901. $sql.= " detail_refuse='".$this->db->escape($details)."',";
  902. $sql.= " fk_user_approve = NULL";
  903. $sql.= ' WHERE rowid = '.$this->id;
  904. if ($this->db->query($sql))
  905. {
  906. $this->fk_statut = 99;
  907. $this->fk_user_refuse = $fuser->id;
  908. $this->detail_refuse = $details;
  909. $this->date_refuse = $now;
  910. return 1;
  911. }
  912. else
  913. {
  914. $this->error=$this->db->lasterror();
  915. return -1;
  916. }
  917. }
  918. else
  919. {
  920. dol_syslog(get_class($this)."::setDeny expensereport already with refuse status", LOG_WARNING);
  921. }
  922. }
  923. /**
  924. * set_unpaid
  925. *
  926. * @param User $fuser User
  927. * @return int <0 if KO, >0 if OK
  928. */
  929. function set_unpaid($fuser)
  930. {
  931. if ($this->fk_c_deplacement_statuts != 5)
  932. {
  933. $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
  934. $sql.= " SET fk_statut = 5";
  935. $sql.= ' WHERE rowid = '.$this->id;
  936. dol_syslog(get_class($this)."::set_unpaid sql=".$sql, LOG_DEBUG);
  937. if ($this->db->query($sql)):
  938. return 1;
  939. else:
  940. $this->error=$this->db->error();
  941. return -1;
  942. endif;
  943. }
  944. else
  945. {
  946. dol_syslog(get_class($this)."::set_unpaid expensereport already with unpaid status", LOG_WARNING);
  947. }
  948. }
  949. /**
  950. * set_cancel
  951. *
  952. * @param User $fuser User
  953. * @param string $detail Detail
  954. * @return int <0 if KO, >0 if OK
  955. */
  956. function set_cancel($fuser,$detail)
  957. {
  958. $this->date_cancel = $this->db->idate(gmmktime());
  959. if ($this->fk_statut != 4)
  960. {
  961. $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
  962. $sql.= " SET fk_statut = 4, fk_user_cancel = ".$fuser->id;
  963. $sql.= ", date_cancel='".$this->date_cancel."'";
  964. $sql.= " ,detail_cancel='".$this->db->escape($detail)."'";
  965. $sql.= ' WHERE rowid = '.$this->id;
  966. dol_syslog(get_class($this)."::set_cancel sql=".$sql, LOG_DEBUG);
  967. if ($this->db->query($sql))
  968. {
  969. return 1;
  970. }
  971. else
  972. {
  973. $this->error=$this->db->error();
  974. return -1;
  975. }
  976. }
  977. else
  978. {
  979. dol_syslog(get_class($this)."::set_cancel expensereport already with cancel status", LOG_WARNING);
  980. }
  981. }
  982. /**
  983. * Return next reference of expense report not already used
  984. *
  985. * @return string free ref
  986. */
  987. function getNextNumRef()
  988. {
  989. global $conf;
  990. $expld_car = (empty($conf->global->NDF_EXPLODE_CHAR))?"-":$conf->global->NDF_EXPLODE_CHAR;
  991. $num_car = (empty($conf->global->NDF_NUM_CAR_REF))?"5":$conf->global->NDF_NUM_CAR_REF;
  992. $sql = 'SELECT de.ref_number_int';
  993. $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' de';
  994. $sql.= ' ORDER BY de.ref_number_int DESC';
  995. $result = $this->db->query($sql);
  996. if($this->db->num_rows($result) > 0):
  997. $objp = $this->db->fetch_object($result);
  998. $this->ref = $objp->ref_number_int;
  999. $this->ref++;
  1000. while(strlen($this->ref) < $num_car):
  1001. $this->ref = "0".$this->ref;
  1002. endwhile;
  1003. else:
  1004. $this->ref = 1;
  1005. while(strlen($this->ref) < $num_car):
  1006. $this->ref = "0".$this->ref;
  1007. endwhile;
  1008. endif;
  1009. if ($result):
  1010. return 1;
  1011. else:
  1012. $this->error=$this->db->error();
  1013. return -1;
  1014. endif;
  1015. }
  1016. /**
  1017. * Return clicable name (with picto eventually)
  1018. *
  1019. * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto
  1020. * @return string String with URL
  1021. */
  1022. function getNomUrl($withpicto=0)
  1023. {
  1024. global $langs;
  1025. $result='';
  1026. $link = '<a href="'.DOL_URL_ROOT.'/expensereport/card.php?id='.$this->id.'">';
  1027. $linkend='</a>';
  1028. $picto='trip';
  1029. $label=$langs->trans("Show").': '.$this->ref;
  1030. if ($withpicto) $result.=($link.img_object($label,$picto).$linkend);
  1031. if ($withpicto && $withpicto != 2) $result.=' ';
  1032. if ($withpicto != 2) $result.=$link.$this->ref.$linkend;
  1033. return $result;
  1034. }
  1035. /**
  1036. * Update total of an expense report when you add a line.
  1037. *
  1038. * @param string $ligne_total_ht Amount without taxes
  1039. * @param string $ligne_total_tva Amount of all taxes
  1040. * @return void
  1041. */
  1042. function update_totaux_add($ligne_total_ht,$ligne_total_tva)
  1043. {
  1044. $this->total_ht = $this->total_ht + $ligne_total_ht;
  1045. $this->total_tva = $this->total_tva + $ligne_total_tva;
  1046. $this->total_ttc = $this->total_ht + $this->total_tva;
  1047. $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET";
  1048. $sql.= " total_ht = ".$this->total_ht;
  1049. $sql.= " , total_ttc = ".$this->total_ttc;
  1050. $sql.= " , total_tva = ".$this->total_tva;
  1051. $sql.= " WHERE rowid = ".$this->id;
  1052. $result = $this->db->query($sql);
  1053. if ($result):
  1054. return 1;
  1055. else:
  1056. $this->error=$this->db->error();
  1057. return -1;
  1058. endif;
  1059. }
  1060. /**
  1061. * Update total of an expense report when you delete a line.
  1062. *
  1063. * @param string $ligne_total_ht Amount without taxes
  1064. * @param string $ligne_total_tva Amount of all taxes
  1065. * @return void
  1066. */
  1067. function update_totaux_del($ligne_total_ht,$ligne_total_tva)
  1068. {
  1069. $this->total_ht = $this->total_ht - $ligne_total_ht;
  1070. $this->total_tva = $this->total_tva - $ligne_total_tva;
  1071. $this->total_ttc = $this->total_ht + $this->total_tva;
  1072. $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET";
  1073. $sql.= " total_ht = ".$this->total_ht;
  1074. $sql.= " , total_ttc = ".$this->total_ttc;
  1075. $sql.= " , total_tva = ".$this->total_tva;
  1076. $sql.= " WHERE rowid = ".$this->id;
  1077. $result = $this->db->query($sql);
  1078. if ($result):
  1079. return 1;
  1080. else:
  1081. $this->error=$this->db->error();
  1082. return -1;
  1083. endif;
  1084. }
  1085. /**
  1086. * updateline
  1087. *
  1088. * @param int $rowid Line to edit
  1089. * @param int $type_fees_id Type payment
  1090. * @param int $projet_id Project id
  1091. * @param double $vatrate Vat rate
  1092. * @param string $comments Description
  1093. * @param real $qty Qty
  1094. * @param double $value_unit Value init
  1095. * @param int $date Date
  1096. * @param int $expensereport_id Expense report id
  1097. * @return int <0 if KO, >0 if OK
  1098. */
  1099. function updateline($rowid, $type_fees_id, $projet_id, $vatrate, $comments, $qty, $value_unit, $date, $expensereport_id)
  1100. {
  1101. global $user;
  1102. if ($this->fk_statut==0 || $this->fk_statut==99)
  1103. {
  1104. $this->db->begin();
  1105. // calcul de tous les totaux de la ligne
  1106. $total_ttc = price2num($qty*$value_unit, 'MT');
  1107. $tx_tva = $vatrate / 100;
  1108. $tx_tva = $tx_tva + 1;
  1109. $total_ht = price2num($total_ttc/$tx_tva, 'MT');
  1110. $total_tva = price2num($total_ttc - $total_ht, 'MT');
  1111. // fin calculs
  1112. $ligne = new ExpenseReportLine($this->db);
  1113. $ligne->comments = $comments;
  1114. $ligne->qty = $qty;
  1115. $ligne->value_unit = $value_unit;
  1116. $ligne->date = $date;
  1117. $ligne->fk_expensereport= $expensereport_id;
  1118. $ligne->fk_c_type_fees = $type_fees_id;
  1119. $ligne->fk_projet = $projet_id;
  1120. $ligne->total_ht = $total_ht;
  1121. $ligne->total_tva = $total_tva;
  1122. $ligne->total_ttc = $total_ttc;
  1123. $ligne->vatrate = price2num($vatrate);
  1124. $ligne->rowid = $rowid;
  1125. // Select des infos sur le type fees
  1126. $sql = "SELECT c.code as code_type_fees, c.label as libelle_type_fees";
  1127. $sql.= " FROM ".MAIN_DB_PREFIX."c_type_fees as c";
  1128. $sql.= " WHERE c.id = ".$type_fees_id;
  1129. $result = $this->db->query($sql);
  1130. $objp_fees = $this->db->fetch_object($result);
  1131. $ligne->type_fees_code = $objp_fees->code_type_fees;
  1132. $ligne->type_fees_libelle = $objp_fees->libelle_type_fees;
  1133. // Select des informations du projet
  1134. $sql = "SELECT p.ref as ref_projet, p.title as title_projet";
  1135. $sql.= " FROM ".MAIN_DB_PREFIX."projet as p";
  1136. $sql.= " WHERE p.rowid = ".$projet_id;
  1137. $result = $this->db->query($sql);
  1138. if ($result) {
  1139. $objp_projet = $this->db->fetch_object($result);
  1140. }
  1141. $ligne->projet_ref = $objp_projet->ref_projet;
  1142. $ligne->projet_title = $objp_projet->title_projet;
  1143. $result = $ligne->update($user);
  1144. if ($result > 0)
  1145. {
  1146. $this->db->commit();
  1147. return 1;
  1148. }
  1149. else
  1150. {
  1151. $this->error=$ligne->error;
  1152. $this->errors=$ligne->errors;
  1153. $this->db->rollback();
  1154. return -2;
  1155. }
  1156. }
  1157. }
  1158. /**
  1159. * deleteline
  1160. *
  1161. * @param int $rowid Row id
  1162. * @param User $fuser User
  1163. * @return int <0 if KO, >0 if OK
  1164. */
  1165. function deleteline($rowid, $fuser='')
  1166. {
  1167. $this->db->begin();
  1168. $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element_line;
  1169. $sql.= ' WHERE rowid = '.$rowid;
  1170. dol_syslog(get_class($this)."::deleteline sql=".$sql);
  1171. $result = $this->db->query($sql);
  1172. if (!$result)
  1173. {
  1174. $this->error=$this->db->error();
  1175. dol_syslog(get_class($this)."::deleteline Error ".$this->error, LOG_ERR);
  1176. $this->db->rollback();
  1177. return -1;
  1178. }
  1179. $this->db->commit();
  1180. return 1;
  1181. }
  1182. /**
  1183. * periode_existe
  1184. *
  1185. * @param User $fuser User
  1186. * @param Date $date_debut Start date
  1187. * @param Date $date_fin End date
  1188. * @return int <0 if KO, >0 if OK
  1189. */
  1190. function periode_existe($fuser, $date_debut, $date_fin)
  1191. {
  1192. $sql = "SELECT rowid, date_debut, date_fin";
  1193. $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element;
  1194. $sql.= " WHERE fk_user_author = '{$fuser->id}'";
  1195. dol_syslog(get_class($this)."::periode_existe sql=".$sql);
  1196. $result = $this->db->query($sql);
  1197. if($result)
  1198. {
  1199. $num_lignes = $this->db->num_rows($result); $i = 0;
  1200. if ($num_lignes>0)
  1201. {
  1202. $date_d_form = $date_debut;
  1203. $date_f_form = $date_fin;
  1204. $existe = false;
  1205. while ($i < $num_lignes)
  1206. {
  1207. $objp = $this->db->fetch_object($result);
  1208. $date_d_req = $this->db->jdate($objp->date_debut); // 3
  1209. $date_f_req = $this->db->jdate($objp->date_fin); // 4
  1210. if (!($date_f_form < $date_d_req || $date_d_form > $date_f_req)) $existe = true;
  1211. $i++;
  1212. }
  1213. if($existe) return 1;
  1214. else return 0;
  1215. }
  1216. else
  1217. {
  1218. return 0;
  1219. }
  1220. }
  1221. else
  1222. {
  1223. $this->error=$this->db->lasterror();
  1224. dol_syslog(get_class($this)."::periode_existe Error ".$this->error, LOG_ERR);
  1225. return -1;
  1226. }
  1227. }
  1228. /**
  1229. * Return list of people with permission to validate trips and expenses
  1230. *
  1231. * @return array Array of user ids
  1232. */
  1233. function fetch_users_approver_expensereport()
  1234. {
  1235. $users_validator=array();
  1236. $sql = "SELECT fk_user";
  1237. $sql.= " FROM ".MAIN_DB_PREFIX."user_rights as ur, ".MAIN_DB_PREFIX."rights_def as rd";
  1238. $sql.= " WHERE ur.fk_id = rd.id and module = 'expensereport' AND perms = 'approve'"; // Permission 'Approve';
  1239. dol_syslog(get_class($this)."::fetch_users_approver_expensereport sql=".$sql);
  1240. $result = $this->db->query($sql);
  1241. if($result)
  1242. {
  1243. $num_lignes = $this->db->num_rows($result); $i = 0;
  1244. while ($i < $num_lignes)
  1245. {
  1246. $objp = $this->db->fetch_object($result);
  1247. array_push($users_validator,$objp->fk_user);
  1248. $i++;
  1249. }
  1250. return $users_validator;
  1251. }
  1252. else
  1253. {
  1254. $this->error=$this->db->lasterror();
  1255. dol_syslog(get_class($this)."::fetch_users_approver_expensereport Error ".$this->error, LOG_ERR);
  1256. return -1;
  1257. }
  1258. }
  1259. /**
  1260. * Create a document onto disk accordign to template module.
  1261. *
  1262. * @param string $modele Force le mnodele a utiliser ('' to not force)
  1263. * @param Translate $outputlangs objet lang a utiliser pour traduction
  1264. * @param int $hidedetails Hide details of lines
  1265. * @param int $hidedesc Hide description
  1266. * @param int $hideref Hide ref
  1267. * @return int 0 if KO, 1 if OK
  1268. */
  1269. public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
  1270. {
  1271. global $conf,$langs;
  1272. $langs->load("trips");
  1273. // Positionne le modele sur le nom du modele a utiliser
  1274. if (! dol_strlen($modele))
  1275. {
  1276. if (! empty($conf->global->EXPENSEREPORT_ADDON_PDF))
  1277. {
  1278. $modele = $conf->global->EXPENSEREPORT_ADDON_PDF;
  1279. }
  1280. else
  1281. {
  1282. $modele = 'standard';
  1283. }
  1284. }
  1285. $modelpath = "core/modules/expensereport/doc/";
  1286. return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
  1287. }
  1288. /**
  1289. * List of types
  1290. *
  1291. * @param int $active Active or not
  1292. * @return array
  1293. */
  1294. function listOfTypes($active=1)
  1295. {
  1296. global $langs;
  1297. $ret=array();
  1298. $sql = "SELECT id, code, label";
  1299. $sql.= " FROM ".MAIN_DB_PREFIX."c_type_fees";
  1300. $sql.= " WHERE active = ".$active;
  1301. dol_syslog(get_class($this)."::listOfTypes", LOG_DEBUG);
  1302. $result = $this->db->query($sql);
  1303. if ( $result )
  1304. {
  1305. $num = $this->db->num_rows($result);
  1306. $i=0;
  1307. while ($i < $num)
  1308. {
  1309. $obj = $this->db->fetch_object($result);
  1310. $ret[$obj->code]=(($langs->trans($obj->code)!=$obj->code)?$langs->trans($obj->code):$obj->label);
  1311. $i++;
  1312. }
  1313. }
  1314. else
  1315. {
  1316. dol_print_error($this->db);
  1317. }
  1318. return $ret;
  1319. }
  1320. /**
  1321. * Charge indicateurs this->nb pour le tableau de bord
  1322. *
  1323. * @return int <0 if KO, >0 if OK
  1324. */
  1325. function load_state_board()
  1326. {
  1327. global $conf;
  1328. $this->nb=array();
  1329. $sql = "SELECT count(ex.rowid) as nb";
  1330. $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as ex";
  1331. $sql.= " WHERE ex.fk_statut > 0";
  1332. $sql.= " AND ex.entity IN (".getEntity('expensereport', 1).")";
  1333. $resql=$this->db->query($sql);
  1334. if ($resql)
  1335. {
  1336. while ($obj=$this->db->fetch_object($resql))
  1337. {
  1338. $this->nb["expensereports"]=$obj->nb;
  1339. }
  1340. $this->db->free($resql);
  1341. return 1;
  1342. }
  1343. else
  1344. {
  1345. dol_print_error($this->db);
  1346. $this->error=$this->db->error();
  1347. return -1;
  1348. }
  1349. }
  1350. /**
  1351. * Load indicators for dashboard (this->nbtodo and this->nbtodolate)
  1352. *
  1353. * @param User $user Objet user
  1354. * @param string $option 'topay' or 'toapprove'
  1355. * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK
  1356. */
  1357. function load_board($user, $option='topay')
  1358. {
  1359. global $conf, $langs;
  1360. if ($user->societe_id) return -1; // protection pour eviter appel par utilisateur externe
  1361. $now=dol_now();
  1362. $sql = "SELECT ex.rowid, ex.date_valid";
  1363. $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as ex";
  1364. if ($option == 'toapprove') $sql.= " WHERE ex.fk_statut = 2";
  1365. else $sql.= " WHERE ex.fk_statut = 5";
  1366. $sql.= " AND ex.entity IN (".getEntity('expensereport', 1).")";
  1367. $resql=$this->db->query($sql);
  1368. if ($resql)
  1369. {
  1370. $langs->load("members");
  1371. $response = new WorkboardResponse();
  1372. if ($option == 'toapprove')
  1373. {
  1374. $response->warning_delay=$conf->expensereport->approve->warning_delay/60/60/24;
  1375. $response->label=$langs->trans("ExpenseReportsToApprove");
  1376. $response->url=DOL_URL_ROOT.'/expensereport/list.php?mainmenu=hrm&amp;statut=2';
  1377. }
  1378. else
  1379. {
  1380. $response->warning_delay=$conf->expensereport->payment->warning_delay/60/60/24;
  1381. $response->label=$langs->trans("ExpenseReportsToPay");
  1382. $response->url=DOL_URL_ROOT.'/expensereport/list.php?mainmenu=hrm&amp;statut=5';
  1383. }
  1384. $response->img=img_object($langs->trans("ExpenseReports"),"trip");
  1385. while ($obj=$this->db->fetch_object($resql))
  1386. {
  1387. $response->nbtodo++;
  1388. if ($option == 'toapprove')
  1389. {
  1390. if ($this->db->jdate($obj->datevalid) < ($now - $conf->expensereport->approve->warning_delay)) {
  1391. $response->nbtodolate++;
  1392. }
  1393. }
  1394. else
  1395. {
  1396. if ($this->db->jdate($obj->datevalid) < ($now - $conf->expensereport->payment->warning_delay)) {
  1397. $response->nbtodolate++;
  1398. }
  1399. }
  1400. }
  1401. return $response;
  1402. }
  1403. else
  1404. {
  1405. dol_print_error($this->db);
  1406. $this->error=$this->db->error();
  1407. return -1;
  1408. }
  1409. }
  1410. /**
  1411. * Return if an expense report is late or not
  1412. *
  1413. * @param string $option 'topay' or 'toapprove'
  1414. * @return boolean True if late, False if not late
  1415. */
  1416. public function hasDelay($option)
  1417. {
  1418. global $conf;
  1419. //Only valid members
  1420. if ($option == 'toapprove' && $this->status != 2) return false;
  1421. if ($option == 'topay' && $this->status != 5) return false;
  1422. $now = dol_now();
  1423. if ($option == 'toapprove')
  1424. return $this->datevalid < ($now - $conf->expensereport->approve->warning_delay);
  1425. else
  1426. return $this->datevalid < ($now - $conf->expensereport->payment->warning_delay);
  1427. }
  1428. }
  1429. /**
  1430. * Class of expense report details lines
  1431. */
  1432. class ExpenseReportLine
  1433. {
  1434. var $db;
  1435. var $error;
  1436. var $rowid;
  1437. var $comments;
  1438. var $qty;
  1439. var $value_unit;
  1440. var $date;
  1441. var $fk_c_type_fees;
  1442. var $fk_projet;
  1443. var $fk_expensereport;
  1444. var $type_fees_code;
  1445. var $type_fees_libelle;
  1446. var $projet_ref;
  1447. var $projet_title;
  1448. var $vatrate;
  1449. var $total_ht;
  1450. var $total_tva;
  1451. var $total_ttc;
  1452. /**
  1453. * Constructor
  1454. *
  1455. * @param DoliDB $db Handlet database
  1456. */
  1457. function __construct($db)
  1458. {
  1459. $this->db= $db;
  1460. }
  1461. /**
  1462. * Fetch record for expense report detailed line
  1463. *
  1464. * @param int $rowid Id of object to load
  1465. * @return int <0 if KO, >0 if OK
  1466. */
  1467. function fetch($rowid)
  1468. {
  1469. $sql = 'SELECT fde.rowid, fde.fk_expensereport, fde.fk_c_type_fees, fde.fk_projet, fde.date,';
  1470. $sql.= ' fde.tva_tx as vatrate, fde.comments, fde.qty, fde.value_unit, fde.total_ht, fde.total_tva, fde.total_ttc,';
  1471. $sql.= ' ctf.code as type_fees_code, ctf.label as type_fees_libelle,';
  1472. $sql.= ' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref';
  1473. $sql.= ' FROM '.MAIN_DB_PREFIX.'expensereport_det as fde';
  1474. $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id';
  1475. $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as pjt ON fde.fk_projet=pjt.rowid';
  1476. $sql.= ' WHERE fde.rowid = '.$rowid;
  1477. $result = $this->db->query($sql);
  1478. if($result)
  1479. {
  1480. $objp = $this->db->fetch_object($result);
  1481. $this->rowid = $objp->rowid;
  1482. $this->id = $obj->rowid;
  1483. $this->ref = $obj->ref;
  1484. $this->fk_expensereport = $objp->fk_expensereport;
  1485. $this->comments = $objp->comments;
  1486. $this->qty = $objp->qty;
  1487. $this->date = $objp->date;
  1488. $this->value_unit = $objp->value_unit;
  1489. $this->fk_c_type_fees = $objp->fk_c_type_fees;
  1490. $this->fk_projet = $objp->fk_projet;
  1491. $this->type_fees_code = $objp->type_fees_code;
  1492. $this->type_fees_libelle = $objp->type_fees_libelle;
  1493. $this->projet_ref = $objp->projet_ref;
  1494. $this->projet_title = $objp->projet_title;
  1495. $this->vatrate = $objp->vatrate;
  1496. $this->total_ht = $objp->total_ht;
  1497. $this->total_tva = $objp->total_tva;
  1498. $this->total_ttc = $objp->total_ttc;
  1499. $this->db->free($result);
  1500. } else {
  1501. dol_print_error($this->db);
  1502. }
  1503. }
  1504. /**
  1505. * insert
  1506. *
  1507. * @param int $notrigger 1=No trigger
  1508. * @return int <0 if KO, >0 if OK
  1509. */
  1510. function insert($notrigger=0)
  1511. {
  1512. global $langs,$user,$conf;
  1513. $error=0;
  1514. dol_syslog("ExpenseReportLine::Insert rang=".$this->rang, LOG_DEBUG);
  1515. // Clean parameters
  1516. $this->comments=trim($this->comments);
  1517. if (!$this->value_unit_HT) $this->value_unit_HT=0;
  1518. $this->qty = price2num($this->qty);
  1519. $this->vatrate = price2num($this->vatrate);
  1520. $this->db->begin();
  1521. $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'expensereport_det';
  1522. $sql.= ' (fk_expensereport, fk_c_type_fees, fk_projet,';
  1523. $sql.= ' tva_tx, comments, qty, value_unit, total_ht, total_tva, total_ttc, date)';
  1524. $sql.= " VALUES (".$this->fk_expensereport.",";
  1525. $sql.= " ".$this->fk_c_type_fees.",";
  1526. $sql.= " ".($this->fk_projet>0?$this->fk_projet:'null').",";
  1527. $sql.= " ".$this->vatrate.",";
  1528. $sql.= " '".$this->db->escape($this->comments)."',";
  1529. $sql.= " ".$this->qty.",";
  1530. $sql.= " ".$this->value_unit.",";
  1531. $sql.= " ".$this->total_ht.",";
  1532. $sql.= " ".$this->total_tva.",";
  1533. $sql.= " ".$this->total_ttc.",";
  1534. $sql.= "'".$this->db->idate($this->date)."'";
  1535. $sql.= ")";
  1536. dol_syslog("ExpenseReportLine::insert sql=".$sql);
  1537. $resql=$this->db->query($sql);
  1538. if ($resql)
  1539. {
  1540. $this->rowid=$this->db->last_insert_id(MAIN_DB_PREFIX.'expensereport_det');
  1541. $tmpparent=new ExpenseReport($this->db);
  1542. $tmpparent->fetch($this->fk_expensereport);
  1543. $result = $tmpparent->update_price();
  1544. if ($result < 0)
  1545. {
  1546. $error++;
  1547. $this->error = $tmpparent->error;
  1548. $this->errors = $tmpparent->errors;
  1549. }
  1550. }
  1551. if (! $error)
  1552. {
  1553. $this->db->commit();
  1554. return $this->rowid;
  1555. }
  1556. else
  1557. {
  1558. $this->error=$this->db->lasterror();
  1559. dol_syslog("ExpenseReportLine::insert Error ".$this->error, LOG_ERR);
  1560. $this->db->rollback();
  1561. return -2;
  1562. }
  1563. }
  1564. /**
  1565. * update
  1566. *
  1567. * @param User $fuser User
  1568. * @return int <0 if KO, >0 if OK
  1569. */
  1570. function update($fuser)
  1571. {
  1572. global $fuser,$langs,$conf;
  1573. $error=0;
  1574. // Clean parameters
  1575. $this->comments=trim($this->comments);
  1576. $this->vatrate = price2num($this->vatrate);
  1577. $this->value_unit = price2num($this->value_unit);
  1578. $this->db->begin();
  1579. // Mise a jour ligne en base
  1580. $sql = "UPDATE ".MAIN_DB_PREFIX."expensereport_det SET";
  1581. $sql.= " comments='".$this->db->escape($this->comments)."'";
  1582. $sql.= ",value_unit=".$this->value_unit."";
  1583. $sql.= ",qty=".$this->qty."";
  1584. $sql.= ",date='".$this->db->idate($this->date)."'";
  1585. $sql.= ",total_ht=".$this->total_ht."";
  1586. $sql.= ",total_tva=".$this->total_tva."";
  1587. $sql.= ",total_ttc=".$this->total_ttc."";
  1588. $sql.= ",tva_tx=".$this->vatrate;
  1589. if ($this->fk_c_type_fees) $sql.= ",fk_c_type_fees=".$this->fk_c_type_fees;
  1590. else $sql.= ",fk_c_type_fees=null";
  1591. if ($this->fk_projet) $sql.= ",fk_projet=".$this->fk_projet;
  1592. else $sql.= ",fk_projet=null";
  1593. $sql.= " WHERE rowid = ".$this->rowid;
  1594. dol_syslog("ExpenseReportLine::update sql=".$sql);
  1595. $resql=$this->db->query($sql);
  1596. if ($resql)
  1597. {
  1598. $tmpparent=new ExpenseReport($this->db);
  1599. $result = $tmpparent->fetch($this->fk_expensereport);
  1600. if ($result > 0)
  1601. {
  1602. $result = $tmpparent->update_price();
  1603. if ($result < 0)
  1604. {
  1605. $error++;
  1606. $this->error = $tmpparent->error;
  1607. $this->errors = $tmpparent->errors;
  1608. }
  1609. }
  1610. else
  1611. {
  1612. $error++;
  1613. $this->error = $tmpparent->error;
  1614. $this->errors = $tmpparent->errors;
  1615. }
  1616. }
  1617. else
  1618. {
  1619. $error++;
  1620. dol_print_error($this->db);
  1621. }
  1622. if (! $error)
  1623. {
  1624. $this->db->commit();
  1625. return 1;
  1626. }
  1627. else
  1628. {
  1629. $this->error=$this->db->lasterror();
  1630. dol_syslog("ExpenseReportLine::update Error ".$this->error, LOG_ERR);
  1631. $this->db->rollback();
  1632. return -2;
  1633. }
  1634. }
  1635. }
  1636. /**
  1637. * Retourne la liste deroulante des differents etats d'une note de frais.
  1638. * Les valeurs de la liste sont les id de la table c_expensereport_statuts
  1639. *
  1640. * @param int $selected preselect status
  1641. * @param string $htmlname Name of HTML select
  1642. * @param int $useempty 1=Add empty line
  1643. * @param int $useshortlabel Use short labels
  1644. * @return string HTML select with status
  1645. */
  1646. function select_expensereport_statut($selected='',$htmlname='fk_statut',$useempty=1, $useshortlabel=0)
  1647. {
  1648. global $db, $langs;
  1649. $tmpep=new ExpenseReport($db);
  1650. print '<select class="flat" name="'.$htmlname.'">';
  1651. if ($useempty) print '<option value="-1">&nbsp;</option>';
  1652. $arrayoflabels=$tmpep->statuts;
  1653. if ($useshortlabel) $arrayoflabels=$tmpep->statuts_short;
  1654. foreach ($arrayoflabels as $key => $val)
  1655. {
  1656. if ($selected != '' && $selected == $key)
  1657. {
  1658. print '<option value="'.$key.'" selected>';
  1659. }
  1660. else
  1661. {
  1662. print '<option value="'.$key.'">';
  1663. }
  1664. print $langs->trans($val);
  1665. print '</option>';
  1666. }
  1667. print '</select>';
  1668. }
  1669. /**
  1670. * Return list of types of notes with select value = id
  1671. *
  1672. * @param int $selected Preselected type
  1673. * @param string $htmlname Name of field in form
  1674. * @param int $showempty Add an empty field
  1675. * @return string Select html
  1676. */
  1677. function select_type_fees_id($selected='',$htmlname='type',$showempty=0)
  1678. {
  1679. global $db,$langs,$user;
  1680. $langs->load("trips");
  1681. print '<select class="flat" name="'.$htmlname.'">';
  1682. if ($showempty)
  1683. {
  1684. print '<option value="-1"';
  1685. if ($selected == -1) print ' selected';
  1686. print '>&nbsp;</option>';
  1687. }
  1688. $sql = "SELECT c.id, c.code, c.label as type FROM ".MAIN_DB_PREFIX."c_type_fees as c";
  1689. $sql.= " ORDER BY c.label ASC";
  1690. $resql=$db->query($sql);
  1691. if ($resql)
  1692. {
  1693. $num = $db->num_rows($resql);
  1694. $i = 0;
  1695. while ($i < $num)
  1696. {
  1697. $obj = $db->fetch_object($resql);
  1698. print '<option value="'.$obj->id.'"';
  1699. if ($obj->code == $selected || $obj->id == $selected) print ' selected';
  1700. print '>';
  1701. if ($obj->code != $langs->trans($obj->code)) print $langs->trans($obj->code);
  1702. else print $langs->trans($obj->type);
  1703. $i++;
  1704. }
  1705. }
  1706. print '</select>';
  1707. }