Pro.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <?php
  2. namespace App\Models;
  3. # use Illuminate\Database\Eloquent\Model;
  4. use App\Helpers\TimeLine;
  5. use Exception;
  6. class Pro extends Model
  7. {
  8. protected $table = 'pro';
  9. public function displayName() {
  10. $name = [];
  11. if(!empty($this->name_last)) $name[] = $this->name_last;
  12. if(!empty($this->name_first)) $name[] = $this->name_first;
  13. if(!count($name)) {
  14. $name = $this->name_display;
  15. }
  16. else {
  17. $name = implode(", ", $name);
  18. }
  19. return $name;
  20. }
  21. public function initials() {
  22. $characters = [];
  23. if(!empty($this->name_first)) $characters[] = $this->name_first[0];
  24. if(!empty($this->name_last)) $characters[] = $this->name_last[0];
  25. return strtolower(implode("", $characters));
  26. }
  27. public function cmBills()
  28. {
  29. return $this->hasMany(Bill::class, 'cm_pro_id');
  30. }
  31. public function hcpBills()
  32. {
  33. return $this->hasMany(Bill::class, 'hcp_pro_id');
  34. }
  35. public function lastPayment() {
  36. return ProTransaction
  37. ::where('pro_id', $this->id)
  38. ->where('plus_or_minus', 'PLUS')
  39. ->orderBy('created_at', 'desc')
  40. ->first();
  41. }
  42. public function hasRates() {
  43. $numRates = ProRate::where('is_active', true)->where('pro_id', $this->id)->count();
  44. return $numRates > 0;
  45. }
  46. public function cmRates() {
  47. return ProRate::distinct('code')
  48. ->where('is_active', true)
  49. ->where('pro_id', $this->id)
  50. ->where('code', 'LIKE', 'CM%')
  51. ->get();
  52. }
  53. public function rmRates() {
  54. return ProRate::distinct('code')
  55. ->where('is_active', true)
  56. ->where('pro_id', $this->id)
  57. ->where('code', 'LIKE', 'RM%')
  58. ->get();
  59. }
  60. public function noteRates() {
  61. return ProRate::distinct('code')
  62. ->where('is_active', true)
  63. ->where('pro_id', $this->id)
  64. ->where('code', 'NOT LIKE', 'CM%')
  65. ->where('code', 'NOT LIKE', 'RM%')
  66. ->get();
  67. }
  68. public function shortcuts() {
  69. return $this->hasMany(ProTextShortcut::class, 'pro_id')->where('is_removed', false);
  70. }
  71. public function noteTemplates() {
  72. return $this->hasMany(NoteTemplatePro::class, 'pro_id')
  73. ->where('is_removed', false)
  74. ->orderBy('position_index', 'asc');
  75. }
  76. public function currentWork() {
  77. return ProClientWork::where('pro_id', $this->id)->where('is_active', true)->first();
  78. }
  79. public function isWorkingOnClient($_client) {
  80. $count = ProClientWork::where('pro_id', $this->id)->where('client_id', $_client->id)->where('is_active', true)->count();
  81. return $count > 0;
  82. }
  83. public function canvasCustomItems($_key) {
  84. return ClientCanvasDataCustomItem::where('key', $_key)->get();
  85. }
  86. /**
  87. * @param $_start - YYYY-MM-DD
  88. * @param $_end - YYYY-MM-DD
  89. * @param string $_timezone - defaults to EASTERN
  90. * @param string $_availableBG - defaults to #00a
  91. * @param string $_unavailableBG - defaults to #a00
  92. * @return array
  93. * @throws Exception
  94. */
  95. public function getAvailabilityEvents($_start, $_end, $_timezone = 'EASTERN', $_availableBG = '#00a', $_unavailableBG = '#a00') {
  96. $_start .= ' 00:00:00';
  97. $_end .= ' 23:59:59';
  98. // get availability data
  99. $proGenAvail = ProGeneralAvailability
  100. ::where('is_cancelled', false)
  101. ->where('pro_id', $this->id)
  102. ->get();
  103. $proSpecAvail = ProSpecificAvailability
  104. ::where('is_cancelled', false)
  105. ->where('pro_id', $this->id)
  106. ->where(function ($query) use ($_start, $_end) {
  107. $query
  108. ->where(function ($query2) use ($_start, $_end) {
  109. $query2
  110. ->where('start_time', '>=', $_start)
  111. ->where('start_time', '<=', $_end);
  112. })
  113. ->orWhere(function ($query2) use ($_start, $_end) {
  114. $query2
  115. ->where('end_time', '>=', $_start)
  116. ->where('end_time', '<=', $_end);
  117. });
  118. })
  119. ->get();
  120. $proSpecUnavail = ProSpecificUnavailability
  121. ::where('is_cancelled', false)
  122. ->where('pro_id', $this->id)
  123. ->where(function ($query) use ($_start, $_end) {
  124. $query
  125. ->where(function ($query2) use ($_start, $_end) {
  126. $query2
  127. ->where('start_time', '>=', $_start)
  128. ->where('start_time', '<=', $_end);
  129. })
  130. ->orWhere(function ($query2) use ($_start, $_end) {
  131. $query2
  132. ->where('end_time', '>=', $_start)
  133. ->where('end_time', '<=', $_end);
  134. });
  135. })
  136. ->get();
  137. // default GA
  138. // if no gen avail, assume mon to fri, 9 to 7
  139. /*if (count($proGenAvail) === 0) {
  140. $dayNames = ['MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY'];
  141. foreach ($dayNames as $dayName) {
  142. $item = new \stdClass();
  143. $item->day_of_week = $dayName;
  144. $item->timezone = $_timezone;
  145. $item->start_time = '09:00:00';
  146. $item->end_time = '18:00:00';
  147. $proGenAvail->push($item);
  148. }
  149. }*/
  150. // create timeline
  151. $phpTZ = appTZtoPHPTZ($_timezone);
  152. $phpTZObject = new \DateTimeZone($phpTZ);
  153. $startDate = new \DateTime($_start, $phpTZObject);
  154. $endDate = new \DateTime($_end, $phpTZObject);
  155. $proTimeLine = new TimeLine($startDate, $endDate);
  156. // General availability
  157. $period = new \DatePeriod($startDate, \DateInterval::createFromDateString('1 day'), $endDate);
  158. $days = [];
  159. foreach ($period as $day) {
  160. $days[] = [
  161. "day" => strtoupper($day->format("l")), // SUNDAY, etc.
  162. "date" => $day->format("Y-m-d"), // 2020-10-04, etc.
  163. ];
  164. }
  165. foreach ($days as $day) {
  166. $proGenAvailForTheDay = $proGenAvail->filter(function ($record) use ($day) {
  167. return $record->day_of_week === $day["day"];
  168. });
  169. foreach ($proGenAvailForTheDay as $ga) {
  170. $gaStart = new \DateTime($day["date"], new \DateTimeZone(appTZtoPHPTZ($ga->timezone)));
  171. $parts = explode(":", $ga->start_time);
  172. $gaStart->setTime(intval($parts[0]), intval($parts[1]), intval($parts[2]));
  173. $gaStart->setTimezone($phpTZObject);
  174. $gaEnd = new \DateTime($day["date"], new \DateTimeZone(appTZtoPHPTZ($ga->timezone)));
  175. $parts = explode(":", $ga->end_time);
  176. $gaEnd->setTime(intval($parts[0]), intval($parts[1]), intval($parts[2]));
  177. $gaEnd->setTimezone($phpTZObject);
  178. $proTimeLine->addAvailability($gaStart, $gaEnd);
  179. }
  180. }
  181. // specific availability
  182. foreach ($proSpecAvail as $sa) {
  183. $saStart = new \DateTime($sa->start_time, new \DateTimeZone(appTZtoPHPTZ($sa->timezone)));
  184. $saStart->setTimezone($phpTZObject);
  185. $saEnd = new \DateTime($sa->end_time, new \DateTimeZone(appTZtoPHPTZ($sa->timezone)));
  186. $saEnd->setTimezone($phpTZObject);
  187. $proTimeLine->addAvailability($saStart, $saEnd);
  188. }
  189. // specific unavailability
  190. foreach ($proSpecUnavail as $sua) {
  191. $suaStart = new \DateTime($sua->start_time, new \DateTimeZone(appTZtoPHPTZ($sua->timezone)));
  192. $suaStart->setTimezone($phpTZObject);
  193. $suaEnd = new \DateTime($sua->end_time, new \DateTimeZone(appTZtoPHPTZ($sua->timezone)));
  194. $suaEnd->setTimezone($phpTZObject);
  195. $proTimeLine->removeAvailability($suaStart, $suaEnd);
  196. }
  197. $events = [];
  198. // availability
  199. foreach ($proTimeLine->getAvailable() as $item) {
  200. $eStart = new \DateTime('@' . $item->start);
  201. $eStart->setTimezone($phpTZObject);
  202. $eEnd = new \DateTime('@' . $item->end);
  203. $eEnd->setTimezone($phpTZObject);
  204. $events[] = [
  205. "type" => "availability",
  206. "start" => $eStart->format('Y-m-d H:i:s'),
  207. "end" => $eEnd->format('Y-m-d H:i:s'),
  208. "editable" => false,
  209. "backgroundColor" => $_availableBG
  210. ];
  211. }
  212. // unavailability
  213. foreach ($proTimeLine->getUnavailable() as $item) {
  214. $eStart = new \DateTime('@' . $item->start);
  215. $eStart->setTimezone($phpTZObject);
  216. $eEnd = new \DateTime('@' . $item->end);
  217. $eEnd->setTimezone($phpTZObject);
  218. $events[] = [
  219. "type" => "unavailability",
  220. "start" => $eStart->format('Y-m-d H:i:s'),
  221. "end" => $eEnd->format('Y-m-d H:i:s'),
  222. "editable" => false,
  223. "backgroundColor" => $_unavailableBG
  224. ];
  225. }
  226. return $events;
  227. }
  228. }