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; } public function getMyClientIds() { $clients = $this->getAccessibleClientsQuery()->get(); $clientIds = []; foreach($clients as $client){ $clientIds[] = $client->id; } return $clientIds; } public function favoritesByCategory($_category) { return ProFavorite::where('pro_id', $this->id) ->where('is_removed', false) ->where('category', $_category) ->orderBy('category', 'asc') ->orderBy('position_index', 'asc') ->get(); } public function getAccessibleClientsQuery() { $proID = $this->id; if ($this->pro_type === 'ADMIN') { $query = Client::where('id', '>', 0); } else { $query = Client::where(function ($q) use ($proID) { $q->where('mcp_pro_id', $proID) ->orWhere('cm_pro_id', $proID) ->orWhere('rmm_pro_id', $proID) ->orWhere('rme_pro_id', $proID) ->orWhere('physician_pro_id', $proID) ->orWhereRaw('id IN (SELECT client_id FROM client_pro_access WHERE is_active AND pro_id = ?)', [$proID]) ->orWhereRaw('id IN (SELECT client_id FROM appointment WHERE pro_id = ?)', [$proID]) ->orWhereRaw('id IN (SELECT mcp_pro_id FROM client_program WHERE client_id = client.id AND is_active = TRUE)') ->orWhereRaw('id IN (SELECT manager_pro_id FROM client_program WHERE client_id = client.id AND is_active = TRUE)'); }); } return $query; } public function canAddCPMEntryForMeasurement(Measurement $measurement, Pro $pro) { // check if client has any programs where this measurement type is allowed $allowed = false; $client = $measurement->client; $clientPrograms = $client->clientPrograms; if($pro->pro_type !== 'ADMIN') { $clientPrograms = $clientPrograms->filter(function($_clientProgram) use ($pro) { return $_clientProgram->manager_pro_id === $pro->id; }); } if(count($clientPrograms)) { foreach ($clientPrograms as $clientProgram) { if(strpos(strtolower($clientProgram->measurement_labels), '|' . strtolower($measurement->label) . '|') !== FALSE) { $allowed = true; break; } } } return $allowed ? $clientPrograms : FALSE; } public function getMeasurements($_onlyUnstamped = true) { $measurementsQuery = Measurement::where('is_removed', false); if ($this->pro_type != 'ADMIN') { $measurementsQuery ->whereIn('client_id', $this->getMyClientIds()); } if ($_onlyUnstamped) { $measurementsQuery ->whereNotNull('client_bdt_measurement_id') ->where(function ($q) { $q->whereNull('status') ->orWhere(function ($q2) { $q2->where('status', '<>', 'ACK') ->where('status', '<>', 'INVALID_ACK'); }); }); } $x = []; $measurements = $measurementsQuery->orderBy('id', 'desc')->paginate(50); // eager load stuff needed in JS foreach ($measurements as $measurement) { if ($measurement->client_bdt_measurement_id) { $measurement->bdtMeasurement = $measurement->clientBDTMeasurement->measurement; } unset($measurement->clientBDTMeasurement); // we do not need this travelling to the frontend $client = [ "uid" => $measurement->client->uid, "name" => $measurement->client->displayName(), ]; $measurement->patient = $client; $measurement->careMonth = $measurement->client->currentCareMonth(); $measurement->timestamp = friendly_date_time($measurement->created_at); unset($measurement->client); // we do not need this travelling to the frontend // if($measurement->label == 'SBP' || $measurement->label = 'DBP'){ // continue; // } $x[] = $measurement; } return $measurements; } }