timeEntryModel.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. <?php
  2. class timeEntryModel extends Staple_Model
  3. {
  4. private $db;
  5. private $id;
  6. private $date;
  7. private $fullDate;
  8. private $inTime;
  9. private $inTimeRaw;
  10. private $roundedInTime;
  11. private $inTimeDate;
  12. private $outTime;
  13. private $outTimeRaw;
  14. private $roundedOutTime;
  15. private $outTimeDate;
  16. private $lessTime;
  17. private $codeId;
  18. private $codeName;
  19. private $timeWorked;
  20. private $batchId;
  21. private $userId;
  22. private $timestamp;
  23. private $note;
  24. /**
  25. * @return mixed
  26. */
  27. public function getId()
  28. {
  29. return $this->id;
  30. }
  31. /**
  32. * @param mixed $id
  33. */
  34. public function setId($id)
  35. {
  36. $this->id = $id;
  37. }
  38. /**
  39. * @return mixed
  40. */
  41. public function getDate()
  42. {
  43. return $this->date;
  44. }
  45. /**
  46. * @param mixed $date
  47. */
  48. public function setDate($date)
  49. {
  50. $this->date = $date;
  51. }
  52. /**
  53. * @return mixed
  54. */
  55. public function getFullDate()
  56. {
  57. return $this->fullDate;
  58. }
  59. /**
  60. * @param mixed $fullDate
  61. */
  62. public function setFullDate($fullDate)
  63. {
  64. $this->fullDate = $fullDate;
  65. }
  66. /**
  67. * @return mixed
  68. */
  69. public function getInTime()
  70. {
  71. return $this->inTime;
  72. }
  73. /**
  74. * @param mixed $inTime
  75. */
  76. public function setInTime($inTime)
  77. {
  78. $this->inTime = $inTime;
  79. }
  80. /**
  81. * @return mixed
  82. */
  83. public function getInTimeRaw()
  84. {
  85. return $this->inTimeRaw;
  86. }
  87. /**
  88. * @param mixed $inTimeRaw
  89. */
  90. public function setInTimeRaw($inTimeRaw)
  91. {
  92. $this->inTimeRaw = $inTimeRaw;
  93. }
  94. /**
  95. * @return mixed
  96. */
  97. public function getRoundedInTime()
  98. {
  99. return $this->roundedInTime;
  100. }
  101. /**
  102. * @param mixed $roundedInTime
  103. */
  104. public function setRoundedInTime($roundedInTime)
  105. {
  106. $this->roundedInTime = $roundedInTime;
  107. }
  108. /**
  109. * @return mixed
  110. */
  111. public function getInTimeDate()
  112. {
  113. return $this->inTimeDate;
  114. }
  115. /**
  116. * @param mixed $inTimeDate
  117. */
  118. public function setInTimeDate($inTimeDate)
  119. {
  120. $this->inTimeDate = $inTimeDate;
  121. }
  122. /**
  123. * @return mixed
  124. */
  125. public function getOutTime()
  126. {
  127. return $this->outTime;
  128. }
  129. /**
  130. * @param mixed $outTime
  131. */
  132. public function setOutTime($outTime)
  133. {
  134. $this->outTime = $outTime;
  135. }
  136. /**
  137. * @return mixed
  138. */
  139. public function getOutTimeRaw()
  140. {
  141. return $this->outTimeRaw;
  142. }
  143. /**
  144. * @param mixed $outTimeRaw
  145. */
  146. public function setOutTimeRaw($outTimeRaw)
  147. {
  148. $this->outTimeRaw = $outTimeRaw;
  149. }
  150. /**
  151. * @return mixed
  152. */
  153. public function getRoundedOutTime()
  154. {
  155. return $this->roundedOutTime;
  156. }
  157. /**
  158. * @param mixed $roundedOutTime
  159. */
  160. public function setRoundedOutTime($roundedOutTime)
  161. {
  162. $this->roundedOutTime = $roundedOutTime;
  163. }
  164. /**
  165. * @return mixed
  166. */
  167. public function getOutTimeDate()
  168. {
  169. return $this->outTimeDate;
  170. }
  171. /**
  172. * @param mixed $outTimeDate
  173. */
  174. public function setOutTimeDate($outTimeDate)
  175. {
  176. $this->outTimeDate = $outTimeDate;
  177. }
  178. /**
  179. * @return mixed
  180. */
  181. public function getLessTime()
  182. {
  183. return $this->lessTime;
  184. }
  185. /**
  186. * @param mixed $lessTime
  187. */
  188. public function setLessTime($lessTime)
  189. {
  190. $this->lessTime = $lessTime;
  191. }
  192. /**
  193. * @return mixed
  194. */
  195. public function getCodeId()
  196. {
  197. return $this->codeId;
  198. }
  199. /**
  200. * @param mixed $codeId
  201. */
  202. public function setCodeId($codeId)
  203. {
  204. $this->codeId = $codeId;
  205. }
  206. /**
  207. * @return mixed
  208. */
  209. public function getCodeName()
  210. {
  211. return $this->codeName;
  212. }
  213. /**
  214. * @param mixed $codeName
  215. */
  216. public function setCodeName($codeName)
  217. {
  218. $this->codeName = $codeName;
  219. }
  220. /**
  221. * @return mixed
  222. */
  223. public function getTimeWorked()
  224. {
  225. return $this->timeWorked;
  226. }
  227. /**
  228. * @param mixed $timeWorked
  229. */
  230. public function setTimeWorked($timeWorked)
  231. {
  232. $this->timeWorked = $timeWorked;
  233. }
  234. /**
  235. * @return mixed
  236. */
  237. public function getBatchId()
  238. {
  239. return $this->batchId;
  240. }
  241. /**
  242. * @param mixed $batchId
  243. */
  244. public function setBatchId($batchId)
  245. {
  246. $this->batchId = $batchId;
  247. }
  248. /**
  249. * @return mixed
  250. */
  251. public function getUserId()
  252. {
  253. return $this->userId;
  254. }
  255. /**
  256. * @param mixed $userId
  257. */
  258. public function setUserId($userId)
  259. {
  260. $this->userId = $userId;
  261. }
  262. /**
  263. * @return mixed
  264. */
  265. public function getTimestamp()
  266. {
  267. return $this->timestamp;
  268. }
  269. /**
  270. * @param mixed $timestamp
  271. */
  272. public function setTimestamp($timestamp)
  273. {
  274. $this->timestamp = $timestamp;
  275. }
  276. /**
  277. * @return mixed
  278. */
  279. public function getNote()
  280. {
  281. return $this->note;
  282. }
  283. /**
  284. * @param mixed $note
  285. */
  286. public function setNote($note)
  287. {
  288. $this->note = $note;
  289. }
  290. function __construct($id = null)
  291. {
  292. $this->db = Staple_DB::get();
  293. if($id !== null)
  294. {
  295. $sql = "SELECT * FROM timeEntries WHERE id = '".$this->db->real_escape_string($id)."'";
  296. if($this->db->query($sql)->fetch_row() > 0)
  297. {
  298. $query = $this->db->query($sql);
  299. $result = $query->fetch_assoc();
  300. //Set ID and Date
  301. $this->setId($result['id']);
  302. $this->setBatchId($result['batchId']);
  303. $this->setDate(date("m/d/Y",$result['inTime']));
  304. $this->setFullDate(date("l, F jS Y",$result['inTime']));
  305. //Set inTime
  306. $inTime = new DateTime();
  307. $inTime->setTimestamp($result['inTime']);
  308. $this->setInTime($inTime->format('g:i A'));
  309. $this->setInTimeRaw($result['inTime']);
  310. $this->setRoundedInTime($this->nearestQuarterHour($result['inTime']));
  311. $this->setInTimeDate(date("Y-m-d", $result['inTime']));
  312. //Out Time
  313. $outTime = new DateTime();
  314. $outTime->setTimestamp($result['outTime']);
  315. $this->setOutTime($outTime->format('g:i A'));
  316. $this->setOutTimeRaw($result['outTime']);
  317. $this->setRoundedOutTime($this->nearestQuarterHour($result['outTime']));
  318. $this->setOutTimeDate(date("Y-m-d", $result['outTime']));
  319. $this->setLessTime($result['lessTime']);
  320. //Calculate Time Worked
  321. switch($result['lessTime'])
  322. {
  323. case 60:
  324. $lessTime = 1;
  325. break;
  326. case 30:
  327. $lessTime = 0.5;
  328. break;
  329. case 15:
  330. $lessTime = 0.25;
  331. break;
  332. default:
  333. $lessTime = 0;
  334. }
  335. //Total Worked Time
  336. $dateTime1 = new DateTime($this->roundedInTime);
  337. $dateTime1->setDate(date('Y',strtotime($this->inTimeDate)), date('m',strtotime($this->inTimeDate)), date('d',strtotime($this->inTimeDate)));
  338. $dateTime2 = new DateTime($this->roundedOutTime);
  339. $dateTime2->setDate(date('Y',strtotime($this->outTimeDate)), date('m',strtotime($this->outTimeDate)), date('d',strtotime($this->outTimeDate)));
  340. $interval = $dateTime1->diff($dateTime2);
  341. $timeWorked = $this->timeToDecimal($interval->h.":".$interval->i)-$lessTime;
  342. if($timeWorked !== 0)
  343. {
  344. $this->setTimeWorked($timeWorked);
  345. }
  346. else
  347. {
  348. $this->setTimeWorked(0);
  349. }
  350. //Get Code Information
  351. $code = new codeModel();
  352. $this->setCodeId($result['codeId']);
  353. $code->load($result['codeId']);
  354. $this->setCodeName($code->getName());
  355. $this->setUserId($result['userId']);
  356. $this->setTimestamp($result['timestamp']);
  357. $this->setNote($result['note']);
  358. return true;
  359. }
  360. }
  361. }
  362. function remove($id)
  363. {
  364. $this->db = Staple_DB::get();
  365. if($id !== null)
  366. {
  367. $auth = Staple_Auth::get();
  368. $user = new userModel($auth->getAuthId());
  369. $userId = $user->getId();
  370. $accountLevel = $user->getAuthLevel();
  371. $entry = new timeEntryModel($id);
  372. $fullDate = $entry->getFullDate();
  373. $inTime = $entry->getInTime();
  374. $outTime = $entry->getOutTime();
  375. $effectedUserId = $entry->getUserId();
  376. $effectedUser = new userModel();
  377. $account = $effectedUser->userInfo($effectedUserId);
  378. //Check for admin account delete
  379. if($accountLevel >= 900)
  380. {
  381. $sql = "DELETE FROM timeEntries WHERE id = '".$this->db->real_escape_string($id)."' AND userId <> '".$this->db->real_escape_string($userId)."'";
  382. if($this->db->query($sql))
  383. {
  384. $audit = new auditModel();
  385. $audit->setUserId($account['id']);
  386. $audit->setAction('Admin Entry Remove');
  387. $audit->setItem($user->getUsername()." removed entry for ".$fullDate." In Time: ".$inTime." Out Time: ".$outTime."");
  388. $audit->save();
  389. return true;
  390. }
  391. }
  392. else
  393. {
  394. //Check if validated
  395. if($this->validated($id))
  396. {
  397. $sql = "DELETE FROM timeEntries WHERE id = '".$this->db->real_escape_string($id)."' AND userId = '".$this->db->real_escape_string($userId)."'";
  398. if($this->db->query($sql))
  399. {
  400. return true;
  401. }
  402. }
  403. }
  404. }
  405. }
  406. function save()
  407. {
  408. $this->db = Staple_DB::get();
  409. $auth = Staple_Auth::get();
  410. $user = new userModel($auth->getAuthId());
  411. $userId = $user->getId();
  412. $batchId = $user->getBatchId();
  413. $inTime = strtotime($this->getDate()." ".$this->getInTime());
  414. $outTime = strtotime($this->getDate()." ".$this->getOutTime());
  415. if(strtotime($this->getDate()." ".$this->getInTime()) > strtotime($this->getDate()." ".$this->getOutTime()))
  416. {
  417. $outTime = strtotime($this->getDate()." 12:00 AM")+86400;
  418. }
  419. if($this->id == NULL)
  420. {
  421. if($this->_overlap($inTime,$outTime))
  422. {
  423. //Insert new item
  424. $sql = "INSERT INTO timeEntries (userId, inTime, outTime, lessTime, codeId, batchId)
  425. VALUES (
  426. '" . $this->db->real_escape_string($userId) . "',
  427. '" . $this->db->real_escape_string($inTime) . "',
  428. '" . $this->db->real_escape_string($outTime) . "',
  429. '" . $this->db->real_escape_string($this->getLessTime()) . "',
  430. '" . $this->db->real_escape_string($this->getCodeId()) . "',
  431. '" . $this->db->real_escape_string($batchId) . "'
  432. )";
  433. $query = $this->db->query($sql);
  434. if ($query === true)
  435. {
  436. return true;
  437. }
  438. }
  439. }
  440. else
  441. {
  442. if($this->_overlap($inTime,$outTime,$this->getId()))
  443. {
  444. //Update item
  445. $sql = "UPDATE timeEntries SET
  446. inTime='" . $this->db->real_escape_string($inTime) . "',
  447. outTime='" . $this->db->real_escape_string($outTime) . "',
  448. lessTime='" . $this->db->real_escape_string($this->getLessTime()) . "',
  449. codeId='" . $this->db->real_escape_string($this->getCodeId()) . "',
  450. batchId='" . $this->db->real_escape_string($batchId) . "'
  451. WHERE id='" . $this->db->real_escape_string($this->id) . "'
  452. ";
  453. $query = $this->db->query($sql);
  454. if ($query === true)
  455. {
  456. return true;
  457. }
  458. }
  459. }
  460. }
  461. function nearestQuarterHour($time,$string = null)
  462. {
  463. //$time = strtotime($time);
  464. $round = 15*60;
  465. $rounded = round($time/$round)*$round;
  466. if($string == 1)
  467. {
  468. return $rounded;
  469. }
  470. else
  471. {
  472. return date("g:i A", $rounded);
  473. }
  474. }
  475. function timeToDecimal($time)
  476. {
  477. $timeArr = explode(':', $time);
  478. $hours = $timeArr[0]*1;
  479. $minutes = $timeArr[1]/60;
  480. $dec = $hours + $minutes;
  481. if($dec > 0)
  482. {
  483. return round($dec,2);
  484. }
  485. else
  486. {
  487. return 0;
  488. }
  489. }
  490. function _overlap($inTime,$outTime,$id = null)
  491. {
  492. //Checks to see if the times entered fit within any other time entry for that user.
  493. $this->db = Staple_DB::get();
  494. $auth = Staple_Auth::get();
  495. $user = new userModel($auth->getAuthId());
  496. $userId = $user->getId();
  497. /*
  498. $dateString = strtotime(date("Y-m-d", $inTime));
  499. $nextDateString = $dateString + 86400;
  500. */
  501. $date = new DateTime();
  502. $dateString = $inTime;
  503. $nextDateString = $date->setTimestamp($inTime)->setTime(23,59,59);
  504. $nextDateString = $nextDateString->format('U');
  505. //Find the earliest time for the given date.
  506. $sql = "
  507. SELECT inTime FROM timeEntries WHERE inTime > '".$this->db->real_escape_string($dateString)."' AND userId = '".$this->db->real_escape_string($userId)."' ORDER BY inTime ASC LIMIT 1
  508. ";
  509. $query = $this->db->query($sql);
  510. $result = $query->fetch_assoc();
  511. $firstInTime = $result['inTime'];
  512. //Find the latest time for the given date.
  513. $sql = "
  514. SELECT outTime FROM timeEntries WHERE outTime > '".$this->db->real_escape_string($dateString)."' AND outTime < '".$this->db->real_escape_string($nextDateString)."' AND userId = '".$this->db->real_escape_string($userId)."' ORDER BY outTime DESC LIMIT 1
  515. ";
  516. if($this->db->query($sql)->num_rows > 0)
  517. {
  518. $query = $this->db->query($sql);
  519. $result = $query->fetch_assoc();
  520. $lastOutTime = $result['outTime'];
  521. }
  522. else
  523. {
  524. $lastOutTime = null;
  525. }
  526. if($id == null)
  527. {
  528. $sql = "SELECT inTime, outTime FROM timeEntries WHERE userId = '".$this->db->real_escape_string($userId)."'";
  529. }
  530. else
  531. {
  532. $sql = "SELECT inTime, outTime FROM timeEntries WHERE userId = '".$this->db->real_escape_string($userId)."' AND id <> '".$this->db->real_escape_string($id)."'";
  533. }
  534. $query = $this->db->query($sql);
  535. $data = array();
  536. while($result = $query->fetch_assoc())
  537. {
  538. $data[] = $result;
  539. }
  540. $overlap = 0;
  541. foreach($data as $entry)
  542. {
  543. if($inTime == $entry['inTime'] && $outTime == $entry['outTime'])
  544. {
  545. $overlap++;
  546. }
  547. if($inTime > $entry['inTime'] && $inTime < $entry['outTime'])
  548. {
  549. $overlap++;
  550. }
  551. if($outTime > $entry['inTime'] && $outTime < $entry['outTime'])
  552. {
  553. $overlap++;
  554. }
  555. if($inTime < $firstInTime && $outTime > $lastOutTime)
  556. {
  557. //$overlap++;
  558. }
  559. }
  560. if($overlap > 0)
  561. {
  562. return false;
  563. }
  564. else
  565. {
  566. return true;
  567. }
  568. }
  569. function validated($id,$uid = null)
  570. {
  571. if($uid == null)
  572. {
  573. $auth = Staple_Auth::get();
  574. $user = new userModel($auth->getAuthId());
  575. $userId = $user->getId();
  576. $batchId = $user->getBatchId();
  577. }
  578. else
  579. {
  580. $user = new userModel();
  581. $info = $user->userInfo($uid);
  582. $userId = $info['id'];
  583. $batchId = $info['batchId'];
  584. }
  585. $sql = "SELECT id FROM timeEntries WHERE userId = '".$this->db->real_escape_string($userId)."' AND batchId = '".$this->db->real_escape_string($batchId)."' AND id = '".$this->db->real_escape_string($id)."'";
  586. if($this->db->query($sql)->num_rows > 0)
  587. {
  588. return true;
  589. }
  590. else
  591. {
  592. return false;
  593. }
  594. }
  595. function adminSave()
  596. {
  597. if(isset($this->userId))
  598. {
  599. //Check for current account.
  600. $currentUser = new userModel();
  601. if($this->userId != $currentUser->getId())
  602. {
  603. $inTime = strtotime($this->getDate()." ".$this->getInTime());
  604. $outTime = strtotime($this->getDate()." ".$this->getOutTime());
  605. $sql = "
  606. INSERT INTO timeEntries
  607. (userId,inTime,outTime,lessTime,codeId,note,batchId)
  608. VALUES (
  609. '".$this->db->real_escape_string($this->userId)."',
  610. '".$this->db->real_escape_string($inTime)."',
  611. '".$this->db->real_escape_string($outTime)."',
  612. '".$this->db->real_escape_string($this->lessTime)."',
  613. '".$this->db->real_escape_string($this->codeId)."',
  614. '".$this->db->real_escape_string($this->note)."',
  615. '".$this->db->real_escape_string("ADMIN ADD")."'
  616. )
  617. ";
  618. if($this->db->query($sql))
  619. {
  620. $user = new userModel();
  621. $audit = new auditModel();
  622. $audit->setUserId($this->userId);
  623. $audit->setAction('Admin Entry Add');
  624. $audit->setItem($user->getUsername()." added entry for ".$this->getDate().". In Time: ".$this->inTime."/Out Time: ".$this->outTime."");
  625. $audit->save();
  626. return true;
  627. }
  628. }
  629. }
  630. }
  631. }
  632. ?>