name_last)) $name[] = $this->name_last; if(!empty($this->name_first)) $name[] = $this->name_first; if(!count($name)) { $name = $this->name_display; } else { $name = implode(", ", $name); } return $name; } public function initials() { $characters = []; if(!empty($this->name_first)) $characters[] = $this->name_first[0]; if(!empty($this->name_last)) $characters[] = $this->name_last[0]; return strtolower(implode("", $characters)); } public function cmBills() { return $this->hasMany(Bill::class, 'cm_pro_id'); } public function hcpBills() { return $this->hasMany(Bill::class, 'hcp_pro_id'); } public function lastPayment() { return ProTransaction ::where('pro_id', $this->id) ->where('plus_or_minus', 'PLUS') ->orderBy('created_at', 'desc') ->first(); } public function hasRates() { $numRates = ProRate::where('is_active', true)->where('pro_id', $this->id)->count(); return $numRates > 0; } public function cmRates() { return ProRate::distinct('code') ->where('is_active', true) ->where('pro_id', $this->id) ->where('code', 'LIKE', 'CM%') ->get(); } public function rmRates() { return ProRate::distinct('code') ->where('is_active', true) ->where('pro_id', $this->id) ->where('code', 'LIKE', 'RM%') ->get(); } public function noteRates() { return ProRate::distinct('code') ->where('is_active', true) ->where('pro_id', $this->id) ->where('code', 'NOT LIKE', 'CM%') ->where('code', 'NOT LIKE', 'RM%') ->get(); } public function shortcuts() { return $this->hasMany(ProTextShortcut::class, 'pro_id')->where('is_removed', false); } public function noteTemplates() { return $this->hasMany(NoteTemplatePro::class, 'pro_id') ->where('is_removed', false) ->orderBy('position_index', 'asc'); } public function currentWork() { return ProClientWork::where('pro_id', $this->id)->where('is_active', true)->first(); } public function isWorkingOnClient($_client) { $count = ProClientWork::where('pro_id', $this->id)->where('client_id', $_client->id)->where('is_active', true)->count(); return $count > 0; } public function canvasCustomItems($_key) { return ClientCanvasDataCustomItem::where('key', $_key)->get(); } /** * @param $_start - YYYY-MM-DD * @param $_end - YYYY-MM-DD * @param string $_timezone - defaults to EASTERN * @param string $_availableBG - defaults to #00a * @param string $_unavailableBG - defaults to #a00 * @return array * @throws Exception */ public function getAvailabilityEvents($_start, $_end, $_timezone = 'EASTERN', $_availableBG = '#00a', $_unavailableBG = '#a00') { $_start .= ' 00:00:00'; $_end .= ' 23:59:59'; // get availability data $proGenAvail = ProGeneralAvailability ::where('is_cancelled', false) ->where('pro_id', $this->id) ->get(); $proSpecAvail = ProSpecificAvailability ::where('is_cancelled', false) ->where('pro_id', $this->id) ->where(function ($query) use ($_start, $_end) { $query ->where(function ($query2) use ($_start, $_end) { $query2 ->where('start_time', '>=', $_start) ->where('start_time', '<=', $_end); }) ->orWhere(function ($query2) use ($_start, $_end) { $query2 ->where('end_time', '>=', $_start) ->where('end_time', '<=', $_end); }); }) ->get(); $proSpecUnavail = ProSpecificUnavailability ::where('is_cancelled', false) ->where('pro_id', $this->id) ->where(function ($query) use ($_start, $_end) { $query ->where(function ($query2) use ($_start, $_end) { $query2 ->where('start_time', '>=', $_start) ->where('start_time', '<=', $_end); }) ->orWhere(function ($query2) use ($_start, $_end) { $query2 ->where('end_time', '>=', $_start) ->where('end_time', '<=', $_end); }); }) ->get(); // default GA // if no gen avail, assume mon to fri, 9 to 7 if (count($proGenAvail) === 0) { $dayNames = ['MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY']; foreach ($dayNames as $dayName) { $item = new \stdClass(); $item->day_of_week = $dayName; $item->timezone = $_timezone; $item->start_time = '09:00:00'; $item->end_time = '18:00:00'; $proGenAvail->push($item); } } // create timeline $phpTZ = appTZtoPHPTZ($_timezone); $phpTZObject = new \DateTimeZone($phpTZ); $startDate = new \DateTime($_start, $phpTZObject); $endDate = new \DateTime($_end, $phpTZObject); $proTimeLine = new TimeLine($startDate, $endDate); // General availability $period = new \DatePeriod($startDate, \DateInterval::createFromDateString('1 day'), $endDate); $days = []; foreach ($period as $day) { $days[] = [ "day" => strtoupper($day->format("l")), // SUNDAY, etc. "date" => $day->format("Y-m-d"), // 2020-10-04, etc. ]; } foreach ($days as $day) { $proGenAvailForTheDay = $proGenAvail->filter(function ($record) use ($day) { return $record->day_of_week === $day["day"]; }); foreach ($proGenAvailForTheDay as $ga) { $gaStart = new \DateTime($day["date"], new \DateTimeZone(appTZtoPHPTZ($ga->timezone))); $parts = explode(":", $ga->start_time); $gaStart->setTime(intval($parts[0]), intval($parts[1]), intval($parts[2])); $gaStart->setTimezone($phpTZObject); $gaEnd = new \DateTime($day["date"], new \DateTimeZone(appTZtoPHPTZ($ga->timezone))); $parts = explode(":", $ga->end_time); $gaEnd->setTime(intval($parts[0]), intval($parts[1]), intval($parts[2])); $gaEnd->setTimezone($phpTZObject); $proTimeLine->addAvailability($gaStart, $gaEnd); } } // specific availability foreach ($proSpecAvail as $sa) { $saStart = new \DateTime($sa->start_time, new \DateTimeZone(appTZtoPHPTZ($sa->timezone))); $saStart->setTimezone($phpTZObject); $saEnd = new \DateTime($sa->end_time, new \DateTimeZone(appTZtoPHPTZ($sa->timezone))); $saEnd->setTimezone($phpTZObject); $proTimeLine->addAvailability($saStart, $saEnd); } // specific unavailability foreach ($proSpecUnavail as $sua) { $suaStart = new \DateTime($sua->start_time, new \DateTimeZone(appTZtoPHPTZ($sua->timezone))); $suaStart->setTimezone($phpTZObject); $suaEnd = new \DateTime($sua->end_time, new \DateTimeZone(appTZtoPHPTZ($sua->timezone))); $suaEnd->setTimezone($phpTZObject); $proTimeLine->removeAvailability($suaStart, $suaEnd); } $events = []; // availability foreach ($proTimeLine->getAvailable() as $item) { $eStart = new \DateTime('@' . $item->start); $eStart->setTimezone($phpTZObject); $eEnd = new \DateTime('@' . $item->end); $eEnd->setTimezone($phpTZObject); $events[] = [ "type" => "availability", "start" => $eStart->format('Y-m-d H:i:s'), "end" => $eEnd->format('Y-m-d H:i:s'), "editable" => false, "backgroundColor" => $_availableBG ]; } // unavailability foreach ($proTimeLine->getUnavailable() as $item) { $eStart = new \DateTime('@' . $item->start); $eStart->setTimezone($phpTZObject); $eEnd = new \DateTime('@' . $item->end); $eEnd->setTimezone($phpTZObject); $events[] = [ "type" => "unavailability", "start" => $eStart->format('Y-m-d H:i:s'), "end" => $eEnd->format('Y-m-d H:i:s'), "editable" => false, "backgroundColor" => $_unavailableBG ]; } return $events; } }