holiday.class.php 71 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386
  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. $sql .= " ORDER BY sortorder";
  1892. $result = $this->db->query($sql);
  1893. if ($result) {
  1894. $num = $this->db->num_rows($result);
  1895. if ($num) {
  1896. while ($obj = $this->db->fetch_object($result)) {
  1897. $types[$obj->rowid] = array('rowid'=> $obj->rowid, 'code'=> $obj->code, 'label'=>$obj->label, 'affect'=>$obj->affect, 'delay'=>$obj->delay, 'newbymonth'=>$obj->newbymonth);
  1898. }
  1899. return $types;
  1900. }
  1901. } else {
  1902. dol_print_error($this->db);
  1903. }
  1904. return array();
  1905. }
  1906. /**
  1907. * Load information on object
  1908. *
  1909. * @param int $id Id of object
  1910. * @return void
  1911. */
  1912. public function info($id)
  1913. {
  1914. global $conf;
  1915. $sql = "SELECT f.rowid, f.statut as status,";
  1916. $sql .= " f.date_create as datec,";
  1917. $sql .= " f.tms as date_modification,";
  1918. $sql .= " f.date_valid as datev,";
  1919. //$sql .= " f.date_approve as datea,";
  1920. $sql .= " f.date_refuse as dater,";
  1921. $sql .= " f.fk_user_create as fk_user_creation,";
  1922. $sql .= " f.fk_user_modif as fk_user_modification,";
  1923. $sql .= " f.fk_user_valid as fk_user_approve_done,";
  1924. $sql .= " f.fk_validator as fk_user_approve_expected,";
  1925. $sql .= " f.fk_user_refuse as fk_user_refuse";
  1926. $sql .= " FROM ".MAIN_DB_PREFIX."holiday as f";
  1927. $sql .= " WHERE f.rowid = ".((int) $id);
  1928. $sql .= " AND f.entity = ".$conf->entity;
  1929. $resql = $this->db->query($sql);
  1930. if ($resql) {
  1931. if ($this->db->num_rows($resql)) {
  1932. $obj = $this->db->fetch_object($resql);
  1933. $this->id = $obj->rowid;
  1934. $this->date_creation = $this->db->jdate($obj->datec);
  1935. $this->date_modification = $this->db->jdate($obj->date_modification);
  1936. $this->date_validation = $this->db->jdate($obj->datev);
  1937. $this->date_approbation = $this->db->jdate($obj->datea);
  1938. $cuser = new User($this->db);
  1939. $cuser->fetch($obj->fk_user_author);
  1940. $this->user_creation = $cuser;
  1941. if ($obj->fk_user_creation) {
  1942. $cuser = new User($this->db);
  1943. $cuser->fetch($obj->fk_user_creation);
  1944. $this->user_creation = $cuser;
  1945. }
  1946. if ($obj->fk_user_valid) {
  1947. $vuser = new User($this->db);
  1948. $vuser->fetch($obj->fk_user_valid);
  1949. $this->user_validation = $vuser;
  1950. }
  1951. if ($obj->fk_user_modification) {
  1952. $muser = new User($this->db);
  1953. $muser->fetch($obj->fk_user_modification);
  1954. $this->user_modification = $muser;
  1955. }
  1956. if ($obj->status == Holiday::STATUS_APPROVED || $obj->status == Holiday::STATUS_CANCELED) {
  1957. if ($obj->fk_user_approve_done) {
  1958. $auser = new User($this->db);
  1959. $auser->fetch($obj->fk_user_approve_done);
  1960. $this->user_approve = $auser;
  1961. }
  1962. } else {
  1963. if ($obj->fk_user_approve_expected) {
  1964. $auser = new User($this->db);
  1965. $auser->fetch($obj->fk_user_approve_expected);
  1966. $this->user_approve = $auser;
  1967. }
  1968. }
  1969. }
  1970. $this->db->free($resql);
  1971. } else {
  1972. dol_print_error($this->db);
  1973. }
  1974. }
  1975. /**
  1976. * Initialise an instance with random values.
  1977. * Used to build previews or test instances.
  1978. * id must be 0 if object instance is a specimen.
  1979. *
  1980. * @return void
  1981. */
  1982. public function initAsSpecimen()
  1983. {
  1984. global $user, $langs;
  1985. // Initialise parameters
  1986. $this->id = 0;
  1987. $this->specimen = 1;
  1988. $this->fk_user = $user->id;
  1989. $this->description = 'SPECIMEN description';
  1990. $this->date_debut = dol_now();
  1991. $this->date_fin = dol_now() + (24 * 3600);
  1992. $this->date_valid = dol_now();
  1993. $this->fk_validator = $user->id;
  1994. $this->halfday = 0;
  1995. $this->fk_type = 1;
  1996. $this->statut = Holiday::STATUS_VALIDATED;
  1997. }
  1998. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  1999. /**
  2000. * Load this->nb for dashboard
  2001. *
  2002. * @return int <0 if KO, >0 if OK
  2003. */
  2004. public function load_state_board()
  2005. {
  2006. // phpcs:enable
  2007. global $user;
  2008. $this->nb = array();
  2009. $sql = "SELECT count(h.rowid) as nb";
  2010. $sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
  2011. $sql .= " WHERE h.statut > 1";
  2012. $sql .= " AND h.entity IN (".getEntity('holiday').")";
  2013. if (empty($user->rights->expensereport->readall)) {
  2014. $userchildids = $user->getAllChildIds(1);
  2015. $sql .= " AND (h.fk_user IN (".$this->db->sanitize(join(',', $userchildids)).")";
  2016. $sql .= " OR h.fk_validator IN (".$this->db->sanitize(join(',', $userchildids))."))";
  2017. }
  2018. $resql = $this->db->query($sql);
  2019. if ($resql) {
  2020. while ($obj = $this->db->fetch_object($resql)) {
  2021. $this->nb["holidays"] = $obj->nb;
  2022. }
  2023. $this->db->free($resql);
  2024. return 1;
  2025. } else {
  2026. dol_print_error($this->db);
  2027. $this->error = $this->db->error();
  2028. return -1;
  2029. }
  2030. }
  2031. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  2032. /**
  2033. * Load indicators for dashboard (this->nbtodo and this->nbtodolate)
  2034. *
  2035. * @param User $user Objet user
  2036. * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK
  2037. */
  2038. public function load_board($user)
  2039. {
  2040. // phpcs:enable
  2041. global $conf, $langs;
  2042. if ($user->socid) {
  2043. return -1; // protection pour eviter appel par utilisateur externe
  2044. }
  2045. $now = dol_now();
  2046. $sql = "SELECT h.rowid, h.date_debut";
  2047. $sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
  2048. $sql .= " WHERE h.statut = 2";
  2049. $sql .= " AND h.entity IN (".getEntity('holiday').")";
  2050. if (empty($user->rights->expensereport->read_all)) {
  2051. $userchildids = $user->getAllChildIds(1);
  2052. $sql .= " AND (h.fk_user IN (".$this->db->sanitize(join(',', $userchildids)).")";
  2053. $sql .= " OR h.fk_validator IN (".$this->db->sanitize(join(',', $userchildids))."))";
  2054. }
  2055. $resql = $this->db->query($sql);
  2056. if ($resql) {
  2057. $langs->load("members");
  2058. $response = new WorkboardResponse();
  2059. $response->warning_delay = $conf->holiday->approve->warning_delay / 60 / 60 / 24;
  2060. $response->label = $langs->trans("HolidaysToApprove");
  2061. $response->labelShort = $langs->trans("ToApprove");
  2062. $response->url = DOL_URL_ROOT.'/holiday/list.php?search_status=2&amp;mainmenu=hrm&amp;leftmenu=holiday';
  2063. $response->img = img_object('', "holiday");
  2064. while ($obj = $this->db->fetch_object($resql)) {
  2065. $response->nbtodo++;
  2066. if ($this->db->jdate($obj->date_debut) < ($now - $conf->holiday->approve->warning_delay)) {
  2067. $response->nbtodolate++;
  2068. }
  2069. }
  2070. return $response;
  2071. } else {
  2072. dol_print_error($this->db);
  2073. $this->error = $this->db->error();
  2074. return -1;
  2075. }
  2076. }
  2077. }