holiday.class.php 71 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385
  1. <?php
  2. /* Copyright (C) 2011 Dimitri Mouillard <dmouillard@teclib.com>
  3. * Copyright (C) 2012-2014 Laurent Destailleur <eldy@users.sourceforge.net>
  4. * Copyright (C) 2012-2016 Regis Houssin <regis.houssin@inodbox.com>
  5. * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
  6. * Copyright (C) 2016 Juanjo Menent <jmenent@2byte.es>
  7. * Copyright (C) 2018-2021 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 holiday.class.php
  24. * \ingroup holiday
  25. * \brief Class file of the module paid holiday.
  26. */
  27. require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
  28. /**
  29. * Class of the module paid holiday. Developed by Teclib ( http://www.teclib.com/ )
  30. */
  31. class Holiday extends CommonObject
  32. {
  33. /**
  34. * @var string ID to identify managed object
  35. */
  36. public $element = 'holiday';
  37. /**
  38. * @var string Name of table without prefix where object is stored
  39. */
  40. public $table_element = 'holiday';
  41. /**
  42. * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
  43. * @var int
  44. */
  45. public $ismultientitymanaged = 0;
  46. /**
  47. * @var string Field with ID of parent key if this field has a parent
  48. */
  49. public $fk_element = 'fk_holiday';
  50. /**
  51. * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
  52. */
  53. public $picto = 'holiday';
  54. /**
  55. * @deprecated
  56. * @see $id
  57. */
  58. public $rowid;
  59. /**
  60. * @var int User ID
  61. */
  62. public $fk_user;
  63. public $date_create = '';
  64. /**
  65. * @var string description
  66. */
  67. public $description;
  68. public $date_debut = ''; // Date start in PHP server TZ
  69. public $date_fin = ''; // Date end in PHP server TZ
  70. public $date_debut_gmt = ''; // Date start in GMT
  71. public $date_fin_gmt = ''; // Date end in GMT
  72. public $halfday = ''; // 0:Full days, 2:Start afternoon end morning, -1:Start afternoon end afternoon, 1:Start morning end morning
  73. public $statut = ''; // 1=draft, 2=validated, 3=approved
  74. /**
  75. * @var int ID of user that must approve. TODO: there is no date for validation (date_valid is used for approval), add one.
  76. */
  77. public $fk_validator;
  78. /**
  79. * @var int Date of approval. TODO: Add a field for approval date and use date_valid instead for validation.
  80. */
  81. public $date_valid = '';
  82. /**
  83. * @var int ID of user that has approved (empty if not approved)
  84. */
  85. public $fk_user_valid;
  86. /**
  87. * @var int Date for refuse
  88. */
  89. public $date_refuse = '';
  90. /**
  91. * @var int ID for refuse
  92. */
  93. public $fk_user_refuse;
  94. /**
  95. * @var int Date for cancelation
  96. */
  97. public $date_cancel = '';
  98. /**
  99. * @var int ID for cancelation
  100. */
  101. public $fk_user_cancel;
  102. public $detail_refuse = '';
  103. /**
  104. * @var int ID
  105. */
  106. public $fk_type;
  107. public $holiday = array();
  108. public $events = array();
  109. public $logs = array();
  110. public $optName = '';
  111. public $optValue = '';
  112. public $optRowid = '';
  113. /**
  114. * Draft status
  115. */
  116. const STATUS_DRAFT = 1;
  117. /**
  118. * Validated status
  119. */
  120. const STATUS_VALIDATED = 2;
  121. /**
  122. * Approved
  123. */
  124. const STATUS_APPROVED = 3;
  125. /**
  126. * Canceled
  127. */
  128. const STATUS_CANCELED = 4;
  129. /**
  130. * Refused
  131. */
  132. const STATUS_REFUSED = 5;
  133. /**
  134. * Constructor
  135. *
  136. * @param DoliDB $db Database handler
  137. */
  138. public function __construct($db)
  139. {
  140. $this->db = $db;
  141. }
  142. /**
  143. * Returns the reference to the following non used Order depending on the active numbering module
  144. * defined into HOLIDAY_ADDON
  145. *
  146. * @param Societe $objsoc third party object
  147. * @return string Holiday free reference
  148. */
  149. public function getNextNumRef($objsoc)
  150. {
  151. global $langs, $conf;
  152. $langs->load("order");
  153. if (empty($conf->global->HOLIDAY_ADDON)) {
  154. $conf->global->HOLIDAY_ADDON = 'mod_holiday_madonna';
  155. }
  156. if (!empty($conf->global->HOLIDAY_ADDON)) {
  157. $mybool = false;
  158. $file = $conf->global->HOLIDAY_ADDON.".php";
  159. $classname = $conf->global->HOLIDAY_ADDON;
  160. // Include file with class
  161. $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
  162. foreach ($dirmodels as $reldir) {
  163. $dir = dol_buildpath($reldir."core/modules/holiday/");
  164. // Load file with numbering class (if found)
  165. $mybool |= @include_once $dir.$file;
  166. }
  167. if ($mybool === false) {
  168. dol_print_error('', "Failed to include file ".$file);
  169. return '';
  170. }
  171. $obj = new $classname();
  172. $numref = $obj->getNextValue($objsoc, $this);
  173. if ($numref != "") {
  174. return $numref;
  175. } else {
  176. $this->error = $obj->error;
  177. //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
  178. return "";
  179. }
  180. } else {
  181. print $langs->trans("Error")." ".$langs->trans("Error_HOLIDAY_ADDON_NotDefined");
  182. return "";
  183. }
  184. }
  185. /**
  186. * Update balance of vacations and check table of users for holidays is complete. If not complete.
  187. *
  188. * @return int <0 if KO, >0 if OK
  189. */
  190. public function updateBalance()
  191. {
  192. $this->db->begin();
  193. // Update sold of vocations
  194. $result = $this->updateSoldeCP();
  195. // Check nb of users into table llx_holiday_users and update with empty lines
  196. //if ($result > 0) $result = $this->verifNbUsers($this->countActiveUsersWithoutCP(), $this->getConfCP('nbUser'));
  197. if ($result >= 0) {
  198. $this->db->commit();
  199. return 0; // for cronjob use (0 is OK, any other value is an error code)
  200. } else {
  201. $this->db->rollback();
  202. return -1;
  203. }
  204. }
  205. /**
  206. * Créer un congés payés dans la base de données
  207. *
  208. * @param User $user User that create
  209. * @param int $notrigger 0=launch triggers after, 1=disable triggers
  210. * @return int <0 if KO, Id of created object if OK
  211. */
  212. public function create($user, $notrigger = 0)
  213. {
  214. global $conf;
  215. $error = 0;
  216. $now = dol_now();
  217. // Check parameters
  218. if (empty($this->fk_user) || !is_numeric($this->fk_user) || $this->fk_user < 0) {
  219. $this->error = "ErrorBadParameterFkUser"; return -1;
  220. }
  221. if (empty($this->fk_validator) || !is_numeric($this->fk_validator) || $this->fk_validator < 0) {
  222. $this->error = "ErrorBadParameterFkValidator"; return -1;
  223. }
  224. if (empty($this->fk_type) || !is_numeric($this->fk_type) || $this->fk_type < 0) {
  225. $this->error = "ErrorBadParameterFkType"; return -1;
  226. }
  227. // Insert request
  228. $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday(";
  229. $sql .= "ref,";
  230. $sql .= "fk_user,";
  231. $sql .= "date_create,";
  232. $sql .= "description,";
  233. $sql .= "date_debut,";
  234. $sql .= "date_fin,";
  235. $sql .= "halfday,";
  236. $sql .= "statut,";
  237. $sql .= "fk_validator,";
  238. $sql .= "fk_type,";
  239. $sql .= "fk_user_create,";
  240. $sql .= "entity";
  241. $sql .= ") VALUES (";
  242. $sql .= "'(PROV)',";
  243. $sql .= " ".((int) $this->fk_user).",";
  244. $sql .= " '".$this->db->idate($now)."',";
  245. $sql .= " '".$this->db->escape($this->description)."',";
  246. $sql .= " '".$this->db->idate($this->date_debut)."',";
  247. $sql .= " '".$this->db->idate($this->date_fin)."',";
  248. $sql .= " ".((int) $this->halfday).",";
  249. $sql .= " '1',";
  250. $sql .= " ".((int) $this->fk_validator).",";
  251. $sql .= " ".((int) $this->fk_type).",";
  252. $sql .= " ".((int) $user->id).",";
  253. $sql .= " ".((int) $conf->entity);
  254. $sql .= ")";
  255. $this->db->begin();
  256. dol_syslog(get_class($this)."::create", LOG_DEBUG);
  257. $resql = $this->db->query($sql);
  258. if (!$resql) {
  259. $error++; $this->errors[] = "Error ".$this->db->lasterror();
  260. }
  261. if (!$error) {
  262. $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."holiday");
  263. if ($this->id) {
  264. // update ref
  265. $initialref = '(PROV'.$this->id.')';
  266. if (!empty($this->ref)) {
  267. $initialref = $this->ref;
  268. }
  269. $sql = 'UPDATE '.MAIN_DB_PREFIX."holiday SET ref='".$this->db->escape($initialref)."' WHERE rowid=".((int) $this->id);
  270. if ($this->db->query($sql)) {
  271. $this->ref = $initialref;
  272. if (!$error) {
  273. $result = $this->insertExtraFields();
  274. if ($result < 0) {
  275. $error++;
  276. }
  277. }
  278. if (!$error && !$notrigger) {
  279. // Call trigger
  280. $result = $this->call_trigger('HOLIDAY_CREATE', $user);
  281. if ($result < 0) {
  282. $error++;
  283. }
  284. // End call triggers
  285. }
  286. }
  287. }
  288. }
  289. // Commit or rollback
  290. if ($error) {
  291. foreach ($this->errors as $errmsg) {
  292. dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR);
  293. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  294. }
  295. $this->db->rollback();
  296. return -1 * $error;
  297. } else {
  298. $this->db->commit();
  299. return $this->id;
  300. }
  301. }
  302. /**
  303. * Load object in memory from database
  304. *
  305. * @param int $id Id object
  306. * @param string $ref Ref object
  307. * @return int <0 if KO, 0 if not found, >0 if OK
  308. */
  309. public function fetch($id, $ref = '')
  310. {
  311. global $langs;
  312. $sql = "SELECT";
  313. $sql .= " cp.rowid,";
  314. $sql .= " cp.ref,";
  315. $sql .= " cp.fk_user,";
  316. $sql .= " cp.date_create,";
  317. $sql .= " cp.description,";
  318. $sql .= " cp.date_debut,";
  319. $sql .= " cp.date_fin,";
  320. $sql .= " cp.halfday,";
  321. $sql .= " cp.statut,";
  322. $sql .= " cp.fk_validator,";
  323. $sql .= " cp.date_valid,";
  324. $sql .= " cp.fk_user_valid,";
  325. $sql .= " cp.date_refuse,";
  326. $sql .= " cp.fk_user_refuse,";
  327. $sql .= " cp.date_cancel,";
  328. $sql .= " cp.fk_user_cancel,";
  329. $sql .= " cp.detail_refuse,";
  330. $sql .= " cp.note_private,";
  331. $sql .= " cp.note_public,";
  332. $sql .= " cp.fk_user_create,";
  333. $sql .= " cp.fk_type,";
  334. $sql .= " cp.entity";
  335. $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp";
  336. if ($id > 0) {
  337. $sql .= " WHERE cp.rowid = ".((int) $id);
  338. } else {
  339. $sql .= " WHERE cp.ref = '".$this->db->escape($ref)."'";
  340. }
  341. dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
  342. $resql = $this->db->query($sql);
  343. if ($resql) {
  344. if ($this->db->num_rows($resql)) {
  345. $obj = $this->db->fetch_object($resql);
  346. $this->id = $obj->rowid;
  347. $this->ref = ($obj->ref ? $obj->ref : $obj->rowid);
  348. $this->fk_user = $obj->fk_user;
  349. $this->date_create = $this->db->jdate($obj->date_create);
  350. $this->description = $obj->description;
  351. $this->date_debut = $this->db->jdate($obj->date_debut);
  352. $this->date_fin = $this->db->jdate($obj->date_fin);
  353. $this->date_debut_gmt = $this->db->jdate($obj->date_debut, 1);
  354. $this->date_fin_gmt = $this->db->jdate($obj->date_fin, 1);
  355. $this->halfday = $obj->halfday;
  356. $this->statut = $obj->statut;
  357. $this->fk_validator = $obj->fk_validator;
  358. $this->date_valid = $this->db->jdate($obj->date_valid);
  359. $this->fk_user_valid = $obj->fk_user_valid;
  360. $this->date_refuse = $this->db->jdate($obj->date_refuse);
  361. $this->fk_user_refuse = $obj->fk_user_refuse;
  362. $this->date_cancel = $this->db->jdate($obj->date_cancel);
  363. $this->fk_user_cancel = $obj->fk_user_cancel;
  364. $this->detail_refuse = $obj->detail_refuse;
  365. $this->note_private = $obj->note_private;
  366. $this->note_public = $obj->note_public;
  367. $this->fk_user_create = $obj->fk_user_create;
  368. $this->fk_type = $obj->fk_type;
  369. $this->entity = $obj->entity;
  370. $this->fetch_optionals();
  371. $result = 1;
  372. } else {
  373. $result = 0;
  374. }
  375. $this->db->free($resql);
  376. return $result;
  377. } else {
  378. $this->error = "Error ".$this->db->lasterror();
  379. return -1;
  380. }
  381. }
  382. /**
  383. * List holidays for a particular user or list of users
  384. *
  385. * @param int|string $user_id ID of user to list, or comma separated list of IDs of users to list
  386. * @param string $order Sort order
  387. * @param string $filter SQL Filter
  388. * @return int -1 if KO, 1 if OK, 2 if no result
  389. */
  390. public function fetchByUser($user_id, $order = '', $filter = '')
  391. {
  392. global $langs, $conf;
  393. $sql = "SELECT";
  394. $sql .= " cp.rowid,";
  395. $sql .= " cp.ref,";
  396. $sql .= " cp.fk_user,";
  397. $sql .= " cp.fk_type,";
  398. $sql .= " cp.date_create,";
  399. $sql .= " cp.description,";
  400. $sql .= " cp.date_debut,";
  401. $sql .= " cp.date_fin,";
  402. $sql .= " cp.halfday,";
  403. $sql .= " cp.statut,";
  404. $sql .= " cp.fk_validator,";
  405. $sql .= " cp.date_valid,";
  406. $sql .= " cp.fk_user_valid,";
  407. $sql .= " cp.date_refuse,";
  408. $sql .= " cp.fk_user_refuse,";
  409. $sql .= " cp.date_cancel,";
  410. $sql .= " cp.fk_user_cancel,";
  411. $sql .= " cp.detail_refuse,";
  412. $sql .= " uu.lastname as user_lastname,";
  413. $sql .= " uu.firstname as user_firstname,";
  414. $sql .= " uu.login as user_login,";
  415. $sql .= " uu.statut as user_statut,";
  416. $sql .= " uu.photo as user_photo,";
  417. $sql .= " ua.lastname as validator_lastname,";
  418. $sql .= " ua.firstname as validator_firstname,";
  419. $sql .= " ua.login as validator_login,";
  420. $sql .= " ua.statut as validator_statut,";
  421. $sql .= " ua.photo as validator_photo";
  422. $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp, ".MAIN_DB_PREFIX."user as uu, ".MAIN_DB_PREFIX."user as ua";
  423. $sql .= " WHERE cp.entity IN (".getEntity('holiday').")";
  424. $sql .= " AND cp.fk_user = uu.rowid AND cp.fk_validator = ua.rowid"; // Hack pour la recherche sur le tableau
  425. $sql .= " AND cp.fk_user IN (".$this->db->sanitize($user_id).")";
  426. // Selection filter
  427. if (!empty($filter)) {
  428. $sql .= $filter;
  429. }
  430. // Order of display of the result
  431. if (!empty($order)) {
  432. $sql .= $order;
  433. }
  434. dol_syslog(get_class($this)."::fetchByUser", LOG_DEBUG);
  435. $resql = $this->db->query($sql);
  436. // If no SQL error
  437. if ($resql) {
  438. $i = 0;
  439. $tab_result = $this->holiday;
  440. $num = $this->db->num_rows($resql);
  441. // If no registration
  442. if (!$num) {
  443. return 2;
  444. }
  445. // List the records and add them to the table
  446. while ($i < $num) {
  447. $obj = $this->db->fetch_object($resql);
  448. $tab_result[$i]['rowid'] = $obj->rowid;
  449. $tab_result[$i]['ref'] = ($obj->ref ? $obj->ref : $obj->rowid);
  450. $tab_result[$i]['fk_user'] = $obj->fk_user;
  451. $tab_result[$i]['fk_type'] = $obj->fk_type;
  452. $tab_result[$i]['date_create'] = $this->db->jdate($obj->date_create);
  453. $tab_result[$i]['description'] = $obj->description;
  454. $tab_result[$i]['date_debut'] = $this->db->jdate($obj->date_debut);
  455. $tab_result[$i]['date_fin'] = $this->db->jdate($obj->date_fin);
  456. $tab_result[$i]['date_debut_gmt'] = $this->db->jdate($obj->date_debut, 1);
  457. $tab_result[$i]['date_fin_gmt'] = $this->db->jdate($obj->date_fin, 1);
  458. $tab_result[$i]['halfday'] = $obj->halfday;
  459. $tab_result[$i]['statut'] = $obj->statut;
  460. $tab_result[$i]['fk_validator'] = $obj->fk_validator;
  461. $tab_result[$i]['date_valid'] = $this->db->jdate($obj->date_valid);
  462. $tab_result[$i]['fk_user_valid'] = $obj->fk_user_valid;
  463. $tab_result[$i]['date_refuse'] = $this->db->jdate($obj->date_refuse);
  464. $tab_result[$i]['fk_user_refuse'] = $obj->fk_user_refuse;
  465. $tab_result[$i]['date_cancel'] = $this->db->jdate($obj->date_cancel);
  466. $tab_result[$i]['fk_user_cancel'] = $obj->fk_user_cancel;
  467. $tab_result[$i]['detail_refuse'] = $obj->detail_refuse;
  468. $tab_result[$i]['user_firstname'] = $obj->user_firstname;
  469. $tab_result[$i]['user_lastname'] = $obj->user_lastname;
  470. $tab_result[$i]['user_login'] = $obj->user_login;
  471. $tab_result[$i]['user_statut'] = $obj->user_statut;
  472. $tab_result[$i]['user_photo'] = $obj->user_photo;
  473. $tab_result[$i]['validator_firstname'] = $obj->validator_firstname;
  474. $tab_result[$i]['validator_lastname'] = $obj->validator_lastname;
  475. $tab_result[$i]['validator_login'] = $obj->validator_login;
  476. $tab_result[$i]['validator_statut'] = $obj->validator_statut;
  477. $tab_result[$i]['validator_photo'] = $obj->validator_photo;
  478. $i++;
  479. }
  480. // Returns 1 with the filled array
  481. $this->holiday = $tab_result;
  482. return 1;
  483. } else {
  484. // SQL Error
  485. $this->error = "Error ".$this->db->lasterror();
  486. return -1;
  487. }
  488. }
  489. /**
  490. * List all holidays of all users
  491. *
  492. * @param string $order Sort order
  493. * @param string $filter SQL Filter
  494. * @return int -1 if KO, 1 if OK, 2 if no result
  495. */
  496. public function fetchAll($order, $filter)
  497. {
  498. global $langs;
  499. $sql = "SELECT";
  500. $sql .= " cp.rowid,";
  501. $sql .= " cp.ref,";
  502. $sql .= " cp.fk_user,";
  503. $sql .= " cp.fk_type,";
  504. $sql .= " cp.date_create,";
  505. $sql .= " cp.tms as date_update,";
  506. $sql .= " cp.description,";
  507. $sql .= " cp.date_debut,";
  508. $sql .= " cp.date_fin,";
  509. $sql .= " cp.halfday,";
  510. $sql .= " cp.statut,";
  511. $sql .= " cp.fk_validator,";
  512. $sql .= " cp.date_valid,";
  513. $sql .= " cp.fk_user_valid,";
  514. $sql .= " cp.date_refuse,";
  515. $sql .= " cp.fk_user_refuse,";
  516. $sql .= " cp.date_cancel,";
  517. $sql .= " cp.fk_user_cancel,";
  518. $sql .= " cp.detail_refuse,";
  519. $sql .= " uu.lastname as user_lastname,";
  520. $sql .= " uu.firstname as user_firstname,";
  521. $sql .= " uu.login as user_login,";
  522. $sql .= " uu.statut as user_statut,";
  523. $sql .= " uu.photo as user_photo,";
  524. $sql .= " ua.lastname as validator_lastname,";
  525. $sql .= " ua.firstname as validator_firstname,";
  526. $sql .= " ua.login as validator_login,";
  527. $sql .= " ua.statut as validator_statut,";
  528. $sql .= " ua.photo as validator_photo";
  529. $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp, ".MAIN_DB_PREFIX."user as uu, ".MAIN_DB_PREFIX."user as ua";
  530. $sql .= " WHERE cp.entity IN (".getEntity('holiday').")";
  531. $sql .= " AND cp.fk_user = uu.rowid AND cp.fk_validator = ua.rowid "; // Hack pour la recherche sur le tableau
  532. // Selection filtering
  533. if (!empty($filter)) {
  534. $sql .= $filter;
  535. }
  536. // order of display
  537. if (!empty($order)) {
  538. $sql .= $order;
  539. }
  540. dol_syslog(get_class($this)."::fetchAll", LOG_DEBUG);
  541. $resql = $this->db->query($sql);
  542. // If no SQL error
  543. if ($resql) {
  544. $i = 0;
  545. $tab_result = $this->holiday;
  546. $num = $this->db->num_rows($resql);
  547. // If no registration
  548. if (!$num) {
  549. return 2;
  550. }
  551. // List the records and add them to the table
  552. while ($i < $num) {
  553. $obj = $this->db->fetch_object($resql);
  554. $tab_result[$i]['rowid'] = $obj->rowid;
  555. $tab_result[$i]['ref'] = ($obj->ref ? $obj->ref : $obj->rowid);
  556. $tab_result[$i]['fk_user'] = $obj->fk_user;
  557. $tab_result[$i]['fk_type'] = $obj->fk_type;
  558. $tab_result[$i]['date_create'] = $this->db->jdate($obj->date_create);
  559. $tab_result[$i]['date_update'] = $this->db->jdate($obj->date_update);
  560. $tab_result[$i]['description'] = $obj->description;
  561. $tab_result[$i]['date_debut'] = $this->db->jdate($obj->date_debut);
  562. $tab_result[$i]['date_fin'] = $this->db->jdate($obj->date_fin);
  563. $tab_result[$i]['date_debut_gmt'] = $this->db->jdate($obj->date_debut, 1);
  564. $tab_result[$i]['date_fin_gmt'] = $this->db->jdate($obj->date_fin, 1);
  565. $tab_result[$i]['halfday'] = $obj->halfday;
  566. $tab_result[$i]['statut'] = $obj->statut;
  567. $tab_result[$i]['fk_validator'] = $obj->fk_validator;
  568. $tab_result[$i]['date_valid'] = $this->db->jdate($obj->date_valid);
  569. $tab_result[$i]['fk_user_valid'] = $obj->fk_user_valid;
  570. $tab_result[$i]['date_refuse'] = $obj->date_refuse;
  571. $tab_result[$i]['fk_user_refuse'] = $obj->fk_user_refuse;
  572. $tab_result[$i]['date_cancel'] = $obj->date_cancel;
  573. $tab_result[$i]['fk_user_cancel'] = $obj->fk_user_cancel;
  574. $tab_result[$i]['detail_refuse'] = $obj->detail_refuse;
  575. $tab_result[$i]['user_firstname'] = $obj->user_firstname;
  576. $tab_result[$i]['user_lastname'] = $obj->user_lastname;
  577. $tab_result[$i]['user_login'] = $obj->user_login;
  578. $tab_result[$i]['user_statut'] = $obj->user_statut;
  579. $tab_result[$i]['user_photo'] = $obj->user_photo;
  580. $tab_result[$i]['validator_firstname'] = $obj->validator_firstname;
  581. $tab_result[$i]['validator_lastname'] = $obj->validator_lastname;
  582. $tab_result[$i]['validator_login'] = $obj->validator_login;
  583. $tab_result[$i]['validator_statut'] = $obj->validator_statut;
  584. $tab_result[$i]['validator_photo'] = $obj->validator_photo;
  585. $i++;
  586. }
  587. // Returns 1 and adds the array to the variable
  588. $this->holiday = $tab_result;
  589. return 1;
  590. } else {
  591. // SQL Error
  592. $this->error = "Error ".$this->db->lasterror();
  593. return -1;
  594. }
  595. }
  596. /**
  597. * Validate leave request
  598. *
  599. * @param User $user User that validate
  600. * @param int $notrigger 0=launch triggers after, 1=disable triggers
  601. * @return int <0 if KO, >0 if OK
  602. */
  603. public function validate($user = null, $notrigger = 0)
  604. {
  605. global $conf, $langs;
  606. require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
  607. $error = 0;
  608. $checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type);
  609. if ($checkBalance > 0) {
  610. $balance = $this->getCPforUser($this->fk_user, $this->fk_type);
  611. if ($balance < 0) {
  612. $this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
  613. return -1;
  614. }
  615. }
  616. // Define new ref
  617. if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref) || $this->ref == $this->id)) {
  618. $num = $this->getNextNumRef(null);
  619. } else {
  620. $num = $this->ref;
  621. }
  622. $this->newref = dol_sanitizeFileName($num);
  623. // Update status
  624. $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
  625. if (!empty($this->statut) && is_numeric($this->statut)) {
  626. $sql .= " statut = ".((int) $this->statut).",";
  627. } else {
  628. $error++;
  629. }
  630. $sql .= " ref = '".$this->db->escape($num)."'";
  631. $sql .= " WHERE rowid = ".((int) $this->id);
  632. $this->db->begin();
  633. dol_syslog(get_class($this)."::validate", LOG_DEBUG);
  634. $resql = $this->db->query($sql);
  635. if (!$resql) {
  636. $error++; $this->errors[] = "Error ".$this->db->lasterror();
  637. }
  638. if (!$error) {
  639. if (!$notrigger) {
  640. // Call trigger
  641. $result = $this->call_trigger('HOLIDAY_VALIDATE', $user);
  642. if ($result < 0) {
  643. $error++;
  644. }
  645. // End call triggers
  646. }
  647. }
  648. if (!$error) {
  649. $this->oldref = $this->ref;
  650. // Rename directory if dir was a temporary ref
  651. if (preg_match('/^[\(]?PROV/i', $this->ref)) {
  652. // Now we rename also files into index
  653. $sql = 'UPDATE ' . MAIN_DB_PREFIX . "ecm_files set filename = CONCAT('" . $this->db->escape($this->newref) . "', SUBSTR(filename, " . (strlen($this->ref) + 1) . ")), filepath = 'holiday/" . $this->db->escape($this->newref) . "'";
  654. $sql .= " WHERE filename LIKE '" . $this->db->escape($this->ref) . "%' AND filepath = 'holiday/" . $this->db->escape($this->ref) . "' and entity = " . ((int) $conf->entity);
  655. $resql = $this->db->query($sql);
  656. if (!$resql) {
  657. $error++;
  658. $this->error = $this->db->lasterror();
  659. }
  660. // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
  661. $oldref = dol_sanitizeFileName($this->ref);
  662. $newref = dol_sanitizeFileName($num);
  663. $dirsource = $conf->holiday->multidir_output[$this->entity] . '/' . $oldref;
  664. $dirdest = $conf->holiday->multidir_output[$this->entity] . '/' . $newref;
  665. if (!$error && file_exists($dirsource)) {
  666. dol_syslog(get_class($this) . "::validate rename dir " . $dirsource . " into " . $dirdest);
  667. if (@rename($dirsource, $dirdest)) {
  668. dol_syslog("Rename ok");
  669. // Rename docs starting with $oldref with $newref
  670. $listoffiles = dol_dir_list($dirdest, 'files', 1, '^' . preg_quote($oldref, '/'));
  671. foreach ($listoffiles as $fileentry) {
  672. $dirsource = $fileentry['name'];
  673. $dirdest = preg_replace('/^' . preg_quote($oldref, '/') . '/', $newref, $dirsource);
  674. $dirsource = $fileentry['path'] . '/' . $dirsource;
  675. $dirdest = $fileentry['path'] . '/' . $dirdest;
  676. @rename($dirsource, $dirdest);
  677. }
  678. }
  679. }
  680. }
  681. }
  682. // Commit or rollback
  683. if ($error) {
  684. foreach ($this->errors as $errmsg) {
  685. dol_syslog(get_class($this)."::validate ".$errmsg, LOG_ERR);
  686. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  687. }
  688. $this->db->rollback();
  689. return -1 * $error;
  690. } else {
  691. $this->db->commit();
  692. return 1;
  693. }
  694. }
  695. /**
  696. * Approve leave request
  697. *
  698. * @param User $user User that approve
  699. * @param int $notrigger 0=launch triggers after, 1=disable triggers
  700. * @return int <0 if KO, >0 if OK
  701. */
  702. public function approve($user = null, $notrigger = 0)
  703. {
  704. global $conf, $langs;
  705. $error = 0;
  706. $checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type);
  707. if ($checkBalance > 0) {
  708. $balance = $this->getCPforUser($this->fk_user, $this->fk_type);
  709. if ($balance < 0) {
  710. $this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
  711. return -1;
  712. }
  713. }
  714. // Update request
  715. $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
  716. $sql .= " description= '".$this->db->escape($this->description)."',";
  717. if (!empty($this->date_debut)) {
  718. $sql .= " date_debut = '".$this->db->idate($this->date_debut)."',";
  719. } else {
  720. $error++;
  721. }
  722. if (!empty($this->date_fin)) {
  723. $sql .= " date_fin = '".$this->db->idate($this->date_fin)."',";
  724. } else {
  725. $error++;
  726. }
  727. $sql .= " halfday = ".((int) $this->halfday).",";
  728. if (!empty($this->statut) && is_numeric($this->statut)) {
  729. $sql .= " statut = ".((int) $this->statut).",";
  730. } else {
  731. $error++;
  732. }
  733. if (!empty($this->fk_validator)) {
  734. $sql .= " fk_validator = '".$this->db->escape($this->fk_validator)."',";
  735. } else {
  736. $error++;
  737. }
  738. if (!empty($this->date_valid)) {
  739. $sql .= " date_valid = '".$this->db->idate($this->date_valid)."',";
  740. } else {
  741. $sql .= " date_valid = NULL,";
  742. }
  743. if (!empty($this->fk_user_valid)) {
  744. $sql .= " fk_user_valid = '".$this->db->escape($this->fk_user_valid)."',";
  745. } else {
  746. $sql .= " fk_user_valid = NULL,";
  747. }
  748. if (!empty($this->date_refuse)) {
  749. $sql .= " date_refuse = '".$this->db->idate($this->date_refuse)."',";
  750. } else {
  751. $sql .= " date_refuse = NULL,";
  752. }
  753. if (!empty($this->fk_user_refuse)) {
  754. $sql .= " fk_user_refuse = '".$this->db->escape($this->fk_user_refuse)."',";
  755. } else {
  756. $sql .= " fk_user_refuse = NULL,";
  757. }
  758. if (!empty($this->date_cancel)) {
  759. $sql .= " date_cancel = '".$this->db->idate($this->date_cancel)."',";
  760. } else {
  761. $sql .= " date_cancel = NULL,";
  762. }
  763. if (!empty($this->fk_user_cancel)) {
  764. $sql .= " fk_user_cancel = '".$this->db->escape($this->fk_user_cancel)."',";
  765. } else {
  766. $sql .= " fk_user_cancel = NULL,";
  767. }
  768. if (!empty($this->detail_refuse)) {
  769. $sql .= " detail_refuse = '".$this->db->escape($this->detail_refuse)."'";
  770. } else {
  771. $sql .= " detail_refuse = NULL";
  772. }
  773. $sql .= " WHERE rowid = ".((int) $this->id);
  774. $this->db->begin();
  775. dol_syslog(get_class($this)."::approve", LOG_DEBUG);
  776. $resql = $this->db->query($sql);
  777. if (!$resql) {
  778. $error++; $this->errors[] = "Error ".$this->db->lasterror();
  779. }
  780. if (!$error) {
  781. if (!$notrigger) {
  782. // Call trigger
  783. $result = $this->call_trigger('HOLIDAY_APPROVE', $user);
  784. if ($result < 0) {
  785. $error++;
  786. }
  787. // End call triggers
  788. }
  789. }
  790. // Commit or rollback
  791. if ($error) {
  792. foreach ($this->errors as $errmsg) {
  793. dol_syslog(get_class($this)."::approve ".$errmsg, LOG_ERR);
  794. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  795. }
  796. $this->db->rollback();
  797. return -1 * $error;
  798. } else {
  799. $this->db->commit();
  800. return 1;
  801. }
  802. }
  803. /**
  804. * Update database
  805. *
  806. * @param User $user User that modify
  807. * @param int $notrigger 0=launch triggers after, 1=disable triggers
  808. * @return int <0 if KO, >0 if OK
  809. */
  810. public function update($user = null, $notrigger = 0)
  811. {
  812. global $conf, $langs;
  813. $error = 0;
  814. $checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type);
  815. if ($checkBalance > 0 && $this->statut != self::STATUS_DRAFT) {
  816. $balance = $this->getCPforUser($this->fk_user, $this->fk_type);
  817. if ($balance < 0) {
  818. $this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
  819. return -1;
  820. }
  821. }
  822. // Update request
  823. $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
  824. $sql .= " description= '".$this->db->escape($this->description)."',";
  825. if (!empty($this->date_debut)) {
  826. $sql .= " date_debut = '".$this->db->idate($this->date_debut)."',";
  827. } else {
  828. $error++;
  829. }
  830. if (!empty($this->date_fin)) {
  831. $sql .= " date_fin = '".$this->db->idate($this->date_fin)."',";
  832. } else {
  833. $error++;
  834. }
  835. $sql .= " halfday = ".$this->halfday.",";
  836. if (!empty($this->statut) && is_numeric($this->statut)) {
  837. $sql .= " statut = ".$this->statut.",";
  838. } else {
  839. $error++;
  840. }
  841. if (!empty($this->fk_validator)) {
  842. $sql .= " fk_validator = '".$this->db->escape($this->fk_validator)."',";
  843. } else {
  844. $error++;
  845. }
  846. if (!empty($this->date_valid)) {
  847. $sql .= " date_valid = '".$this->db->idate($this->date_valid)."',";
  848. } else {
  849. $sql .= " date_valid = NULL,";
  850. }
  851. if (!empty($this->fk_user_valid)) {
  852. $sql .= " fk_user_valid = '".$this->db->escape($this->fk_user_valid)."',";
  853. } else {
  854. $sql .= " fk_user_valid = NULL,";
  855. }
  856. if (!empty($this->date_refuse)) {
  857. $sql .= " date_refuse = '".$this->db->idate($this->date_refuse)."',";
  858. } else {
  859. $sql .= " date_refuse = NULL,";
  860. }
  861. if (!empty($this->fk_user_refuse)) {
  862. $sql .= " fk_user_refuse = '".$this->db->escape($this->fk_user_refuse)."',";
  863. } else {
  864. $sql .= " fk_user_refuse = NULL,";
  865. }
  866. if (!empty($this->date_cancel)) {
  867. $sql .= " date_cancel = '".$this->db->idate($this->date_cancel)."',";
  868. } else {
  869. $sql .= " date_cancel = NULL,";
  870. }
  871. if (!empty($this->fk_user_cancel)) {
  872. $sql .= " fk_user_cancel = '".$this->db->escape($this->fk_user_cancel)."',";
  873. } else {
  874. $sql .= " fk_user_cancel = NULL,";
  875. }
  876. if (!empty($this->detail_refuse)) {
  877. $sql .= " detail_refuse = '".$this->db->escape($this->detail_refuse)."'";
  878. } else {
  879. $sql .= " detail_refuse = NULL";
  880. }
  881. $sql .= " WHERE rowid = ".((int) $this->id);
  882. $this->db->begin();
  883. dol_syslog(get_class($this)."::update", LOG_DEBUG);
  884. $resql = $this->db->query($sql);
  885. if (!$resql) {
  886. $error++; $this->errors[] = "Error ".$this->db->lasterror();
  887. }
  888. if (!$error) {
  889. if (!$notrigger) {
  890. // Call trigger
  891. $result = $this->call_trigger('HOLIDAY_MODIFY', $user);
  892. if ($result < 0) {
  893. $error++;
  894. }
  895. // End call triggers
  896. }
  897. }
  898. // Commit or rollback
  899. if ($error) {
  900. foreach ($this->errors as $errmsg) {
  901. dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
  902. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  903. }
  904. $this->db->rollback();
  905. return -1 * $error;
  906. } else {
  907. $this->db->commit();
  908. return 1;
  909. }
  910. }
  911. /**
  912. * Delete object in database
  913. *
  914. * @param User $user User that delete
  915. * @param int $notrigger 0=launch triggers after, 1=disable triggers
  916. * @return int <0 if KO, >0 if OK
  917. */
  918. public function delete($user, $notrigger = 0)
  919. {
  920. global $conf, $langs;
  921. $error = 0;
  922. $sql = "DELETE FROM ".MAIN_DB_PREFIX."holiday";
  923. $sql .= " WHERE rowid=".((int) $this->id);
  924. $this->db->begin();
  925. dol_syslog(get_class($this)."::delete", LOG_DEBUG);
  926. $resql = $this->db->query($sql);
  927. if (!$resql) {
  928. $error++; $this->errors[] = "Error ".$this->db->lasterror();
  929. }
  930. if (!$error) {
  931. if (!$notrigger) {
  932. // Call trigger
  933. $result = $this->call_trigger('HOLIDAY_DELETE', $user);
  934. if ($result < 0) {
  935. $error++;
  936. }
  937. // End call triggers
  938. }
  939. }
  940. // Commit or rollback
  941. if ($error) {
  942. foreach ($this->errors as $errmsg) {
  943. dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
  944. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  945. }
  946. $this->db->rollback();
  947. return -1 * $error;
  948. } else {
  949. $this->db->commit();
  950. return 1;
  951. }
  952. }
  953. /**
  954. * Check if a user is on holiday (partially or completely) into a period.
  955. * This function can be used to avoid to have 2 leave requests on same period for example.
  956. * Warning: It consumes a lot of memory because it load in ->holiday all holiday of a dedicated user at each call.
  957. *
  958. * @param int $fk_user Id user
  959. * @param integer $dateStart Start date of period to check
  960. * @param integer $dateEnd End date of period to check
  961. * @param int $halfday Tag to define how start and end the period to check:
  962. * 0:Full days, 2:Start afternoon end morning, -1:Start afternoon end afternoon, 1:Start morning end morning
  963. * @return boolean False = New range overlap an existing holiday, True = no overlapping (is never on holiday during checked period).
  964. * @see verifDateHolidayForTimestamp()
  965. */
  966. public function verifDateHolidayCP($fk_user, $dateStart, $dateEnd, $halfday = 0)
  967. {
  968. $this->fetchByUser($fk_user, '', '');
  969. foreach ($this->holiday as $infos_CP) {
  970. if ($infos_CP['statut'] == 4) {
  971. continue; // ignore not validated holidays
  972. }
  973. if ($infos_CP['statut'] == 5) {
  974. continue; // ignore not validated holidays
  975. }
  976. //var_dump("--");
  977. //var_dump("old: ".dol_print_date($infos_CP['date_debut'],'dayhour').' '.dol_print_date($infos_CP['date_fin'],'dayhour').' '.$infos_CP['halfday']);
  978. //var_dump("new: ".dol_print_date($dateStart,'dayhour').' '.dol_print_date($dateEnd,'dayhour').' '.$halfday);
  979. if ($halfday == 0) {
  980. if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
  981. return false;
  982. }
  983. if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
  984. return false;
  985. }
  986. } elseif ($halfday == -1) {
  987. // new start afternoon, new end afternoon
  988. if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
  989. if ($dateStart < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
  990. return false;
  991. }
  992. }
  993. if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
  994. if ($dateStart < $dateEnd) {
  995. return false;
  996. }
  997. if ($dateEnd < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
  998. return false;
  999. }
  1000. }
  1001. } elseif ($halfday == 1) {
  1002. // new start morning, new end morning
  1003. if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
  1004. if ($dateStart < $dateEnd) {
  1005. return false;
  1006. }
  1007. if ($dateStart > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
  1008. return false;
  1009. }
  1010. }
  1011. if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
  1012. if ($dateEnd > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
  1013. return false;
  1014. }
  1015. }
  1016. } elseif ($halfday == 2) {
  1017. // new start afternoon, new end morning
  1018. if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
  1019. if ($dateStart < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
  1020. return false;
  1021. }
  1022. }
  1023. if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
  1024. if ($dateEnd > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
  1025. return false;
  1026. }
  1027. }
  1028. } else {
  1029. dol_print_error('', 'Bad value of parameter halfday when calling function verifDateHolidayCP');
  1030. }
  1031. }
  1032. return true;
  1033. }
  1034. /**
  1035. * Check that a user is not on holiday for a particular timestamp. Can check approved leave requests and not into public holidays of company.
  1036. *
  1037. * @param int $fk_user Id user
  1038. * @param integer $timestamp Time stamp date for a day (YYYY-MM-DD) without hours (= 12:00AM in english and not 12:00PM that is 12:00)
  1039. * @param string $status Filter on holiday status. '-1' = no filter.
  1040. * @return array array('morning'=> ,'afternoon'=> ), Boolean is true if user is available for day timestamp.
  1041. * @see verifDateHolidayCP()
  1042. */
  1043. public function verifDateHolidayForTimestamp($fk_user, $timestamp, $status = '-1')
  1044. {
  1045. global $langs, $conf;
  1046. $isavailablemorning = true;
  1047. $isavailableafternoon = true;
  1048. // Check into leave requests
  1049. $sql = "SELECT cp.rowid, cp.date_debut as date_start, cp.date_fin as date_end, cp.halfday, cp.statut";
  1050. $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp";
  1051. $sql .= " WHERE cp.entity IN (".getEntity('holiday').")";
  1052. $sql .= " AND cp.fk_user = ".(int) $fk_user;
  1053. $sql .= " AND cp.date_debut <= '".$this->db->idate($timestamp)."' AND cp.date_fin >= '".$this->db->idate($timestamp)."'";
  1054. if ($status != '-1') {
  1055. $sql .= " AND cp.statut IN (".$this->db->sanitize($status).")";
  1056. }
  1057. $resql = $this->db->query($sql);
  1058. if ($resql) {
  1059. $num_rows = $this->db->num_rows($resql); // Note, we can have 2 records if on is morning and the other one is afternoon
  1060. if ($num_rows > 0) {
  1061. $arrayofrecord = array();
  1062. $i = 0;
  1063. while ($i < $num_rows) {
  1064. $obj = $this->db->fetch_object($resql);
  1065. // Note: $obj->halfday is 0:Full days, 2:Sart afternoon end morning, -1:Start afternoon, 1:End morning
  1066. $arrayofrecord[$obj->rowid] = array('date_start'=>$this->db->jdate($obj->date_start), 'date_end'=>$this->db->jdate($obj->date_end), 'halfday'=>$obj->halfday);
  1067. $i++;
  1068. }
  1069. // We found a record, user is on holiday by default, so is not available is true.
  1070. $isavailablemorning = true;
  1071. foreach ($arrayofrecord as $record) {
  1072. if ($timestamp == $record['date_start'] && $record['halfday'] == 2) {
  1073. continue;
  1074. }
  1075. if ($timestamp == $record['date_start'] && $record['halfday'] == -1) {
  1076. continue;
  1077. }
  1078. $isavailablemorning = false;
  1079. break;
  1080. }
  1081. $isavailableafternoon = true;
  1082. foreach ($arrayofrecord as $record) {
  1083. if ($timestamp == $record['date_end'] && $record['halfday'] == 2) {
  1084. continue;
  1085. }
  1086. if ($timestamp == $record['date_end'] && $record['halfday'] == 1) {
  1087. continue;
  1088. }
  1089. $isavailableafternoon = false;
  1090. break;
  1091. }
  1092. }
  1093. } else {
  1094. dol_print_error($this->db);
  1095. }
  1096. $result = array('morning'=>$isavailablemorning, 'afternoon'=>$isavailableafternoon);
  1097. if (!$isavailablemorning) {
  1098. $result['morning_reason'] = 'leave_request';
  1099. }
  1100. if (!$isavailableafternoon) {
  1101. $result['afternoon_reason'] = 'leave_request';
  1102. }
  1103. return $result;
  1104. }
  1105. /**
  1106. * Return clicable name (with picto eventually)
  1107. *
  1108. * @param int $withpicto 0=_No picto, 1=Includes the picto in the linkn, 2=Picto only
  1109. * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
  1110. * @param int $notooltip 1=Disable tooltip
  1111. * @return string String with URL
  1112. */
  1113. public function getNomUrl($withpicto = 0, $save_lastsearch_value = -1, $notooltip = 0)
  1114. {
  1115. global $langs, $hookmanager;
  1116. $result = '';
  1117. $label = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Holiday").'</u>';
  1118. if (isset($this->statut)) {
  1119. $label .= ' '.$this->getLibStatut(5);
  1120. }
  1121. $label .= '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
  1122. $url = DOL_URL_ROOT.'/holiday/card.php?id='.$this->id;
  1123. //if ($option != 'nolink')
  1124. //{
  1125. // Add param to save lastsearch_values or not
  1126. $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
  1127. if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
  1128. $add_save_lastsearch_values = 1;
  1129. }
  1130. if ($add_save_lastsearch_values) {
  1131. $url .= '&save_lastsearch_values=1';
  1132. }
  1133. //}
  1134. $linkstart = '<a href="'.$url.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
  1135. $linkend = '</a>';
  1136. $result .= $linkstart;
  1137. if ($withpicto) {
  1138. $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
  1139. }
  1140. if ($withpicto != 2) {
  1141. $result .= $this->ref;
  1142. }
  1143. $result .= $linkend;
  1144. global $action;
  1145. $hookmanager->initHooks(array($this->element . 'dao'));
  1146. $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
  1147. $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
  1148. if ($reshook > 0) {
  1149. $result = $hookmanager->resPrint;
  1150. } else {
  1151. $result .= $hookmanager->resPrint;
  1152. }
  1153. return $result;
  1154. }
  1155. /**
  1156. * Returns the label status
  1157. *
  1158. * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto
  1159. * @return string Label
  1160. */
  1161. public function getLibStatut($mode = 0)
  1162. {
  1163. return $this->LibStatut($this->statut, $mode, $this->date_debut);
  1164. }
  1165. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  1166. /**
  1167. * Returns the label of a status
  1168. *
  1169. * @param int $status Id status
  1170. * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto
  1171. * @param integer $startdate Date holiday should start
  1172. * @return string Label
  1173. */
  1174. public function LibStatut($status, $mode = 0, $startdate = '')
  1175. {
  1176. // phpcs:enable
  1177. global $langs;
  1178. if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
  1179. global $langs;
  1180. //$langs->load("mymodule");
  1181. $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP');
  1182. $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP');
  1183. $this->labelStatus[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP');
  1184. $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP');
  1185. $this->labelStatus[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP');
  1186. $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP');
  1187. $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP');
  1188. $this->labelStatusShort[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP');
  1189. $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP');
  1190. $this->labelStatusShort[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP');
  1191. }
  1192. $params = array();
  1193. $statusType = 'status6';
  1194. if (!empty($startdate) && $startdate >= dol_now()) { // If not yet passed, we use a green "in live" color
  1195. $statusType = 'status4';
  1196. $params = array('tooltip'=>$this->labelStatus[$status].' - '.$langs->trans("Forthcoming"));
  1197. }
  1198. if ($status == self::STATUS_DRAFT) {
  1199. $statusType = 'status0';
  1200. }
  1201. if ($status == self::STATUS_VALIDATED) {
  1202. $statusType = 'status1';
  1203. }
  1204. if ($status == self::STATUS_CANCELED) {
  1205. $statusType = 'status5';
  1206. }
  1207. if ($status == self::STATUS_REFUSED) {
  1208. $statusType = 'status5';
  1209. }
  1210. return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode, '', $params);
  1211. }
  1212. /**
  1213. * Affiche un select HTML des statuts de congés payés
  1214. *
  1215. * @param int $selected Id of preselected status
  1216. * @param string $htmlname Name of HTML select field
  1217. * @param string $morecss More CSS on select component
  1218. * @return string Show select of status
  1219. */
  1220. public function selectStatutCP($selected = '', $htmlname = 'select_statut', $morecss = 'minwidth125')
  1221. {
  1222. global $langs;
  1223. // Liste des statuts
  1224. $name = array('DraftCP', 'ToReviewCP', 'ApprovedCP', 'CancelCP', 'RefuseCP');
  1225. $nb = count($name) + 1;
  1226. // Select HTML
  1227. $out = '<select name="'.$htmlname.'" id="'.$htmlname.'" class="flat'.($morecss ? ' '.$morecss : '').'">'."\n";
  1228. $out .= '<option value="-1">&nbsp;</option>'."\n";
  1229. // Boucle des statuts
  1230. for ($i = 1; $i < $nb; $i++) {
  1231. if ($i == $selected) {
  1232. $out .= '<option value="'.$i.'" selected>'.$langs->trans($name[$i - 1]).'</option>'."\n";
  1233. } else {
  1234. $out .= '<option value="'.$i.'">'.$langs->trans($name[$i - 1]).'</option>'."\n";
  1235. }
  1236. }
  1237. $out .= '</select>'."\n";
  1238. $out .= ajax_combobox($htmlname);
  1239. print $out;
  1240. }
  1241. /**
  1242. * Met à jour une option du module Holiday Payés
  1243. *
  1244. * @param string $name name du paramètre de configuration
  1245. * @param string $value vrai si mise à jour OK sinon faux
  1246. * @return boolean ok or ko
  1247. */
  1248. public function updateConfCP($name, $value)
  1249. {
  1250. $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
  1251. $sql .= " value = '".$this->db->escape($value)."'";
  1252. $sql .= " WHERE name = '".$this->db->escape($name)."'";
  1253. dol_syslog(get_class($this).'::updateConfCP name='.$name.'', LOG_DEBUG);
  1254. $result = $this->db->query($sql);
  1255. if ($result) {
  1256. return true;
  1257. }
  1258. return false;
  1259. }
  1260. /**
  1261. * Return value of a conf parameterfor leave module
  1262. * TODO Move this into llx_const table
  1263. *
  1264. * @param string $name Name of parameter
  1265. * @param string $createifnotfound 'stringvalue'=Create entry with string value if not found. For example 'YYYYMMDDHHMMSS'.
  1266. * @return string Value of parameter. Example: 'YYYYMMDDHHMMSS' or < 0 if error
  1267. */
  1268. public function getConfCP($name, $createifnotfound = '')
  1269. {
  1270. $sql = "SELECT value";
  1271. $sql .= " FROM ".MAIN_DB_PREFIX."holiday_config";
  1272. $sql .= " WHERE name = '".$this->db->escape($name)."'";
  1273. dol_syslog(get_class($this).'::getConfCP name='.$name.' createifnotfound='.$createifnotfound, LOG_DEBUG);
  1274. $result = $this->db->query($sql);
  1275. if ($result) {
  1276. $obj = $this->db->fetch_object($result);
  1277. // Return value
  1278. if (empty($obj)) {
  1279. if ($createifnotfound) {
  1280. $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_config(name, value)";
  1281. $sql .= " VALUES('".$this->db->escape($name)."', '".$this->db->escape($createifnotfound)."')";
  1282. $result = $this->db->query($sql);
  1283. if ($result) {
  1284. return $createifnotfound;
  1285. } else {
  1286. $this->error = $this->db->lasterror();
  1287. return -2;
  1288. }
  1289. } else {
  1290. return '';
  1291. }
  1292. } else {
  1293. return $obj->value;
  1294. }
  1295. } else {
  1296. // Erreur SQL
  1297. $this->error = $this->db->lasterror();
  1298. return -1;
  1299. }
  1300. }
  1301. /**
  1302. * Met à jour le timestamp de la dernière mise à jour du solde des CP
  1303. *
  1304. * @param int $userID Id of user
  1305. * @param float $nbHoliday Nb of days
  1306. * @param int $fk_type Type of vacation
  1307. * @return int 0=Nothing done, 1=OK, -1=KO
  1308. */
  1309. public function updateSoldeCP($userID = '', $nbHoliday = '', $fk_type = '')
  1310. {
  1311. global $user, $langs;
  1312. $error = 0;
  1313. if (empty($userID) && empty($nbHoliday) && empty($fk_type)) {
  1314. $langs->load("holiday");
  1315. // Si mise à jour pour tout le monde en début de mois
  1316. $now = dol_now();
  1317. $month = date('m', $now);
  1318. $newdateforlastupdate = dol_print_date($now, '%Y%m%d%H%M%S');
  1319. // Get month of last update
  1320. $lastUpdate = $this->getConfCP('lastUpdate', $newdateforlastupdate);
  1321. $monthLastUpdate = $lastUpdate[4].$lastUpdate[5];
  1322. //print 'month: '.$month.' lastUpdate:'.$lastUpdate.' monthLastUpdate:'.$monthLastUpdate;exit;
  1323. // If month date is not same than the one of last update (the one we saved in database), then we update the timestamp and balance of each open user.
  1324. if ($month != $monthLastUpdate) {
  1325. $this->db->begin();
  1326. $users = $this->fetchUsers(false, false, ' AND u.statut > 0');
  1327. $nbUser = count($users);
  1328. $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
  1329. $sql .= " value = '".$this->db->escape($newdateforlastupdate)."'";
  1330. $sql .= " WHERE name = 'lastUpdate'";
  1331. $result = $this->db->query($sql);
  1332. $typeleaves = $this->getTypes(1, 1);
  1333. // Update each user counter
  1334. foreach ($users as $userCounter) {
  1335. $nbDaysToAdd = (isset($typeleaves[$userCounter['type']]['newbymonth']) ? $typeleaves[$userCounter['type']]['newbymonth'] : 0);
  1336. if (empty($nbDaysToAdd)) {
  1337. continue;
  1338. }
  1339. dol_syslog("We update leave type id ".$userCounter['type']." for user id ".$userCounter['rowid'], LOG_DEBUG);
  1340. $nowHoliday = $userCounter['nb_holiday'];
  1341. $newSolde = $nowHoliday + $nbDaysToAdd;
  1342. // We add a log for each user
  1343. $this->addLogCP($user->id, $userCounter['rowid'], $langs->trans('HolidaysMonthlyUpdate'), $newSolde, $userCounter['type']);
  1344. $result = $this->updateSoldeCP($userCounter['rowid'], $newSolde, $userCounter['type'], $langs->trans('HolidaysMonthlyUpdate'));
  1345. if ($result < 0) {
  1346. $error++;
  1347. break;
  1348. }
  1349. }
  1350. if (!$error) {
  1351. $this->db->commit();
  1352. return 1;
  1353. } else {
  1354. $this->db->rollback();
  1355. return -1;
  1356. }
  1357. }
  1358. return 0;
  1359. } else {
  1360. // Mise à jour pour un utilisateur
  1361. $nbHoliday = price2num($nbHoliday, 5);
  1362. $sql = "SELECT nb_holiday FROM ".MAIN_DB_PREFIX."holiday_users";
  1363. $sql .= " WHERE fk_user = ".(int) $userID." AND fk_type = ".(int) $fk_type;
  1364. $resql = $this->db->query($sql);
  1365. if ($resql) {
  1366. $num = $this->db->num_rows($resql);
  1367. if ($num > 0) {
  1368. // Update for user
  1369. $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_users SET";
  1370. $sql .= " nb_holiday = ".((float) $nbHoliday);
  1371. $sql .= " WHERE fk_user = ".(int) $userID." AND fk_type = ".(int) $fk_type;
  1372. $result = $this->db->query($sql);
  1373. if (!$result) {
  1374. $error++;
  1375. $this->errors[] = $this->db->lasterror();
  1376. }
  1377. } else {
  1378. // Insert for user
  1379. $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users(nb_holiday, fk_user, fk_type) VALUES (";
  1380. $sql .= ((float) $nbHoliday);
  1381. $sql .= ", ".(int) $userID.", ".(int) $fk_type.")";
  1382. $result = $this->db->query($sql);
  1383. if (!$result) {
  1384. $error++;
  1385. $this->errors[] = $this->db->lasterror();
  1386. }
  1387. }
  1388. } else {
  1389. $this->errors[] = $this->db->lasterror();
  1390. $error++;
  1391. }
  1392. if (!$error) {
  1393. return 1;
  1394. } else {
  1395. return -1;
  1396. }
  1397. }
  1398. }
  1399. /**
  1400. * Retourne un checked si vrai
  1401. *
  1402. * @param string $name name du paramètre de configuration
  1403. * @return string retourne checked si > 0
  1404. */
  1405. public function getCheckOption($name)
  1406. {
  1407. $sql = "SELECT value";
  1408. $sql .= " FROM ".MAIN_DB_PREFIX."holiday_config";
  1409. $sql .= " WHERE name = '".$this->db->escape($name)."'";
  1410. $result = $this->db->query($sql);
  1411. if ($result) {
  1412. $obj = $this->db->fetch_object($result);
  1413. // Si la valeur est 1 on retourne checked
  1414. if ($obj->value) {
  1415. return 'checked';
  1416. }
  1417. }
  1418. }
  1419. /**
  1420. * Créer les entrées pour chaque utilisateur au moment de la configuration
  1421. *
  1422. * @param boolean $single Single
  1423. * @param int $userid Id user
  1424. * @return void
  1425. */
  1426. public function createCPusers($single = false, $userid = '')
  1427. {
  1428. // do we have to add balance for all users ?
  1429. if (!$single) {
  1430. dol_syslog(get_class($this).'::createCPusers');
  1431. $arrayofusers = $this->fetchUsers(false, true);
  1432. foreach ($arrayofusers as $users) {
  1433. $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users";
  1434. $sql .= " (fk_user, nb_holiday)";
  1435. $sql .= " VALUES (".((int) $users['rowid'])."', '0')";
  1436. $resql = $this->db->query($sql);
  1437. if (!$resql) {
  1438. dol_print_error($this->db);
  1439. }
  1440. }
  1441. } else {
  1442. $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users";
  1443. $sql .= " (fk_user, nb_holiday)";
  1444. $sql .= " VALUES (".((int) $userid)."', '0')";
  1445. $resql = $this->db->query($sql);
  1446. if (!$resql) {
  1447. dol_print_error($this->db);
  1448. }
  1449. }
  1450. }
  1451. /**
  1452. * Supprime un utilisateur du module Congés Payés
  1453. *
  1454. * @param int $user_id ID de l'utilisateur à supprimer
  1455. * @return boolean Vrai si pas d'erreur, faut si Erreur
  1456. */
  1457. public function deleteCPuser($user_id)
  1458. {
  1459. $sql = "DELETE FROM ".MAIN_DB_PREFIX."holiday_users";
  1460. $sql .= " WHERE fk_user = ".((int) $user_id);
  1461. $this->db->query($sql);
  1462. }
  1463. /**
  1464. * Return balance of holiday for one user
  1465. *
  1466. * @param int $user_id ID de l'utilisateur
  1467. * @param int $fk_type Filter on type
  1468. * @return float Retourne le solde de congés payés de l'utilisateur
  1469. */
  1470. public function getCPforUser($user_id, $fk_type = 0)
  1471. {
  1472. $sql = "SELECT nb_holiday";
  1473. $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users";
  1474. $sql .= " WHERE fk_user = ".(int) $user_id;
  1475. if ($fk_type > 0) {
  1476. $sql .= " AND fk_type = ".(int) $fk_type;
  1477. }
  1478. dol_syslog(get_class($this).'::getCPforUser user_id='.$user_id.' type_id='.$fk_type, LOG_DEBUG);
  1479. $result = $this->db->query($sql);
  1480. if ($result) {
  1481. $obj = $this->db->fetch_object($result);
  1482. //return number_format($obj->nb_holiday,2);
  1483. if ($obj) {
  1484. return $obj->nb_holiday;
  1485. } else {
  1486. return null;
  1487. }
  1488. } else {
  1489. return null;
  1490. }
  1491. }
  1492. /**
  1493. * Get list of Users or list of vacation balance.
  1494. *
  1495. * @param boolean $stringlist If true return a string list of id. If false, return an array with detail.
  1496. * @param boolean $type If true, read Dolibarr user list, if false, return vacation balance list.
  1497. * @param string $filters Filters. Warning: This must not contains data from user input.
  1498. * @return array|string|int Return an array
  1499. */
  1500. public function fetchUsers($stringlist = true, $type = true, $filters = '')
  1501. {
  1502. global $conf;
  1503. dol_syslog(get_class($this)."::fetchUsers", LOG_DEBUG);
  1504. if ($stringlist) {
  1505. if ($type) {
  1506. // If user of Dolibarr
  1507. $sql = "SELECT";
  1508. if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
  1509. $sql .= " DISTINCT";
  1510. }
  1511. $sql .= " u.rowid";
  1512. $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
  1513. if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
  1514. $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
  1515. $sql .= " WHERE ((ug.fk_user = u.rowid";
  1516. $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
  1517. $sql .= " OR u.entity = 0)"; // Show always superadmin
  1518. } else {
  1519. $sql .= " WHERE u.entity IN (".getEntity('user').")";
  1520. }
  1521. $sql .= " AND u.statut > 0";
  1522. $sql .= " AND u.employee = 1"; // We only want employee users for holidays
  1523. if ($filters) {
  1524. $sql .= $filters;
  1525. }
  1526. $resql = $this->db->query($sql);
  1527. // Si pas d'erreur SQL
  1528. if ($resql) {
  1529. $i = 0;
  1530. $num = $this->db->num_rows($resql);
  1531. $stringlist = '';
  1532. // Boucles du listage des utilisateurs
  1533. while ($i < $num) {
  1534. $obj = $this->db->fetch_object($resql);
  1535. if ($i == 0) {
  1536. $stringlist .= $obj->rowid;
  1537. } else {
  1538. $stringlist .= ', '.$obj->rowid;
  1539. }
  1540. $i++;
  1541. }
  1542. // Retoune le tableau des utilisateurs
  1543. return $stringlist;
  1544. } else {
  1545. // Erreur SQL
  1546. $this->error = "Error ".$this->db->lasterror();
  1547. return -1;
  1548. }
  1549. } else {
  1550. // We want only list of vacation balance for user ids
  1551. $sql = "SELECT DISTINCT cpu.fk_user";
  1552. $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u";
  1553. $sql .= " WHERE cpu.fk_user = u.rowid";
  1554. if ($filters) {
  1555. $sql .= $filters;
  1556. }
  1557. $resql = $this->db->query($sql);
  1558. // Si pas d'erreur SQL
  1559. if ($resql) {
  1560. $i = 0;
  1561. $num = $this->db->num_rows($resql);
  1562. $stringlist = '';
  1563. // Boucles du listage des utilisateurs
  1564. while ($i < $num) {
  1565. $obj = $this->db->fetch_object($resql);
  1566. if ($i == 0) {
  1567. $stringlist .= $obj->fk_user;
  1568. } else {
  1569. $stringlist .= ', '.$obj->fk_user;
  1570. }
  1571. $i++;
  1572. }
  1573. // Retoune le tableau des utilisateurs
  1574. return $stringlist;
  1575. } else {
  1576. // Erreur SQL
  1577. $this->error = "Error ".$this->db->lasterror();
  1578. return -1;
  1579. }
  1580. }
  1581. } else {
  1582. // Si faux donc return array
  1583. // List for Dolibarr users
  1584. if ($type) {
  1585. // If we need users of Dolibarr
  1586. $sql = "SELECT";
  1587. if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
  1588. $sql .= " DISTINCT";
  1589. }
  1590. $sql .= " u.rowid, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut, u.fk_user";
  1591. $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
  1592. if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
  1593. $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
  1594. $sql .= " WHERE ((ug.fk_user = u.rowid";
  1595. $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
  1596. $sql .= " OR u.entity = 0)"; // Show always superadmin
  1597. } else {
  1598. $sql .= " WHERE u.entity IN (".getEntity('user').")";
  1599. }
  1600. $sql .= " AND u.statut > 0";
  1601. $sql .= " AND u.employee = 1"; // We only want employee users for holidays
  1602. if ($filters) {
  1603. $sql .= $filters;
  1604. }
  1605. $resql = $this->db->query($sql);
  1606. // Si pas d'erreur SQL
  1607. if ($resql) {
  1608. $i = 0;
  1609. $tab_result = $this->holiday;
  1610. $num = $this->db->num_rows($resql);
  1611. // Boucles du listage des utilisateurs
  1612. while ($i < $num) {
  1613. $obj = $this->db->fetch_object($resql);
  1614. $tab_result[$i]['rowid'] = $obj->rowid; // rowid of user
  1615. $tab_result[$i]['name'] = $obj->lastname; // deprecated
  1616. $tab_result[$i]['lastname'] = $obj->lastname;
  1617. $tab_result[$i]['firstname'] = $obj->firstname;
  1618. $tab_result[$i]['gender'] = $obj->gender;
  1619. $tab_result[$i]['status'] = $obj->statut;
  1620. $tab_result[$i]['employee'] = $obj->employee;
  1621. $tab_result[$i]['photo'] = $obj->photo;
  1622. $tab_result[$i]['fk_user'] = $obj->fk_user; // rowid of manager
  1623. //$tab_result[$i]['type'] = $obj->type;
  1624. //$tab_result[$i]['nb_holiday'] = $obj->nb_holiday;
  1625. $i++;
  1626. }
  1627. // Retoune le tableau des utilisateurs
  1628. return $tab_result;
  1629. } else {
  1630. // Erreur SQL
  1631. $this->errors[] = "Error ".$this->db->lasterror();
  1632. return -1;
  1633. }
  1634. } else {
  1635. // List of vacation balance users
  1636. $sql = "SELECT cpu.fk_type, cpu.nb_holiday, u.rowid, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut, u.fk_user";
  1637. $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u";
  1638. $sql .= " WHERE cpu.fk_user = u.rowid";
  1639. if ($filters) {
  1640. $sql .= $filters;
  1641. }
  1642. $resql = $this->db->query($sql);
  1643. // Si pas d'erreur SQL
  1644. if ($resql) {
  1645. $i = 0;
  1646. $tab_result = $this->holiday;
  1647. $num = $this->db->num_rows($resql);
  1648. // Boucles du listage des utilisateurs
  1649. while ($i < $num) {
  1650. $obj = $this->db->fetch_object($resql);
  1651. $tab_result[$i]['rowid'] = $obj->rowid; // rowid of user
  1652. $tab_result[$i]['name'] = $obj->lastname; // deprecated
  1653. $tab_result[$i]['lastname'] = $obj->lastname;
  1654. $tab_result[$i]['firstname'] = $obj->firstname;
  1655. $tab_result[$i]['gender'] = $obj->gender;
  1656. $tab_result[$i]['status'] = $obj->statut;
  1657. $tab_result[$i]['employee'] = $obj->employee;
  1658. $tab_result[$i]['photo'] = $obj->photo;
  1659. $tab_result[$i]['fk_user'] = $obj->fk_user; // rowid of manager
  1660. $tab_result[$i]['type'] = $obj->fk_type;
  1661. $tab_result[$i]['nb_holiday'] = $obj->nb_holiday;
  1662. $i++;
  1663. }
  1664. // Retoune le tableau des utilisateurs
  1665. return $tab_result;
  1666. } else {
  1667. // Erreur SQL
  1668. $this->error = "Error ".$this->db->lasterror();
  1669. return -1;
  1670. }
  1671. }
  1672. }
  1673. }
  1674. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  1675. /**
  1676. * Return list of people with permission to validate leave requests.
  1677. * Search for permission "approve leave requests"
  1678. *
  1679. * @return array Array of user ids
  1680. */
  1681. public function fetch_users_approver_holiday()
  1682. {
  1683. // phpcs:enable
  1684. $users_validator = array();
  1685. $sql = "SELECT DISTINCT ur.fk_user";
  1686. $sql .= " FROM ".MAIN_DB_PREFIX."user_rights as ur, ".MAIN_DB_PREFIX."rights_def as rd";
  1687. $sql .= " WHERE ur.fk_id = rd.id and rd.module = 'holiday' AND rd.perms = 'approve'"; // Permission 'Approve';
  1688. $sql .= "UNION";
  1689. $sql .= " SELECT DISTINCT ugu.fk_user";
  1690. $sql .= " FROM ".MAIN_DB_PREFIX."usergroup_user as ugu, ".MAIN_DB_PREFIX."usergroup_rights as ur, ".MAIN_DB_PREFIX."rights_def as rd";
  1691. $sql .= " WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'holiday' AND rd.perms = 'approve'"; // Permission 'Approve';
  1692. //print $sql;
  1693. dol_syslog(get_class($this)."::fetch_users_approver_holiday sql=".$sql);
  1694. $result = $this->db->query($sql);
  1695. if ($result) {
  1696. $num_rows = $this->db->num_rows($result); $i = 0;
  1697. while ($i < $num_rows) {
  1698. $objp = $this->db->fetch_object($result);
  1699. array_push($users_validator, $objp->fk_user);
  1700. $i++;
  1701. }
  1702. return $users_validator;
  1703. } else {
  1704. $this->error = $this->db->lasterror();
  1705. dol_syslog(get_class($this)."::fetch_users_approver_holiday Error ".$this->error, LOG_ERR);
  1706. return -1;
  1707. }
  1708. }
  1709. /**
  1710. * Compte le nombre d'utilisateur actifs dans Dolibarr
  1711. *
  1712. * @return int retourne le nombre d'utilisateur
  1713. */
  1714. public function countActiveUsers()
  1715. {
  1716. $sql = "SELECT count(u.rowid) as compteur";
  1717. $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
  1718. $sql .= " WHERE u.statut > 0";
  1719. $result = $this->db->query($sql);
  1720. $objet = $this->db->fetch_object($result);
  1721. return $objet->compteur;
  1722. }
  1723. /**
  1724. * Compte le nombre d'utilisateur actifs dans Dolibarr sans CP
  1725. *
  1726. * @return int retourne le nombre d'utilisateur
  1727. */
  1728. public function countActiveUsersWithoutCP()
  1729. {
  1730. $sql = "SELECT count(u.rowid) as compteur";
  1731. $sql .= " FROM ".MAIN_DB_PREFIX."user as u LEFT OUTER JOIN ".MAIN_DB_PREFIX."holiday_users hu ON (hu.fk_user=u.rowid)";
  1732. $sql .= " WHERE u.statut > 0 AND hu.fk_user IS NULL";
  1733. $result = $this->db->query($sql);
  1734. $objet = $this->db->fetch_object($result);
  1735. return $objet->compteur;
  1736. }
  1737. /**
  1738. * Compare le nombre d'utilisateur actif de Dolibarr à celui des utilisateurs des congés payés
  1739. *
  1740. * @param int $userDolibarrWithoutCP Number of active users in Dolibarr without holidays
  1741. * @param int $userCP Number of active users into table of holidays
  1742. * @return int <0 if KO, >0 if OK
  1743. */
  1744. public function verifNbUsers($userDolibarrWithoutCP, $userCP)
  1745. {
  1746. if (empty($userCP)) {
  1747. $userCP = 0;
  1748. }
  1749. dol_syslog(get_class($this).'::verifNbUsers userDolibarr='.$userDolibarrWithoutCP.' userCP='.$userCP);
  1750. return 1;
  1751. }
  1752. /**
  1753. * addLogCP
  1754. *
  1755. * @param int $fk_user_action Id user creation
  1756. * @param int $fk_user_update Id user update
  1757. * @param string $label Label (Example: 'Leave', 'Manual update', 'Leave request cancelation'...)
  1758. * @param int $new_solde New value
  1759. * @param int $fk_type Type of vacation
  1760. * @return int Id of record added, 0 if nothing done, < 0 if KO
  1761. */
  1762. public function addLogCP($fk_user_action, $fk_user_update, $label, $new_solde, $fk_type)
  1763. {
  1764. global $conf, $langs;
  1765. $error = 0;
  1766. $prev_solde = price2num($this->getCPforUser($fk_user_update, $fk_type), 5);
  1767. $new_solde = price2num($new_solde, 5);
  1768. //print "$prev_solde == $new_solde";
  1769. if ($prev_solde == $new_solde) {
  1770. return 0;
  1771. }
  1772. $this->db->begin();
  1773. // Insert request
  1774. $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_logs (";
  1775. $sql .= "date_action,";
  1776. $sql .= "fk_user_action,";
  1777. $sql .= "fk_user_update,";
  1778. $sql .= "type_action,";
  1779. $sql .= "prev_solde,";
  1780. $sql .= "new_solde,";
  1781. $sql .= "fk_type";
  1782. $sql .= ") VALUES (";
  1783. $sql .= " '".$this->db->idate(dol_now())."',";
  1784. $sql .= " ".((int) $fk_user_action).",";
  1785. $sql .= " ".((int) $fk_user_update).",";
  1786. $sql .= " '".$this->db->escape($label)."',";
  1787. $sql .= " ".((float) $prev_solde).",";
  1788. $sql .= " ".((float) $new_solde).",";
  1789. $sql .= " ".((int) $fk_type);
  1790. $sql .= ")";
  1791. $resql = $this->db->query($sql);
  1792. if (!$resql) {
  1793. $error++; $this->errors[] = "Error ".$this->db->lasterror();
  1794. }
  1795. if (!$error) {
  1796. $this->optRowid = $this->db->last_insert_id(MAIN_DB_PREFIX."holiday_logs");
  1797. }
  1798. // Commit or rollback
  1799. if ($error) {
  1800. foreach ($this->errors as $errmsg) {
  1801. dol_syslog(get_class($this)."::addLogCP ".$errmsg, LOG_ERR);
  1802. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  1803. }
  1804. $this->db->rollback();
  1805. return -1 * $error;
  1806. } else {
  1807. $this->db->commit();
  1808. return $this->optRowid;
  1809. }
  1810. }
  1811. /**
  1812. * Liste le log des congés payés
  1813. *
  1814. * @param string $order Filtrage par ordre
  1815. * @param string $filter Filtre de séléction
  1816. * @return int -1 si erreur, 1 si OK et 2 si pas de résultat
  1817. */
  1818. public function fetchLog($order, $filter)
  1819. {
  1820. $sql = "SELECT";
  1821. $sql .= " cpl.rowid,";
  1822. $sql .= " cpl.date_action,";
  1823. $sql .= " cpl.fk_user_action,";
  1824. $sql .= " cpl.fk_user_update,";
  1825. $sql .= " cpl.type_action,";
  1826. $sql .= " cpl.prev_solde,";
  1827. $sql .= " cpl.new_solde,";
  1828. $sql .= " cpl.fk_type";
  1829. $sql .= " FROM ".MAIN_DB_PREFIX."holiday_logs as cpl";
  1830. $sql .= " WHERE cpl.rowid > 0"; // To avoid error with other search and criteria
  1831. // Filtrage de séléction
  1832. if (!empty($filter)) {
  1833. $sql .= " ".$filter;
  1834. }
  1835. // Ordre d'affichage
  1836. if (!empty($order)) {
  1837. $sql .= " ".$order;
  1838. }
  1839. dol_syslog(get_class($this)."::fetchLog", LOG_DEBUG);
  1840. $resql = $this->db->query($sql);
  1841. // Si pas d'erreur SQL
  1842. if ($resql) {
  1843. $i = 0;
  1844. $tab_result = $this->logs;
  1845. $num = $this->db->num_rows($resql);
  1846. // Si pas d'enregistrement
  1847. if (!$num) {
  1848. return 2;
  1849. }
  1850. // On liste les résultats et on les ajoutent dans le tableau
  1851. while ($i < $num) {
  1852. $obj = $this->db->fetch_object($resql);
  1853. $tab_result[$i]['rowid'] = $obj->rowid;
  1854. $tab_result[$i]['date_action'] = $obj->date_action;
  1855. $tab_result[$i]['fk_user_action'] = $obj->fk_user_action;
  1856. $tab_result[$i]['fk_user_update'] = $obj->fk_user_update;
  1857. $tab_result[$i]['type_action'] = $obj->type_action;
  1858. $tab_result[$i]['prev_solde'] = $obj->prev_solde;
  1859. $tab_result[$i]['new_solde'] = $obj->new_solde;
  1860. $tab_result[$i]['fk_type'] = $obj->fk_type;
  1861. $i++;
  1862. }
  1863. // Retourne 1 et ajoute le tableau à la variable
  1864. $this->logs = $tab_result;
  1865. return 1;
  1866. } else {
  1867. // Erreur SQL
  1868. $this->error = "Error ".$this->db->lasterror();
  1869. return -1;
  1870. }
  1871. }
  1872. /**
  1873. * Return array with list of types
  1874. *
  1875. * @param int $active Status of type. -1 = Both
  1876. * @param int $affect Filter on affect (a request will change sold or not). -1 = Both
  1877. * @return array Return array with list of types
  1878. */
  1879. public function getTypes($active = -1, $affect = -1)
  1880. {
  1881. global $mysoc;
  1882. $sql = "SELECT rowid, code, label, affect, delay, newbymonth";
  1883. $sql .= " FROM ".MAIN_DB_PREFIX."c_holiday_types";
  1884. $sql .= " WHERE (fk_country IS NULL OR fk_country = ".((int) $mysoc->country_id).')';
  1885. if ($active >= 0) {
  1886. $sql .= " AND active = ".((int) $active);
  1887. }
  1888. if ($affect >= 0) {
  1889. $sql .= " AND affect = ".((int) $affect);
  1890. }
  1891. $result = $this->db->query($sql);
  1892. if ($result) {
  1893. $num = $this->db->num_rows($result);
  1894. if ($num) {
  1895. while ($obj = $this->db->fetch_object($result)) {
  1896. $types[$obj->rowid] = array('rowid'=> $obj->rowid, 'code'=> $obj->code, 'label'=>$obj->label, 'affect'=>$obj->affect, 'delay'=>$obj->delay, 'newbymonth'=>$obj->newbymonth);
  1897. }
  1898. return $types;
  1899. }
  1900. } else {
  1901. dol_print_error($this->db);
  1902. }
  1903. return array();
  1904. }
  1905. /**
  1906. * Load information on object
  1907. *
  1908. * @param int $id Id of object
  1909. * @return void
  1910. */
  1911. public function info($id)
  1912. {
  1913. global $conf;
  1914. $sql = "SELECT f.rowid, f.statut as status,";
  1915. $sql .= " f.date_create as datec,";
  1916. $sql .= " f.tms as date_modification,";
  1917. $sql .= " f.date_valid as datev,";
  1918. //$sql .= " f.date_approve as datea,";
  1919. $sql .= " f.date_refuse as dater,";
  1920. $sql .= " f.fk_user_create as fk_user_creation,";
  1921. $sql .= " f.fk_user_modif as fk_user_modification,";
  1922. $sql .= " f.fk_user_valid as fk_user_approve_done,";
  1923. $sql .= " f.fk_validator as fk_user_approve_expected,";
  1924. $sql .= " f.fk_user_refuse as fk_user_refuse";
  1925. $sql .= " FROM ".MAIN_DB_PREFIX."holiday as f";
  1926. $sql .= " WHERE f.rowid = ".((int) $id);
  1927. $sql .= " AND f.entity = ".$conf->entity;
  1928. $resql = $this->db->query($sql);
  1929. if ($resql) {
  1930. if ($this->db->num_rows($resql)) {
  1931. $obj = $this->db->fetch_object($resql);
  1932. $this->id = $obj->rowid;
  1933. $this->date_creation = $this->db->jdate($obj->datec);
  1934. $this->date_modification = $this->db->jdate($obj->date_modification);
  1935. $this->date_validation = $this->db->jdate($obj->datev);
  1936. $this->date_approbation = $this->db->jdate($obj->datea);
  1937. $cuser = new User($this->db);
  1938. $cuser->fetch($obj->fk_user_author);
  1939. $this->user_creation = $cuser;
  1940. if ($obj->fk_user_creation) {
  1941. $cuser = new User($this->db);
  1942. $cuser->fetch($obj->fk_user_creation);
  1943. $this->user_creation = $cuser;
  1944. }
  1945. if ($obj->fk_user_valid) {
  1946. $vuser = new User($this->db);
  1947. $vuser->fetch($obj->fk_user_valid);
  1948. $this->user_validation = $vuser;
  1949. }
  1950. if ($obj->fk_user_modification) {
  1951. $muser = new User($this->db);
  1952. $muser->fetch($obj->fk_user_modification);
  1953. $this->user_modification = $muser;
  1954. }
  1955. if ($obj->status == Holiday::STATUS_APPROVED || $obj->status == Holiday::STATUS_CANCELED) {
  1956. if ($obj->fk_user_approve_done) {
  1957. $auser = new User($this->db);
  1958. $auser->fetch($obj->fk_user_approve_done);
  1959. $this->user_approve = $auser;
  1960. }
  1961. } else {
  1962. if ($obj->fk_user_approve_expected) {
  1963. $auser = new User($this->db);
  1964. $auser->fetch($obj->fk_user_approve_expected);
  1965. $this->user_approve = $auser;
  1966. }
  1967. }
  1968. }
  1969. $this->db->free($resql);
  1970. } else {
  1971. dol_print_error($this->db);
  1972. }
  1973. }
  1974. /**
  1975. * Initialise an instance with random values.
  1976. * Used to build previews or test instances.
  1977. * id must be 0 if object instance is a specimen.
  1978. *
  1979. * @return void
  1980. */
  1981. public function initAsSpecimen()
  1982. {
  1983. global $user, $langs;
  1984. // Initialise parameters
  1985. $this->id = 0;
  1986. $this->specimen = 1;
  1987. $this->fk_user = $user->id;
  1988. $this->description = 'SPECIMEN description';
  1989. $this->date_debut = dol_now();
  1990. $this->date_fin = dol_now() + (24 * 3600);
  1991. $this->date_valid = dol_now();
  1992. $this->fk_validator = $user->id;
  1993. $this->halfday = 0;
  1994. $this->fk_type = 1;
  1995. $this->statut = Holiday::STATUS_VALIDATED;
  1996. }
  1997. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  1998. /**
  1999. * Load this->nb for dashboard
  2000. *
  2001. * @return int <0 if KO, >0 if OK
  2002. */
  2003. public function load_state_board()
  2004. {
  2005. // phpcs:enable
  2006. global $user;
  2007. $this->nb = array();
  2008. $sql = "SELECT count(h.rowid) as nb";
  2009. $sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
  2010. $sql .= " WHERE h.statut > 1";
  2011. $sql .= " AND h.entity IN (".getEntity('holiday').")";
  2012. if (empty($user->rights->expensereport->readall)) {
  2013. $userchildids = $user->getAllChildIds(1);
  2014. $sql .= " AND (h.fk_user IN (".$this->db->sanitize(join(',', $userchildids)).")";
  2015. $sql .= " OR h.fk_validator IN (".$this->db->sanitize(join(',', $userchildids))."))";
  2016. }
  2017. $resql = $this->db->query($sql);
  2018. if ($resql) {
  2019. while ($obj = $this->db->fetch_object($resql)) {
  2020. $this->nb["holidays"] = $obj->nb;
  2021. }
  2022. $this->db->free($resql);
  2023. return 1;
  2024. } else {
  2025. dol_print_error($this->db);
  2026. $this->error = $this->db->error();
  2027. return -1;
  2028. }
  2029. }
  2030. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  2031. /**
  2032. * Load indicators for dashboard (this->nbtodo and this->nbtodolate)
  2033. *
  2034. * @param User $user Objet user
  2035. * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK
  2036. */
  2037. public function load_board($user)
  2038. {
  2039. // phpcs:enable
  2040. global $conf, $langs;
  2041. if ($user->socid) {
  2042. return -1; // protection pour eviter appel par utilisateur externe
  2043. }
  2044. $now = dol_now();
  2045. $sql = "SELECT h.rowid, h.date_debut";
  2046. $sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
  2047. $sql .= " WHERE h.statut = 2";
  2048. $sql .= " AND h.entity IN (".getEntity('holiday').")";
  2049. if (empty($user->rights->expensereport->read_all)) {
  2050. $userchildids = $user->getAllChildIds(1);
  2051. $sql .= " AND (h.fk_user IN (".$this->db->sanitize(join(',', $userchildids)).")";
  2052. $sql .= " OR h.fk_validator IN (".$this->db->sanitize(join(',', $userchildids))."))";
  2053. }
  2054. $resql = $this->db->query($sql);
  2055. if ($resql) {
  2056. $langs->load("members");
  2057. $response = new WorkboardResponse();
  2058. $response->warning_delay = $conf->holiday->approve->warning_delay / 60 / 60 / 24;
  2059. $response->label = $langs->trans("HolidaysToApprove");
  2060. $response->labelShort = $langs->trans("ToApprove");
  2061. $response->url = DOL_URL_ROOT.'/holiday/list.php?search_status=2&amp;mainmenu=hrm&amp;leftmenu=holiday';
  2062. $response->img = img_object('', "holiday");
  2063. while ($obj = $this->db->fetch_object($resql)) {
  2064. $response->nbtodo++;
  2065. if ($this->db->jdate($obj->date_debut) < ($now - $conf->holiday->approve->warning_delay)) {
  2066. $response->nbtodolate++;
  2067. }
  2068. }
  2069. return $response;
  2070. } else {
  2071. dol_print_error($this->db);
  2072. $this->error = $this->db->error();
  2073. return -1;
  2074. }
  2075. }
  2076. }