WorkHour.php 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <?php
  2. class WorkHour {
  3. private $conn;
  4. private $table_name = 'work_hours';
  5. public $id;
  6. public $task_id;
  7. public $user_id;
  8. public $date;
  9. public $start_time;
  10. public $end_time;
  11. public $hours;
  12. public $description;
  13. public $rate;
  14. public $total_amount;
  15. public $created_at;
  16. public $updated_at;
  17. public function __construct($db) {
  18. $this->conn = $db;
  19. }
  20. public function create() {
  21. // Calculate hours from start_time and end_time if provided
  22. if ($this->start_time && $this->end_time) {
  23. $start = new DateTime($this->start_time);
  24. $end = new DateTime($this->end_time);
  25. $interval = $start->diff($end);
  26. $this->hours = $interval->format('%H:%I');
  27. // Convert to decimal hours for database storage
  28. $parts = explode(':', $this->hours);
  29. $this->hours = (float)$parts[0] + ((float)$parts[1] / 60);
  30. }
  31. // Auto-fetch client hour price if rate is not provided or empty
  32. if (!$this->rate || $this->rate === '') {
  33. $this->rate = $this->getClientHourPrice();
  34. }
  35. // Calculate total amount if rate is provided and greater than 0
  36. if ($this->rate && $this->rate > 0) {
  37. $this->total_amount = $this->hours * $this->rate;
  38. } else {
  39. $this->rate = null;
  40. $this->total_amount = null;
  41. }
  42. $query = "INSERT INTO " . $this->table_name . "
  43. SET task_id=:task_id, user_id=:user_id, date=:date, hours=:hours,
  44. description=:description, rate=:rate, total_amount=:total_amount, created_at=:created_at,
  45. updated_at=:updated_at";
  46. $stmt = $this->conn->prepare($query);
  47. $this->task_id = htmlspecialchars(strip_tags($this->task_id));
  48. $this->user_id = htmlspecialchars(strip_tags($this->user_id));
  49. $this->date = htmlspecialchars(strip_tags($this->date));
  50. $this->hours = htmlspecialchars(strip_tags($this->hours));
  51. $this->description = htmlspecialchars(strip_tags($this->description));
  52. $this->rate = $this->rate ? htmlspecialchars(strip_tags($this->rate)) : null;
  53. $this->total_amount = $this->total_amount ? htmlspecialchars(strip_tags($this->total_amount)) : null;
  54. $this->created_at = date('Y-m-d H:i:s');
  55. $this->updated_at = date('Y-m-d H:i:s');
  56. $stmt->bindParam(":task_id", $this->task_id);
  57. $stmt->bindParam(":user_id", $this->user_id);
  58. $stmt->bindParam(":date", $this->date);
  59. $stmt->bindParam(":hours", $this->hours);
  60. $stmt->bindParam(":description", $this->description);
  61. $stmt->bindParam(":rate", $this->rate);
  62. $stmt->bindParam(":total_amount", $this->total_amount);
  63. $stmt->bindParam(":created_at", $this->created_at);
  64. $stmt->bindParam(":updated_at", $this->updated_at);
  65. if($stmt->execute()) {
  66. return true;
  67. }
  68. return false;
  69. }
  70. public function read() {
  71. $query = "SELECT wh.*, t.title as task_title, u.first_name, u.last_name
  72. FROM " . $this->table_name . " wh
  73. LEFT JOIN tasks t ON wh.task_id = t.id
  74. LEFT JOIN users u ON wh.user_id = u.id
  75. ORDER BY wh.date DESC, wh.created_at DESC";
  76. $stmt = $this->conn->prepare($query);
  77. $stmt->execute();
  78. return $stmt;
  79. }
  80. public function readByTask($task_id) {
  81. $query = "SELECT wh.*, u.first_name, u.last_name, c.hour_price as client_hour_price,
  82. c.company_name as client_name, c.first_name as client_first_name, c.last_name as client_last_name
  83. FROM " . $this->table_name . " wh
  84. LEFT JOIN users u ON wh.user_id = u.id
  85. LEFT JOIN tasks t ON wh.task_id = t.id
  86. LEFT JOIN projects p ON t.project_id = p.id
  87. LEFT JOIN clients c ON p.customer_id = c.id
  88. WHERE wh.task_id = ?
  89. ORDER BY wh.date DESC, wh.created_at DESC";
  90. $stmt = $this->conn->prepare($query);
  91. $stmt->bindParam(1, $task_id);
  92. $stmt->execute();
  93. return $stmt;
  94. }
  95. public function readOne() {
  96. $query = "SELECT wh.*, t.title as task_title, u.first_name, u.last_name
  97. FROM " . $this->table_name . " wh
  98. LEFT JOIN tasks t ON wh.task_id = t.id
  99. LEFT JOIN users u ON wh.user_id = u.id
  100. WHERE wh.id = ? LIMIT 0,1";
  101. $stmt = $this->conn->prepare($query);
  102. $stmt->bindParam(1, $this->id);
  103. $stmt->execute();
  104. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  105. $this->task_id = $row['task_id'];
  106. $this->user_id = $row['user_id'];
  107. $this->date = $row['date'];
  108. $this->hours = $row['hours'];
  109. $this->description = $row['description'];
  110. $this->rate = $row['rate'];
  111. $this->total_amount = $row['total_amount'];
  112. $this->created_at = $row['created_at'];
  113. $this->updated_at = $row['updated_at'];
  114. }
  115. public function update() {
  116. $query = "UPDATE " . $this->table_name . "
  117. SET task_id=:task_id, user_id=:user_id, date=:date, hours=:hours,
  118. description=:description, rate=:rate, total_amount=:total_amount,
  119. updated_at=:updated_at
  120. WHERE id=:id";
  121. $stmt = $this->conn->prepare($query);
  122. $this->task_id = htmlspecialchars(strip_tags($this->task_id));
  123. $this->user_id = htmlspecialchars(strip_tags($this->user_id));
  124. $this->date = htmlspecialchars(strip_tags($this->date));
  125. $this->hours = htmlspecialchars(strip_tags($this->hours));
  126. $this->description = htmlspecialchars(strip_tags($this->description));
  127. $this->rate = htmlspecialchars(strip_tags($this->rate));
  128. $this->total_amount = htmlspecialchars(strip_tags($this->total_amount));
  129. $this->updated_at = date('Y-m-d H:i:s');
  130. $stmt->bindParam(":task_id", $this->task_id);
  131. $stmt->bindParam(":user_id", $this->user_id);
  132. $stmt->bindParam(":date", $this->date);
  133. $stmt->bindParam(":hours", $this->hours);
  134. $stmt->bindParam(":description", $this->description);
  135. $stmt->bindParam(":rate", $this->rate);
  136. $stmt->bindParam(":total_amount", $this->total_amount);
  137. $stmt->bindParam(":updated_at", $this->updated_at);
  138. $stmt->bindParam(":id", $this->id);
  139. if($stmt->execute()) {
  140. return true;
  141. }
  142. return false;
  143. }
  144. public function delete() {
  145. $query = "DELETE FROM " . $this->table_name . " WHERE id = ?";
  146. $stmt = $this->conn->prepare($query);
  147. $stmt->bindParam(1, $this->id);
  148. if($stmt->execute()) {
  149. return true;
  150. }
  151. return false;
  152. }
  153. public function getTotalHoursByTask($task_id) {
  154. $query = "SELECT SUM(hours) as total_hours, COUNT(*) as entries
  155. FROM " . $this->table_name . "
  156. WHERE task_id = ?";
  157. $stmt = $this->conn->prepare($query);
  158. $stmt->bindParam(1, $task_id);
  159. $stmt->execute();
  160. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  161. return [
  162. 'total_hours' => $row['total_hours'] || 0,
  163. 'entries' => $row['entries'] || 0
  164. ];
  165. }
  166. public function getTotalHoursByUser($user_id, $start_date = null, $end_date = null) {
  167. $query = "SELECT SUM(wh.hours) as total_hours, COUNT(*) as entries
  168. FROM " . $this->table_name . " wh
  169. WHERE wh.user_id = ?";
  170. if ($start_date && $end_date) {
  171. $query .= " AND wh.date BETWEEN ? AND ?";
  172. }
  173. $stmt = $this->conn->prepare($query);
  174. $stmt->bindParam(1, $user_id);
  175. if ($start_date && $end_date) {
  176. $stmt->bindParam(2, $start_date);
  177. $stmt->bindParam(3, $end_date);
  178. }
  179. $stmt->execute();
  180. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  181. return [
  182. 'total_hours' => $row['total_hours'] || 0,
  183. 'entries' => $row['entries'] || 0
  184. ];
  185. }
  186. public function getClientHourPrice() {
  187. $query = "SELECT c.hour_price
  188. FROM " . $this->table_name . " wh
  189. LEFT JOIN tasks t ON wh.task_id = t.id
  190. LEFT JOIN projects p ON t.project_id = p.id
  191. LEFT JOIN clients c ON p.customer_id = c.id
  192. WHERE wh.task_id = ? AND c.hour_price IS NOT NULL AND c.hour_price > 0
  193. LIMIT 1";
  194. $stmt = $this->conn->prepare($query);
  195. $stmt->bindParam(1, $this->task_id);
  196. $stmt->execute();
  197. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  198. return $row ? $row['hour_price'] : 0;
  199. }
  200. }
  201. ?>