holiday.class.php 76 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488
  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-2023 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. * getTooltipContentArray
  1148. *
  1149. * @param array $params ex option, infologin
  1150. * @since v18
  1151. * @return array
  1152. */
  1153. public function getTooltipContentArray($params)
  1154. {
  1155. global $conf, $langs;
  1156. $langs->load('holiday');
  1157. $nofetch = !empty($params['nofetch']);
  1158. $datas = array();
  1159. $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Holiday").'</u>';
  1160. if (isset($this->statut)) {
  1161. $datas['picto'] .= ' '.$this->getLibStatut(5);
  1162. }
  1163. $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
  1164. // show type for this record only in ajax to not overload lists
  1165. if (!$nofetch && !empty($this->fk_type)) {
  1166. $typeleaves = $this->getTypes(1, -1);
  1167. $labeltoshow = (($typeleaves[$this->fk_type]['code'] && $langs->trans($typeleaves[$this->fk_type]['code']) != $typeleaves[$this->fk_type]['code']) ? $langs->trans($typeleaves[$this->fk_type]['code']) : $typeleaves[$this->fk_type]['label']);
  1168. $datas['type'] = '<br><b>'.$langs->trans("Type") . ':</b> ' . (empty($labeltoshow) ? $langs->trans("TypeWasDisabledOrRemoved", $this->fk_type) : $labeltoshow);
  1169. }
  1170. if (isset($this->halfday) && !empty($this->date_debut) && !empty($this->date_fin)) {
  1171. $listhalfday = array(
  1172. 'morning' => $langs->trans("Morning"),
  1173. "afternoon" => $langs->trans("Afternoon")
  1174. );
  1175. $starthalfday = ($this->halfday == -1 || $this->halfday == 2) ? 'afternoon' : 'morning';
  1176. $endhalfday = ($this->halfday == 1 || $this->halfday == 2) ? 'morning' : 'afternoon';
  1177. $datas['date_start'] = '<br><b>'.$langs->trans('DateDebCP') . '</b>: '. dol_print_date($this->date_debut, 'day') . '&nbsp;&nbsp;<span class="opacitymedium">'.$langs->trans($listhalfday[$starthalfday]).'</span>';
  1178. $datas['date_end'] = '<br><b>'.$langs->trans('DateFinCP') . '</b>: '. dol_print_date($this->date_fin, 'day') . '&nbsp;&nbsp;<span class="opacitymedium">'.$langs->trans($listhalfday[$endhalfday]).'</span>';
  1179. }
  1180. return $datas;
  1181. }
  1182. /**
  1183. * Return clicable name (with picto eventually)
  1184. *
  1185. * @param int $withpicto 0=_No picto, 1=Includes the picto in the linkn, 2=Picto only
  1186. * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
  1187. * @param int $notooltip 1=Disable tooltip
  1188. * @param string $morecss Add more css on link
  1189. * @return string String with URL
  1190. */
  1191. public function getNomUrl($withpicto = 0, $save_lastsearch_value = -1, $notooltip = 0, $morecss = '')
  1192. {
  1193. global $conf, $langs, $hookmanager;
  1194. if (!empty($conf->dol_no_mouse_hover)) {
  1195. $notooltip = 1; // Force disable tooltips
  1196. }
  1197. $result = '';
  1198. $params = [
  1199. 'id' => $this->id,
  1200. 'objecttype' => $this->element,
  1201. 'nofetch' => 1,
  1202. ];
  1203. $classfortooltip = 'classfortooltip';
  1204. $dataparams = '';
  1205. if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
  1206. $classfortooltip = 'classforajaxtooltip';
  1207. $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
  1208. $label = '';
  1209. } else {
  1210. $label = implode($this->getTooltipContentArray($params));
  1211. }
  1212. $url = DOL_URL_ROOT.'/holiday/card.php?id='.$this->id;
  1213. //if ($option != 'nolink')
  1214. //{
  1215. // Add param to save lastsearch_values or not
  1216. $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
  1217. if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
  1218. $add_save_lastsearch_values = 1;
  1219. }
  1220. if ($add_save_lastsearch_values) {
  1221. $url .= '&save_lastsearch_values=1';
  1222. }
  1223. //}
  1224. $linkclose = '';
  1225. if (empty($notooltip)) {
  1226. if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
  1227. $label = $langs->trans("ShowMyObject");
  1228. $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
  1229. }
  1230. $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
  1231. $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
  1232. } else {
  1233. $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
  1234. }
  1235. $linkstart = '<a href="'.$url.'"';
  1236. $linkstart .= $linkclose.'>';
  1237. $linkend = '</a>';
  1238. $result .= $linkstart;
  1239. if ($withpicto) {
  1240. $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
  1241. }
  1242. if ($withpicto != 2) {
  1243. $result .= $this->ref;
  1244. }
  1245. $result .= $linkend;
  1246. global $action;
  1247. $hookmanager->initHooks(array($this->element . 'dao'));
  1248. $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
  1249. $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
  1250. if ($reshook > 0) {
  1251. $result = $hookmanager->resPrint;
  1252. } else {
  1253. $result .= $hookmanager->resPrint;
  1254. }
  1255. return $result;
  1256. }
  1257. /**
  1258. * Returns the label status
  1259. *
  1260. * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto
  1261. * @return string Label
  1262. */
  1263. public function getLibStatut($mode = 0)
  1264. {
  1265. return $this->LibStatut($this->statut, $mode, $this->date_debut);
  1266. }
  1267. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  1268. /**
  1269. * Returns the label of a status
  1270. *
  1271. * @param int $status Id status
  1272. * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto
  1273. * @param integer $startdate Date holiday should start
  1274. * @return string Label
  1275. */
  1276. public function LibStatut($status, $mode = 0, $startdate = '')
  1277. {
  1278. // phpcs:enable
  1279. global $langs;
  1280. if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
  1281. global $langs;
  1282. //$langs->load("mymodule");
  1283. $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP');
  1284. $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP');
  1285. $this->labelStatus[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP');
  1286. $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP');
  1287. $this->labelStatus[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP');
  1288. $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP');
  1289. $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP');
  1290. $this->labelStatusShort[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP');
  1291. $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP');
  1292. $this->labelStatusShort[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP');
  1293. }
  1294. $params = array();
  1295. $statusType = 'status6';
  1296. if (!empty($startdate) && $startdate >= dol_now()) { // If not yet passed, we use a green "in live" color
  1297. $statusType = 'status4';
  1298. $params = array('tooltip'=>$this->labelStatus[$status].' - '.$langs->trans("Forthcoming"));
  1299. }
  1300. if ($status == self::STATUS_DRAFT) {
  1301. $statusType = 'status0';
  1302. }
  1303. if ($status == self::STATUS_VALIDATED) {
  1304. $statusType = 'status1';
  1305. }
  1306. if ($status == self::STATUS_CANCELED) {
  1307. $statusType = 'status5';
  1308. }
  1309. if ($status == self::STATUS_REFUSED) {
  1310. $statusType = 'status5';
  1311. }
  1312. return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode, '', $params);
  1313. }
  1314. /**
  1315. * Affiche un select HTML des statuts de congés payés
  1316. *
  1317. * @param int $selected Id of preselected status
  1318. * @param string $htmlname Name of HTML select field
  1319. * @param string $morecss More CSS on select component
  1320. * @return string Show select of status
  1321. */
  1322. public function selectStatutCP($selected = '', $htmlname = 'select_statut', $morecss = 'minwidth125')
  1323. {
  1324. global $langs;
  1325. // Liste des statuts
  1326. $name = array('DraftCP', 'ToReviewCP', 'ApprovedCP', 'CancelCP', 'RefuseCP');
  1327. $nb = count($name) + 1;
  1328. // Select HTML
  1329. $out = '<select name="'.$htmlname.'" id="'.$htmlname.'" class="flat'.($morecss ? ' '.$morecss : '').'">'."\n";
  1330. $out .= '<option value="-1">&nbsp;</option>'."\n";
  1331. // Boucle des statuts
  1332. for ($i = 1; $i < $nb; $i++) {
  1333. if ($i == $selected) {
  1334. $out .= '<option value="'.$i.'" selected>'.$langs->trans($name[$i - 1]).'</option>'."\n";
  1335. } else {
  1336. $out .= '<option value="'.$i.'">'.$langs->trans($name[$i - 1]).'</option>'."\n";
  1337. }
  1338. }
  1339. $out .= '</select>'."\n";
  1340. $showempty= 0;
  1341. $out .= ajax_combobox($htmlname, array(), 0, 0, 'resolve', ($showempty < 0 ? (string) $showempty : '-1'), $morecss);
  1342. return $out;
  1343. }
  1344. /**
  1345. * Met à jour une option du module Holiday Payés
  1346. *
  1347. * @param string $name name du paramètre de configuration
  1348. * @param string $value vrai si mise à jour OK sinon faux
  1349. * @return boolean ok or ko
  1350. */
  1351. public function updateConfCP($name, $value)
  1352. {
  1353. $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
  1354. $sql .= " value = '".$this->db->escape($value)."'";
  1355. $sql .= " WHERE name = '".$this->db->escape($name)."'";
  1356. dol_syslog(get_class($this).'::updateConfCP name='.$name, LOG_DEBUG);
  1357. $result = $this->db->query($sql);
  1358. if ($result) {
  1359. return true;
  1360. }
  1361. return false;
  1362. }
  1363. /**
  1364. * Return value of a conf parameter for leave module
  1365. * TODO Move this into llx_const table
  1366. *
  1367. * @param string $name Name of parameter
  1368. * @param string $createifnotfound 'stringvalue'=Create entry with string value if not found. For example 'YYYYMMDDHHMMSS'.
  1369. * @return string Value of parameter. Example: 'YYYYMMDDHHMMSS' or < 0 if error
  1370. */
  1371. public function getConfCP($name, $createifnotfound = '')
  1372. {
  1373. $sql = "SELECT value";
  1374. $sql .= " FROM ".MAIN_DB_PREFIX."holiday_config";
  1375. $sql .= " WHERE name = '".$this->db->escape($name)."'";
  1376. dol_syslog(get_class($this).'::getConfCP name='.$name.' createifnotfound='.$createifnotfound, LOG_DEBUG);
  1377. $result = $this->db->query($sql);
  1378. if ($result) {
  1379. $obj = $this->db->fetch_object($result);
  1380. // Return value
  1381. if (empty($obj)) {
  1382. if ($createifnotfound) {
  1383. $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_config(name, value)";
  1384. $sql .= " VALUES('".$this->db->escape($name)."', '".$this->db->escape($createifnotfound)."')";
  1385. $result = $this->db->query($sql);
  1386. if ($result) {
  1387. return $createifnotfound;
  1388. } else {
  1389. $this->error = $this->db->lasterror();
  1390. return -2;
  1391. }
  1392. } else {
  1393. return '';
  1394. }
  1395. } else {
  1396. return $obj->value;
  1397. }
  1398. } else {
  1399. // Erreur SQL
  1400. $this->error = $this->db->lasterror();
  1401. return -1;
  1402. }
  1403. }
  1404. /**
  1405. * Met à jour le timestamp de la dernière mise à jour du solde des CP
  1406. *
  1407. * @param int $userID Id of user
  1408. * @param float $nbHoliday Nb of days
  1409. * @param int $fk_type Type of vacation
  1410. * @return int 0=Nothing done, 1=OK, -1=KO
  1411. */
  1412. public function updateSoldeCP($userID = '', $nbHoliday = '', $fk_type = '')
  1413. {
  1414. global $user, $langs;
  1415. $error = 0;
  1416. if (empty($userID) && empty($nbHoliday) && empty($fk_type)) {
  1417. $langs->load("holiday");
  1418. // Si mise à jour pour tout le monde en début de mois
  1419. $now = dol_now();
  1420. $month = date('m', $now);
  1421. $newdateforlastupdate = dol_print_date($now, '%Y%m%d%H%M%S');
  1422. // Get month of last update
  1423. $lastUpdate = $this->getConfCP('lastUpdate', $newdateforlastupdate);
  1424. $monthLastUpdate = $lastUpdate[4].$lastUpdate[5];
  1425. //print 'month: '.$month.' lastUpdate:'.$lastUpdate.' monthLastUpdate:'.$monthLastUpdate;exit;
  1426. // 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.
  1427. if ($month != $monthLastUpdate) {
  1428. $this->db->begin();
  1429. $users = $this->fetchUsers(false, false, ' AND u.statut > 0');
  1430. $nbUser = count($users);
  1431. $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
  1432. $sql .= " value = '".$this->db->escape($newdateforlastupdate)."'";
  1433. $sql .= " WHERE name = 'lastUpdate'";
  1434. $result = $this->db->query($sql);
  1435. $typeleaves = $this->getTypes(1, 1);
  1436. // Update each user counter
  1437. foreach ($users as $userCounter) {
  1438. $nbDaysToAdd = (isset($typeleaves[$userCounter['type']]['newbymonth']) ? $typeleaves[$userCounter['type']]['newbymonth'] : 0);
  1439. if (empty($nbDaysToAdd)) {
  1440. continue;
  1441. }
  1442. dol_syslog("We update leave type id ".$userCounter['type']." for user id ".$userCounter['rowid'], LOG_DEBUG);
  1443. $nowHoliday = $userCounter['nb_holiday'];
  1444. $newSolde = $nowHoliday + $nbDaysToAdd;
  1445. // We add a log for each user
  1446. $this->addLogCP($user->id, $userCounter['rowid'], $langs->trans('HolidaysMonthlyUpdate'), $newSolde, $userCounter['type']);
  1447. $result = $this->updateSoldeCP($userCounter['rowid'], $newSolde, $userCounter['type']);
  1448. if ($result < 0) {
  1449. $error++;
  1450. break;
  1451. }
  1452. }
  1453. if (!$error) {
  1454. $this->db->commit();
  1455. return 1;
  1456. } else {
  1457. $this->db->rollback();
  1458. return -1;
  1459. }
  1460. }
  1461. return 0;
  1462. } else {
  1463. // Mise à jour pour un utilisateur
  1464. $nbHoliday = price2num($nbHoliday, 5);
  1465. $sql = "SELECT nb_holiday FROM ".MAIN_DB_PREFIX."holiday_users";
  1466. $sql .= " WHERE fk_user = ".(int) $userID." AND fk_type = ".(int) $fk_type;
  1467. $resql = $this->db->query($sql);
  1468. if ($resql) {
  1469. $num = $this->db->num_rows($resql);
  1470. if ($num > 0) {
  1471. // Update for user
  1472. $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_users SET";
  1473. $sql .= " nb_holiday = ".((float) $nbHoliday);
  1474. $sql .= " WHERE fk_user = ".(int) $userID." AND fk_type = ".(int) $fk_type;
  1475. $result = $this->db->query($sql);
  1476. if (!$result) {
  1477. $error++;
  1478. $this->errors[] = $this->db->lasterror();
  1479. }
  1480. } else {
  1481. // Insert for user
  1482. $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users(nb_holiday, fk_user, fk_type) VALUES (";
  1483. $sql .= ((float) $nbHoliday);
  1484. $sql .= ", ".(int) $userID.", ".(int) $fk_type.")";
  1485. $result = $this->db->query($sql);
  1486. if (!$result) {
  1487. $error++;
  1488. $this->errors[] = $this->db->lasterror();
  1489. }
  1490. }
  1491. } else {
  1492. $this->errors[] = $this->db->lasterror();
  1493. $error++;
  1494. }
  1495. if (!$error) {
  1496. return 1;
  1497. } else {
  1498. return -1;
  1499. }
  1500. }
  1501. }
  1502. /**
  1503. * Create entries for each user at setup step
  1504. *
  1505. * @param boolean $single Single
  1506. * @param int $userid Id user
  1507. * @return void
  1508. */
  1509. public function createCPusers($single = false, $userid = '')
  1510. {
  1511. // do we have to add balance for all users ?
  1512. if (!$single) {
  1513. dol_syslog(get_class($this).'::createCPusers');
  1514. $arrayofusers = $this->fetchUsers(false, true);
  1515. foreach ($arrayofusers as $users) {
  1516. $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users";
  1517. $sql .= " (fk_user, nb_holiday)";
  1518. $sql .= " VALUES (".((int) $users['rowid'])."', '0')";
  1519. $resql = $this->db->query($sql);
  1520. if (!$resql) {
  1521. dol_print_error($this->db);
  1522. }
  1523. }
  1524. } else {
  1525. $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users";
  1526. $sql .= " (fk_user, nb_holiday)";
  1527. $sql .= " VALUES (".((int) $userid)."', '0')";
  1528. $resql = $this->db->query($sql);
  1529. if (!$resql) {
  1530. dol_print_error($this->db);
  1531. }
  1532. }
  1533. }
  1534. /**
  1535. * Return balance of holiday for one user
  1536. *
  1537. * @param int $user_id ID de l'utilisateur
  1538. * @param int $fk_type Filter on type
  1539. * @return float Retourne le solde de congés payés de l'utilisateur
  1540. */
  1541. public function getCPforUser($user_id, $fk_type = 0)
  1542. {
  1543. $sql = "SELECT nb_holiday";
  1544. $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users";
  1545. $sql .= " WHERE fk_user = ".(int) $user_id;
  1546. if ($fk_type > 0) {
  1547. $sql .= " AND fk_type = ".(int) $fk_type;
  1548. }
  1549. dol_syslog(get_class($this).'::getCPforUser user_id='.$user_id.' type_id='.$fk_type, LOG_DEBUG);
  1550. $result = $this->db->query($sql);
  1551. if ($result) {
  1552. $obj = $this->db->fetch_object($result);
  1553. //return number_format($obj->nb_holiday,2);
  1554. if ($obj) {
  1555. return $obj->nb_holiday;
  1556. } else {
  1557. return null;
  1558. }
  1559. } else {
  1560. return null;
  1561. }
  1562. }
  1563. /**
  1564. * Get list of Users or list of vacation balance.
  1565. *
  1566. * @param boolean $stringlist If true return a string list of id. If false, return an array with detail.
  1567. * @param boolean $type If true, read Dolibarr user list, if false, return vacation balance list.
  1568. * @param string $filters Filters. Warning: This must not contains data from user input.
  1569. * @return array|string|int Return an array
  1570. */
  1571. public function fetchUsers($stringlist = true, $type = true, $filters = '')
  1572. {
  1573. global $conf;
  1574. dol_syslog(get_class($this)."::fetchUsers", LOG_DEBUG);
  1575. if ($stringlist) {
  1576. if ($type) {
  1577. // If user of Dolibarr
  1578. $sql = "SELECT";
  1579. if (isModEnabled('multicompany') && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
  1580. $sql .= " DISTINCT";
  1581. }
  1582. $sql .= " u.rowid";
  1583. $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
  1584. if (isModEnabled('multicompany') && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
  1585. $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
  1586. $sql .= " WHERE ((ug.fk_user = u.rowid";
  1587. $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
  1588. $sql .= " OR u.entity = 0)"; // Show always superadmin
  1589. } else {
  1590. $sql .= " WHERE u.entity IN (".getEntity('user').")";
  1591. }
  1592. $sql .= " AND u.statut > 0";
  1593. $sql .= " AND u.employee = 1"; // We only want employee users for holidays
  1594. if ($filters) {
  1595. $sql .= $filters;
  1596. }
  1597. $resql = $this->db->query($sql);
  1598. // Si pas d'erreur SQL
  1599. if ($resql) {
  1600. $i = 0;
  1601. $num = $this->db->num_rows($resql);
  1602. $stringlist = '';
  1603. // Boucles du listage des utilisateurs
  1604. while ($i < $num) {
  1605. $obj = $this->db->fetch_object($resql);
  1606. if ($i == 0) {
  1607. $stringlist .= $obj->rowid;
  1608. } else {
  1609. $stringlist .= ', '.$obj->rowid;
  1610. }
  1611. $i++;
  1612. }
  1613. // Retoune le tableau des utilisateurs
  1614. return $stringlist;
  1615. } else {
  1616. // Erreur SQL
  1617. $this->error = "Error ".$this->db->lasterror();
  1618. return -1;
  1619. }
  1620. } else {
  1621. // We want only list of vacation balance for user ids
  1622. $sql = "SELECT DISTINCT cpu.fk_user";
  1623. $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u";
  1624. $sql .= " WHERE cpu.fk_user = u.rowid";
  1625. if ($filters) {
  1626. $sql .= $filters;
  1627. }
  1628. $resql = $this->db->query($sql);
  1629. // Si pas d'erreur SQL
  1630. if ($resql) {
  1631. $i = 0;
  1632. $num = $this->db->num_rows($resql);
  1633. $stringlist = '';
  1634. // Boucles du listage des utilisateurs
  1635. while ($i < $num) {
  1636. $obj = $this->db->fetch_object($resql);
  1637. if ($i == 0) {
  1638. $stringlist .= $obj->fk_user;
  1639. } else {
  1640. $stringlist .= ', '.$obj->fk_user;
  1641. }
  1642. $i++;
  1643. }
  1644. // Retoune le tableau des utilisateurs
  1645. return $stringlist;
  1646. } else {
  1647. // Erreur SQL
  1648. $this->error = "Error ".$this->db->lasterror();
  1649. return -1;
  1650. }
  1651. }
  1652. } else {
  1653. // Si faux donc return array
  1654. // List for Dolibarr users
  1655. if ($type) {
  1656. // If we need users of Dolibarr
  1657. $sql = "SELECT";
  1658. if (isModEnabled('multicompany') && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
  1659. $sql .= " DISTINCT";
  1660. }
  1661. $sql .= " u.rowid, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut, u.fk_user";
  1662. $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
  1663. if (isModEnabled('multicompany') && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
  1664. $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
  1665. $sql .= " WHERE ((ug.fk_user = u.rowid";
  1666. $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
  1667. $sql .= " OR u.entity = 0)"; // Show always superadmin
  1668. } else {
  1669. $sql .= " WHERE u.entity IN (".getEntity('user').")";
  1670. }
  1671. $sql .= " AND u.statut > 0";
  1672. $sql .= " AND u.employee = 1"; // We only want employee users for holidays
  1673. if ($filters) {
  1674. $sql .= $filters;
  1675. }
  1676. $resql = $this->db->query($sql);
  1677. // Si pas d'erreur SQL
  1678. if ($resql) {
  1679. $i = 0;
  1680. $tab_result = $this->holiday;
  1681. $num = $this->db->num_rows($resql);
  1682. // Boucles du listage des utilisateurs
  1683. while ($i < $num) {
  1684. $obj = $this->db->fetch_object($resql);
  1685. $tab_result[$i]['rowid'] = $obj->rowid; // rowid of user
  1686. $tab_result[$i]['id'] = $obj->rowid; // id of user
  1687. $tab_result[$i]['name'] = $obj->lastname; // deprecated
  1688. $tab_result[$i]['lastname'] = $obj->lastname;
  1689. $tab_result[$i]['firstname'] = $obj->firstname;
  1690. $tab_result[$i]['gender'] = $obj->gender;
  1691. $tab_result[$i]['status'] = $obj->statut;
  1692. $tab_result[$i]['employee'] = $obj->employee;
  1693. $tab_result[$i]['photo'] = $obj->photo;
  1694. $tab_result[$i]['fk_user'] = $obj->fk_user; // rowid of manager
  1695. //$tab_result[$i]['type'] = $obj->type;
  1696. //$tab_result[$i]['nb_holiday'] = $obj->nb_holiday;
  1697. $i++;
  1698. }
  1699. // Retoune le tableau des utilisateurs
  1700. return $tab_result;
  1701. } else {
  1702. // Erreur SQL
  1703. $this->errors[] = "Error ".$this->db->lasterror();
  1704. return -1;
  1705. }
  1706. } else {
  1707. // List of vacation balance users
  1708. $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";
  1709. $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u";
  1710. $sql .= " WHERE cpu.fk_user = u.rowid";
  1711. if ($filters) {
  1712. $sql .= $filters;
  1713. }
  1714. $resql = $this->db->query($sql);
  1715. // Si pas d'erreur SQL
  1716. if ($resql) {
  1717. $i = 0;
  1718. $tab_result = $this->holiday;
  1719. $num = $this->db->num_rows($resql);
  1720. // Boucles du listage des utilisateurs
  1721. while ($i < $num) {
  1722. $obj = $this->db->fetch_object($resql);
  1723. $tab_result[$i]['rowid'] = $obj->rowid; // rowid of user
  1724. $tab_result[$i]['id'] = $obj->rowid; // id of user
  1725. $tab_result[$i]['name'] = $obj->lastname; // deprecated
  1726. $tab_result[$i]['lastname'] = $obj->lastname;
  1727. $tab_result[$i]['firstname'] = $obj->firstname;
  1728. $tab_result[$i]['gender'] = $obj->gender;
  1729. $tab_result[$i]['status'] = $obj->statut;
  1730. $tab_result[$i]['employee'] = $obj->employee;
  1731. $tab_result[$i]['photo'] = $obj->photo;
  1732. $tab_result[$i]['fk_user'] = $obj->fk_user; // rowid of manager
  1733. $tab_result[$i]['type'] = $obj->fk_type;
  1734. $tab_result[$i]['nb_holiday'] = $obj->nb_holiday;
  1735. $i++;
  1736. }
  1737. // Retoune le tableau des utilisateurs
  1738. return $tab_result;
  1739. } else {
  1740. // Erreur SQL
  1741. $this->error = "Error ".$this->db->lasterror();
  1742. return -1;
  1743. }
  1744. }
  1745. }
  1746. }
  1747. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  1748. /**
  1749. * Return list of people with permission to validate leave requests.
  1750. * Search for permission "approve leave requests"
  1751. *
  1752. * @return array|int Array of user ids or -1 if error
  1753. */
  1754. public function fetch_users_approver_holiday()
  1755. {
  1756. // phpcs:enable
  1757. $users_validator = array();
  1758. $sql = "SELECT DISTINCT ur.fk_user";
  1759. $sql .= " FROM ".MAIN_DB_PREFIX."user_rights as ur, ".MAIN_DB_PREFIX."rights_def as rd";
  1760. $sql .= " WHERE ur.fk_id = rd.id and rd.module = 'holiday' AND rd.perms = 'approve'"; // Permission 'Approve';
  1761. $sql .= "UNION";
  1762. $sql .= " SELECT DISTINCT ugu.fk_user";
  1763. $sql .= " FROM ".MAIN_DB_PREFIX."usergroup_user as ugu, ".MAIN_DB_PREFIX."usergroup_rights as ur, ".MAIN_DB_PREFIX."rights_def as rd";
  1764. $sql .= " WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'holiday' AND rd.perms = 'approve'"; // Permission 'Approve';
  1765. //print $sql;
  1766. dol_syslog(get_class($this)."::fetch_users_approver_holiday sql=".$sql);
  1767. $result = $this->db->query($sql);
  1768. if ($result) {
  1769. $num_rows = $this->db->num_rows($result); $i = 0;
  1770. while ($i < $num_rows) {
  1771. $objp = $this->db->fetch_object($result);
  1772. array_push($users_validator, $objp->fk_user);
  1773. $i++;
  1774. }
  1775. return $users_validator;
  1776. } else {
  1777. $this->error = $this->db->lasterror();
  1778. dol_syslog(get_class($this)."::fetch_users_approver_holiday Error ".$this->error, LOG_ERR);
  1779. return -1;
  1780. }
  1781. }
  1782. /**
  1783. * Compte le nombre d'utilisateur actifs dans Dolibarr
  1784. *
  1785. * @return int retourne le nombre d'utilisateur
  1786. */
  1787. public function countActiveUsers()
  1788. {
  1789. $sql = "SELECT count(u.rowid) as compteur";
  1790. $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
  1791. $sql .= " WHERE u.statut > 0";
  1792. $result = $this->db->query($sql);
  1793. $objet = $this->db->fetch_object($result);
  1794. return $objet->compteur;
  1795. }
  1796. /**
  1797. * Compte le nombre d'utilisateur actifs dans Dolibarr sans CP
  1798. *
  1799. * @return int retourne le nombre d'utilisateur
  1800. */
  1801. public function countActiveUsersWithoutCP()
  1802. {
  1803. $sql = "SELECT count(u.rowid) as compteur";
  1804. $sql .= " FROM ".MAIN_DB_PREFIX."user as u LEFT OUTER JOIN ".MAIN_DB_PREFIX."holiday_users hu ON (hu.fk_user=u.rowid)";
  1805. $sql .= " WHERE u.statut > 0 AND hu.fk_user IS NULL";
  1806. $result = $this->db->query($sql);
  1807. $objet = $this->db->fetch_object($result);
  1808. return $objet->compteur;
  1809. }
  1810. /**
  1811. * Compare le nombre d'utilisateur actif de Dolibarr à celui des utilisateurs des congés payés
  1812. *
  1813. * @param int $userDolibarrWithoutCP Number of active users in Dolibarr without holidays
  1814. * @param int $userCP Number of active users into table of holidays
  1815. * @return int <0 if KO, >0 if OK
  1816. */
  1817. public function verifNbUsers($userDolibarrWithoutCP, $userCP)
  1818. {
  1819. if (empty($userCP)) {
  1820. $userCP = 0;
  1821. }
  1822. dol_syslog(get_class($this).'::verifNbUsers userDolibarr='.$userDolibarrWithoutCP.' userCP='.$userCP);
  1823. return 1;
  1824. }
  1825. /**
  1826. * addLogCP
  1827. *
  1828. * @param int $fk_user_action Id user creation
  1829. * @param int $fk_user_update Id user update
  1830. * @param string $label Label (Example: 'Leave', 'Manual update', 'Leave request cancelation'...)
  1831. * @param int $new_solde New value
  1832. * @param int $fk_type Type of vacation
  1833. * @return int Id of record added, 0 if nothing done, < 0 if KO
  1834. */
  1835. public function addLogCP($fk_user_action, $fk_user_update, $label, $new_solde, $fk_type)
  1836. {
  1837. global $conf, $langs;
  1838. $error = 0;
  1839. $prev_solde = price2num($this->getCPforUser($fk_user_update, $fk_type), 5);
  1840. $new_solde = price2num($new_solde, 5);
  1841. //print "$prev_solde == $new_solde";
  1842. if ($prev_solde == $new_solde) {
  1843. return 0;
  1844. }
  1845. $this->db->begin();
  1846. // Insert request
  1847. $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_logs (";
  1848. $sql .= "date_action,";
  1849. $sql .= "fk_user_action,";
  1850. $sql .= "fk_user_update,";
  1851. $sql .= "type_action,";
  1852. $sql .= "prev_solde,";
  1853. $sql .= "new_solde,";
  1854. $sql .= "fk_type";
  1855. $sql .= ") VALUES (";
  1856. $sql .= " '".$this->db->idate(dol_now())."',";
  1857. $sql .= " ".((int) $fk_user_action).",";
  1858. $sql .= " ".((int) $fk_user_update).",";
  1859. $sql .= " '".$this->db->escape($label)."',";
  1860. $sql .= " ".((float) $prev_solde).",";
  1861. $sql .= " ".((float) $new_solde).",";
  1862. $sql .= " ".((int) $fk_type);
  1863. $sql .= ")";
  1864. $resql = $this->db->query($sql);
  1865. if (!$resql) {
  1866. $error++; $this->errors[] = "Error ".$this->db->lasterror();
  1867. }
  1868. if (!$error) {
  1869. $this->optRowid = $this->db->last_insert_id(MAIN_DB_PREFIX."holiday_logs");
  1870. }
  1871. // Commit or rollback
  1872. if ($error) {
  1873. foreach ($this->errors as $errmsg) {
  1874. dol_syslog(get_class($this)."::addLogCP ".$errmsg, LOG_ERR);
  1875. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  1876. }
  1877. $this->db->rollback();
  1878. return -1 * $error;
  1879. } else {
  1880. $this->db->commit();
  1881. return $this->optRowid;
  1882. }
  1883. }
  1884. /**
  1885. * Liste le log des congés payés
  1886. *
  1887. * @param string $order Filtrage par ordre
  1888. * @param string $filter Filtre de séléction
  1889. * @return int -1 si erreur, 1 si OK et 2 si pas de résultat
  1890. */
  1891. public function fetchLog($order, $filter)
  1892. {
  1893. $sql = "SELECT";
  1894. $sql .= " cpl.rowid,";
  1895. $sql .= " cpl.date_action,";
  1896. $sql .= " cpl.fk_user_action,";
  1897. $sql .= " cpl.fk_user_update,";
  1898. $sql .= " cpl.type_action,";
  1899. $sql .= " cpl.prev_solde,";
  1900. $sql .= " cpl.new_solde,";
  1901. $sql .= " cpl.fk_type";
  1902. $sql .= " FROM ".MAIN_DB_PREFIX."holiday_logs as cpl";
  1903. $sql .= " WHERE cpl.rowid > 0"; // To avoid error with other search and criteria
  1904. // Filtrage de séléction
  1905. if (!empty($filter)) {
  1906. $sql .= " ".$filter;
  1907. }
  1908. // Ordre d'affichage
  1909. if (!empty($order)) {
  1910. $sql .= " ".$order;
  1911. }
  1912. dol_syslog(get_class($this)."::fetchLog", LOG_DEBUG);
  1913. $resql = $this->db->query($sql);
  1914. // Si pas d'erreur SQL
  1915. if ($resql) {
  1916. $i = 0;
  1917. $tab_result = $this->logs;
  1918. $num = $this->db->num_rows($resql);
  1919. // Si pas d'enregistrement
  1920. if (!$num) {
  1921. return 2;
  1922. }
  1923. // On liste les résultats et on les ajoutent dans le tableau
  1924. while ($i < $num) {
  1925. $obj = $this->db->fetch_object($resql);
  1926. $tab_result[$i]['rowid'] = $obj->rowid;
  1927. $tab_result[$i]['id'] = $obj->rowid;
  1928. $tab_result[$i]['date_action'] = $obj->date_action;
  1929. $tab_result[$i]['fk_user_action'] = $obj->fk_user_action;
  1930. $tab_result[$i]['fk_user_update'] = $obj->fk_user_update;
  1931. $tab_result[$i]['type_action'] = $obj->type_action;
  1932. $tab_result[$i]['prev_solde'] = $obj->prev_solde;
  1933. $tab_result[$i]['new_solde'] = $obj->new_solde;
  1934. $tab_result[$i]['fk_type'] = $obj->fk_type;
  1935. $i++;
  1936. }
  1937. // Retourne 1 et ajoute le tableau à la variable
  1938. $this->logs = $tab_result;
  1939. return 1;
  1940. } else {
  1941. // Erreur SQL
  1942. $this->error = "Error ".$this->db->lasterror();
  1943. return -1;
  1944. }
  1945. }
  1946. /**
  1947. * Return array with list of types
  1948. *
  1949. * @param int $active Status of type. -1 = Both
  1950. * @param int $affect Filter on affect (a request will change sold or not). -1 = Both
  1951. * @return array Return array with list of types
  1952. */
  1953. public function getTypes($active = -1, $affect = -1)
  1954. {
  1955. global $mysoc;
  1956. $sql = "SELECT rowid, code, label, affect, delay, newbymonth";
  1957. $sql .= " FROM ".MAIN_DB_PREFIX."c_holiday_types";
  1958. $sql .= " WHERE (fk_country IS NULL OR fk_country = ".((int) $mysoc->country_id).')';
  1959. if ($active >= 0) {
  1960. $sql .= " AND active = ".((int) $active);
  1961. }
  1962. if ($affect >= 0) {
  1963. $sql .= " AND affect = ".((int) $affect);
  1964. }
  1965. $sql .= " ORDER BY sortorder";
  1966. $result = $this->db->query($sql);
  1967. if ($result) {
  1968. $num = $this->db->num_rows($result);
  1969. if ($num) {
  1970. while ($obj = $this->db->fetch_object($result)) {
  1971. $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);
  1972. }
  1973. return $types;
  1974. }
  1975. } else {
  1976. dol_print_error($this->db);
  1977. }
  1978. return array();
  1979. }
  1980. /**
  1981. * Load information on object
  1982. *
  1983. * @param int $id Id of object
  1984. * @return void
  1985. */
  1986. public function info($id)
  1987. {
  1988. global $conf;
  1989. $sql = "SELECT f.rowid, f.statut as status,";
  1990. $sql .= " f.date_create as datec,";
  1991. $sql .= " f.tms as date_modification,";
  1992. $sql .= " f.date_valid as datev,";
  1993. $sql .= " f.date_approval as datea,";
  1994. $sql .= " f.date_refuse as dater,";
  1995. $sql .= " f.fk_user_create as fk_user_creation,";
  1996. $sql .= " f.fk_user_modif as fk_user_modification,";
  1997. $sql .= " f.fk_user_valid as fk_user_validation,";
  1998. $sql .= " f.fk_user_approve as fk_user_approval_done,";
  1999. $sql .= " f.fk_validator as fk_user_approval_expected,";
  2000. $sql .= " f.fk_user_refuse as fk_user_refuse";
  2001. $sql .= " FROM ".MAIN_DB_PREFIX."holiday as f";
  2002. $sql .= " WHERE f.rowid = ".((int) $id);
  2003. $sql .= " AND f.entity = ".$conf->entity;
  2004. $resql = $this->db->query($sql);
  2005. if ($resql) {
  2006. if ($this->db->num_rows($resql)) {
  2007. $obj = $this->db->fetch_object($resql);
  2008. $this->id = $obj->rowid;
  2009. $this->date_creation = $this->db->jdate($obj->datec);
  2010. $this->date_modification = $this->db->jdate($obj->date_modification);
  2011. $this->date_validation = $this->db->jdate($obj->datev);
  2012. $this->date_approval = $this->db->jdate($obj->datea);
  2013. if (!empty($obj->fk_user_creation)) {
  2014. $cuser = new User($this->db);
  2015. $cuser->fetch($obj->fk_user_creation);
  2016. $this->user_creation = $cuser;
  2017. }
  2018. if (!empty($obj->fk_user_valid)) {
  2019. $vuser = new User($this->db);
  2020. $vuser->fetch($obj->fk_user_valid);
  2021. $this->user_validation = $vuser;
  2022. }
  2023. if (!empty($obj->fk_user_modification)) {
  2024. $muser = new User($this->db);
  2025. $muser->fetch($obj->fk_user_modification);
  2026. $this->user_modification = $muser;
  2027. }
  2028. if ($obj->status == Holiday::STATUS_APPROVED || $obj->status == Holiday::STATUS_CANCELED) {
  2029. if ($obj->fk_user_approval_done) {
  2030. $auser = new User($this->db);
  2031. $auser->fetch($obj->fk_user_approval_done);
  2032. $this->user_approve = $auser;
  2033. }
  2034. }
  2035. }
  2036. $this->db->free($resql);
  2037. } else {
  2038. dol_print_error($this->db);
  2039. }
  2040. }
  2041. /**
  2042. * Initialise an instance with random values.
  2043. * Used to build previews or test instances.
  2044. * id must be 0 if object instance is a specimen.
  2045. *
  2046. * @return void
  2047. */
  2048. public function initAsSpecimen()
  2049. {
  2050. global $user, $langs;
  2051. // Initialise parameters
  2052. $this->id = 0;
  2053. $this->specimen = 1;
  2054. $this->fk_user = $user->id;
  2055. $this->description = 'SPECIMEN description';
  2056. $this->date_debut = dol_now();
  2057. $this->date_fin = dol_now() + (24 * 3600);
  2058. $this->date_valid = dol_now();
  2059. $this->fk_validator = $user->id;
  2060. $this->halfday = 0;
  2061. $this->fk_type = 1;
  2062. $this->statut = Holiday::STATUS_VALIDATED;
  2063. }
  2064. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  2065. /**
  2066. * Load this->nb for dashboard
  2067. *
  2068. * @return int <0 if KO, >0 if OK
  2069. */
  2070. public function load_state_board()
  2071. {
  2072. // phpcs:enable
  2073. global $user;
  2074. $this->nb = array();
  2075. $sql = "SELECT count(h.rowid) as nb";
  2076. $sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
  2077. $sql .= " WHERE h.statut > 1";
  2078. $sql .= " AND h.entity IN (".getEntity('holiday').")";
  2079. if (empty($user->rights->expensereport->readall)) {
  2080. $userchildids = $user->getAllChildIds(1);
  2081. $sql .= " AND (h.fk_user IN (".$this->db->sanitize(join(',', $userchildids)).")";
  2082. $sql .= " OR h.fk_validator IN (".$this->db->sanitize(join(',', $userchildids))."))";
  2083. }
  2084. $resql = $this->db->query($sql);
  2085. if ($resql) {
  2086. while ($obj = $this->db->fetch_object($resql)) {
  2087. $this->nb["holidays"] = $obj->nb;
  2088. }
  2089. $this->db->free($resql);
  2090. return 1;
  2091. } else {
  2092. dol_print_error($this->db);
  2093. $this->error = $this->db->error();
  2094. return -1;
  2095. }
  2096. }
  2097. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  2098. /**
  2099. * Load indicators for dashboard (this->nbtodo and this->nbtodolate)
  2100. *
  2101. * @param User $user Objet user
  2102. * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK
  2103. */
  2104. public function load_board($user)
  2105. {
  2106. // phpcs:enable
  2107. global $conf, $langs;
  2108. if ($user->socid) {
  2109. return -1; // protection pour eviter appel par utilisateur externe
  2110. }
  2111. $now = dol_now();
  2112. $sql = "SELECT h.rowid, h.date_debut";
  2113. $sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
  2114. $sql .= " WHERE h.statut = 2";
  2115. $sql .= " AND h.entity IN (".getEntity('holiday').")";
  2116. if (empty($user->rights->expensereport->read_all)) {
  2117. $userchildids = $user->getAllChildIds(1);
  2118. $sql .= " AND (h.fk_user IN (".$this->db->sanitize(join(',', $userchildids)).")";
  2119. $sql .= " OR h.fk_validator IN (".$this->db->sanitize(join(',', $userchildids))."))";
  2120. }
  2121. $resql = $this->db->query($sql);
  2122. if ($resql) {
  2123. $langs->load("members");
  2124. $response = new WorkboardResponse();
  2125. $response->warning_delay = $conf->holiday->approve->warning_delay / 60 / 60 / 24;
  2126. $response->label = $langs->trans("HolidaysToApprove");
  2127. $response->labelShort = $langs->trans("ToApprove");
  2128. $response->url = DOL_URL_ROOT.'/holiday/list.php?search_status=2&amp;mainmenu=hrm&amp;leftmenu=holiday';
  2129. $response->img = img_object('', "holiday");
  2130. while ($obj = $this->db->fetch_object($resql)) {
  2131. $response->nbtodo++;
  2132. if ($this->db->jdate($obj->date_debut) < ($now - $conf->holiday->approve->warning_delay)) {
  2133. $response->nbtodolate++;
  2134. }
  2135. }
  2136. return $response;
  2137. } else {
  2138. dol_print_error($this->db);
  2139. $this->error = $this->db->error();
  2140. return -1;
  2141. }
  2142. }
  2143. /**
  2144. * Return clicable link of object (with eventually picto)
  2145. *
  2146. * @param string $option Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link)
  2147. * @param array $arraydata Label of holiday type (if known)
  2148. * @return string HTML Code for Kanban thumb.
  2149. */
  2150. public function getKanbanView($option = '', $arraydata = null)
  2151. {
  2152. global $langs;
  2153. $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
  2154. $return = '<div class="box-flex-item box-flex-grow-zero">';
  2155. $return .= '<div class="info-box info-box-sm">';
  2156. $return .= '<span class="info-box-icon bg-infobox-action">';
  2157. $return .= img_picto('', $this->picto);
  2158. $return .= '</span>';
  2159. $return .= '<div class="info-box-content">';
  2160. $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.$arraydata['user']->getNomUrl(-1).'</span>';
  2161. $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
  2162. if (property_exists($this, 'fk_type')) {
  2163. $return .= '<br><span class="opacitymedium">'.$langs->trans("Type").'</span> : ';
  2164. $return .= '<span class="info_box-label maxwidth100">'.$arraydata['labeltype'].'</span>';
  2165. }
  2166. if (property_exists($this, 'date_debut') && property_exists($this, 'date_fin')) {
  2167. $return .= '<br><span class="info-box-label">'.dol_print_date($this->date_debut, 'day').'</span>';
  2168. $return .= ' <span class="opacitymedium">'.$langs->trans("To").'</span> ';
  2169. $return .= '<span class="info-box-label">'.dol_print_date($this->date_fin, 'day').'</span>';
  2170. }
  2171. if (method_exists($this, 'getLibStatut')) {
  2172. $return .= '<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).'</div>';
  2173. }
  2174. $return .= '</div>';
  2175. $return .= '</div>';
  2176. $return .= '</div>';
  2177. return $return;
  2178. }
  2179. }