holiday.class.php 72 KB

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