Client.php 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078
  1. <?php
  2. namespace App\Models;
  3. use Illuminate\Database\Eloquent\Relations\HasOne;
  4. use Illuminate\Support\Collection;
  5. # use Illuminate\Database\Eloquent\Model;
  6. use Illuminate\Support\Facades\DB;
  7. class Client extends Model
  8. {
  9. protected $table = 'client';
  10. public function primaryCoverages()
  11. {
  12. return $this->hasMany(ClientPrimaryCoverage::class, 'client_id', 'id')
  13. ->whereRaw('(is_cancelled IS NULL OR is_cancelled IS FALSE)')
  14. ->orderBy('created_at', 'desc');
  15. }
  16. public function latestManualParentClientPrimaryCoverage(){
  17. return $this->hasOne(ClientPrimaryCoverage::class, 'id', 'latest_manual_parent_client_primary_coverage_id');
  18. }
  19. public function effectiveClientPrimaryCoverage(){
  20. return $this->hasOne(ClientPrimaryCoverage::class, 'id', 'effective_client_primary_coverage_id');
  21. }
  22. public function latestClientPrimaryCoverage(){
  23. return $this->hasOne(ClientPrimaryCoverage::class, 'id', 'latest_client_primary_coverage_id');
  24. }
  25. public function latestNewClientPrimaryCoverage(){
  26. return $this->hasOne(ClientPrimaryCoverage::class, 'id', 'latest_new_client_primary_coverage_id');
  27. }
  28. public function latestAutoRefreshClientPrimaryCoverage(){
  29. return $this->hasOne(ClientPrimaryCoverage::class, 'id', 'latest_auto_refresh_client_primary_coverage_id')
  30. ->whereRaw('(is_cancelled IS NULL OR is_cancelled IS FALSE)');
  31. }
  32. public function latestManualClientPrimaryCoverage(){
  33. return $this->hasOne(ClientPrimaryCoverage::class, 'id', 'latest_manual_client_primary_coverage_id')
  34. ->whereRaw('(is_cancelled IS NULL OR is_cancelled IS FALSE)');
  35. }
  36. public function temporaryOutsiderNewClientPrimaryCoverage(){
  37. return $this->hasOne(ClientPrimaryCoverage::class, 'id', 'temporary_outsider_new_client_primary_coverage_id');
  38. }
  39. public function displayName($_flat = true)
  40. {
  41. $result = '';
  42. if($_flat) {
  43. $result = $this->name_first . ' ' . $this->name_last;
  44. }
  45. else {
  46. $result = $this->name_last . ', ' . $this->name_first;
  47. }
  48. if($this->client_engagement_status_category == 'DUMMY') {
  49. $result .= ' [Test Record]';
  50. }
  51. if($this->client_engagement_status_category == 'DUPLICATE') {
  52. $result .= ' [Duplicate Record]';
  53. }
  54. return $result;
  55. }
  56. public function rtmMskHcp()
  57. {
  58. return $this->hasOne(Pro::class, 'id', 'rtm_msk_hcp_pro_id');
  59. }
  60. public function rtmLungHcp()
  61. {
  62. return $this->hasOne(Pro::class, 'id', 'rtm_lung_hcp_pro_id');
  63. }
  64. public function rtmMskCoach()
  65. {
  66. return $this->hasOne(Pro::class, 'id', 'rtm_msk_coach_pro_id');
  67. }
  68. public function rtmLungCoach()
  69. {
  70. return $this->hasOne(Pro::class, 'id', 'rtm_lung_coach_pro_id');
  71. }
  72. public function mcp()
  73. {
  74. return $this->hasOne(Pro::class, 'id', 'mcp_pro_id');
  75. }
  76. public function rd()
  77. {
  78. return $this->hasOne(Pro::class, 'id', 'rd_pro_id');
  79. }
  80. public function pcp()
  81. {
  82. return $this->hasOne(Pro::class, 'id', 'physician_pro_id');
  83. }
  84. public function cm()
  85. {
  86. return $this->hasOne(Pro::class, 'id', 'cm_pro_id');
  87. }
  88. public function rmm()
  89. {
  90. return $this->hasOne(Pro::class, 'id', 'rmm_pro_id');
  91. }
  92. public function rme()
  93. {
  94. return $this->hasOne(Pro::class, 'id', 'rme_pro_id');
  95. }
  96. public function rms()
  97. {
  98. return $this->hasOne(Pro::class, 'id', 'rms_pro_id');
  99. }
  100. public function rmg()
  101. {
  102. return $this->hasOne(Pro::class, 'id', 'rmg_pro_id');
  103. }
  104. public function defaultNaPro()
  105. {
  106. return $this->hasOne(Pro::class, 'id', 'default_na_pro_id');
  107. }
  108. public function stickyNoteUpdatedBySession()
  109. {
  110. return $this->hasOne(AppSession::class, 'id', 'sticky_note_updated_by_session_id');
  111. }
  112. public function creator()
  113. {
  114. return $this->hasOne(Pro::class, 'id', 'created_by_pro_id');
  115. }
  116. public function prosInMeetingWith()
  117. {
  118. return Pro::where('in_meeting_with_client_id', $this->id)->get();
  119. }
  120. public function notes()
  121. {
  122. return $this->hasMany(Note::class, 'client_id', 'id')
  123. // ->where('is_core_note', false)
  124. ->orderBy('effective_dateest', 'desc')
  125. ->orderBy('created_at', 'desc');
  126. }
  127. public function notesPendingClaimsClosed()
  128. {
  129. return $this->hasMany(Note::class, 'client_id', 'id')
  130. ->where('is_claim_closed', false)
  131. ->where('is_signed_by_hcp', true)
  132. ->where('is_cancelled', false)
  133. ->orderBy('effective_dateest', 'desc')
  134. ->orderBy('created_at', 'desc');
  135. }
  136. public function prescriptions()
  137. {
  138. return $this->hasMany(Erx::class, 'client_id', 'id')
  139. /*->where(function ($q) {
  140. $q->whereNull('pro_declared_status')
  141. ->orWhere('pro_declared_status', '<>', 'CANCELLED');
  142. })*/
  143. ->orderBy('created_at', 'desc')
  144. ->orderByRaw('note_id DESC NULLS LAST');
  145. }
  146. public function prescriptionsCreatedInNote($note)
  147. {
  148. return Erx::where('client_id', $this->id)
  149. ->where('note_id', $note->id)
  150. ->orderBy('created_at', 'desc')
  151. ->where(function ($q) {
  152. $q->whereNull('pro_declared_status')
  153. ->orWhere('pro_declared_status', '<>', 'CANCELLED');
  154. })
  155. ->get();
  156. }
  157. public function notesAscending()
  158. {
  159. return $this->hasMany(Note::class, 'client_id', 'id')
  160. ->orderBy('effective_dateest', 'asc')
  161. ->orderBy('created_at', 'desc');;
  162. }
  163. public function mcCodeChecks(){
  164. // $tables = DB::select("SELECT * FROM pg_catalog.pg_tables WHERE schemaname != 'pg_catalog' AND schemaname != 'information_schema'");
  165. // foreach ($tables as $table) {
  166. // dump($table);
  167. // }
  168. // die();
  169. return $this->hasMany(McCodeCheck::class, 'client_id', 'id')->orderBy('created_at', 'asc');
  170. }
  171. public function activeNotes()
  172. {
  173. return $this->hasMany(Note::class, 'client_id', 'id')
  174. ->where('is_cancelled', false)
  175. ->where('id', '<>', $this->core_note_id)
  176. ->orderBy('effective_dateest', 'desc')
  177. ->orderBy('created_at', 'desc');;
  178. }
  179. public function cancelledNotes()
  180. {
  181. return $this->hasMany(Note::class, 'client_id', 'id')
  182. ->where('is_cancelled', true)
  183. ->where('id', '<>', $this->core_note_id)
  184. ->orderBy('effective_dateest', 'desc')
  185. ->orderBy('created_at', 'desc');;
  186. }
  187. public function sections()
  188. {
  189. return $this->hasMany(Section::class, 'client_id', 'id')
  190. ->where('is_active', true)
  191. ->orderBy('created_at', 'asc');
  192. }
  193. public function handouts($note = null)
  194. {
  195. $mappings = HandoutClient::where('client_id', $this->id);
  196. if($note) {
  197. $mappings = $mappings->where('note_id', $note->id);
  198. }
  199. $mappings = $mappings->get();
  200. return $mappings;
  201. // $handouts = new Collection();
  202. // foreach ($mappings as $mapping) {
  203. // $handout = Handout::where('id', $mapping->handout_id)->first();
  204. // $handout->handout_client_uid = $mapping->uid;
  205. // $handouts->add($handout);
  206. // }
  207. // $handouts = $handouts->sortBy('created_at');
  208. // return $handouts;
  209. }
  210. public function duplicateOf()
  211. {
  212. return $this->hasOne(Client::class, 'id', 'duplicate_of_client_id');
  213. }
  214. public function actionItems()
  215. {
  216. return $this->hasMany(ActionItem::class, 'client_id', 'id')
  217. ->orderBy('action_item_category', 'asc')
  218. ->orderBy('created_at', 'desc');
  219. }
  220. public function infoLines()
  221. {
  222. return $this->hasMany(ClientInfoLine::class, 'client_id', 'id')->orderBy('created_at', 'desc');
  223. }
  224. public function measurements()
  225. {
  226. return $this->hasMany(Measurement::class, 'client_id', 'id')
  227. /*->distinct('label')*/
  228. ->where('is_active', true)
  229. ->orderByRaw('ts DESC NULLS LAST');
  230. }
  231. public function cellularMeasurements()
  232. {
  233. return $this->hasMany(Measurement::class, 'client_id', 'id')
  234. /*->distinct('label')*/
  235. ->where('is_active', true)
  236. ->where('is_cellular', true)
  237. ->where('is_cellular_zero', false)
  238. ->orderByRaw('ts DESC NULLS LAST');
  239. }
  240. public function recentMeasurements()
  241. {
  242. return $this->hasMany(Measurement::class, 'client_id', 'id')
  243. ->where('is_active', true)
  244. ->whereNotNull('label')
  245. ->where('label', '<>', 'SBP')
  246. ->where('label', '<>', 'DBP')
  247. ->where('is_cellular_zero', false)
  248. ->orderByRaw('ts DESC NULLS LAST')
  249. ->offset(0)->limit(20);
  250. }
  251. public function nonZeroMeasurements()
  252. {
  253. return $this->hasMany(Measurement::class, 'client_id', 'id')
  254. /*->distinct('label')*/
  255. ->where('is_active', true)
  256. ->where('is_cellular_zero', false)
  257. ->orderBy('effective_date', 'desc');
  258. }
  259. public function getNonZeroBpMeasurements(){
  260. return $this->hasMany(Measurement::class, 'client_id', 'id')
  261. /*->distinct('label')*/
  262. ->where('is_active', true)
  263. ->where('label', '=', 'BP')
  264. ->where('sbp_mm_hg', '>', 0)
  265. ->where('dbp_mm_hg', '>', 0)
  266. ->orderBy('ts', 'desc');
  267. }
  268. public function getNonZeroWeightMeasurements(){
  269. return $this->hasMany(Measurement::class, 'client_id', 'id')
  270. /*->distinct('label')*/
  271. ->where('is_active', true)
  272. ->where('label', '=', 'Wt. (lbs.)')
  273. ->where('numeric_value', '>', 0)
  274. ->orderBy('ts', 'desc');
  275. }
  276. public function currentCareMonth()
  277. {
  278. $cmStartDate = date('Y-m-01');
  279. return CareMonth::where('client_id', $this->id)
  280. ->whereRaw('start_date = ?', [$cmStartDate])
  281. ->first();
  282. }
  283. // returns the current care-month, if in fact patient is awaiting mcp rm interaction
  284. public function isAwaitingRMCommunicationFromMCP() {
  285. // if patient is enrolled in rm AND has current care month AND $careMonth->has_mcp_interacted_with_client_about_rm IS FALSE
  286. $careMonth = $this->currentCareMonth();
  287. if(!$careMonth) return false;
  288. if(!$careMonth->is_client_enrolled_in_rm) return false;
  289. return $careMonth->has_mcp_interacted_with_client_about_rm ? false : $careMonth;
  290. }
  291. public function previousCareMonth()
  292. {
  293. $cmStartDate = date('Y-m-d', strtotime('first day of last month'));
  294. return CareMonth
  295. ::where('client_id', $this->id)
  296. ->where('start_date', $cmStartDate)
  297. ->first();
  298. }
  299. public function measurementsInCareMonth(CareMonth $careMonth)
  300. {
  301. $cmStartDate = strtotime($careMonth->start_date);
  302. $month = date("n", $cmStartDate);
  303. $year = date("Y", $cmStartDate);
  304. $measurements = Measurement
  305. ::where('client_id', $this->id)
  306. ->whereRaw('EXTRACT(MONTH FROM effective_date) = ?', [$month])
  307. ->whereRaw('EXTRACT(YEAR FROM effective_date) = ?', [$year])
  308. ->where('is_active', true)
  309. ->orderBy('ts', 'desc')
  310. ->get();
  311. return $measurements;
  312. }
  313. public function allMeasurements()
  314. {
  315. return $this->hasMany(Measurement::class, 'client_id', 'id')
  316. ->where('is_active', true)
  317. ->whereNull('parent_measurement_id')
  318. ->orderBy('label', 'asc')
  319. ->orderBy('effective_date', 'desc');
  320. }
  321. public function smses()
  322. {
  323. return $this->hasMany(ClientSMS::class, 'client_id', 'id')
  324. ->orderBy('created_at', 'desc');
  325. }
  326. public function ismses()
  327. {
  328. return $this->hasMany(Isms::class, 'client_id', 'id')
  329. ->orderBy('created_at', 'desc');
  330. }
  331. public function documents()
  332. {
  333. return $this->hasMany(ClientDocument::class, 'client_id', 'id')
  334. ->orderBy('created_at', 'desc');
  335. }
  336. public function incomingReports() {
  337. return $this->hasMany(IncomingReport::class, 'client_id', 'id')
  338. ->orderBy('created_at', 'desc');
  339. }
  340. public function smsNumbers() {
  341. return $this->hasMany(ClientSMSNumber::class, 'client_id', 'id')
  342. ->orderBy('created_at', 'desc');
  343. }
  344. public function nextMcpAppointment()
  345. {
  346. return $this->hasOne(Appointment::class, 'id', 'next_mcp_appointment_id');
  347. }
  348. public function lastMcpAppointment()
  349. {
  350. return $this->hasOne(Appointment::class, 'id', 'previous_mcp_appointment_id');
  351. }
  352. public function mostRecentCompletedMcpNote()
  353. {
  354. return $this->hasOne(Note::class, 'id', 'most_recent_completed_mcp_note_id');
  355. }
  356. public function lastMeasurementOfType($_type) {
  357. return Measurement::where('client_id', $this->id)
  358. ->whereNotNull('bdt_measurement_id')
  359. ->whereNotNull('ts')
  360. ->where('is_cellular_zero', false)
  361. ->where('is_active', true)
  362. ->where('label', '=', $_type)
  363. ->orderBy('ts', 'desc')
  364. ->first();
  365. }
  366. public function appointments()
  367. {
  368. return $this->hasMany(Appointment::class, 'client_id', 'id')
  369. ->orderBy('start_time', 'desc');
  370. }
  371. public function appointmentsForProByStatus($forPro = 'all', $status = 'all')
  372. {
  373. $appointments = Appointment::where('client_id', $this->id);
  374. if($forPro !== 'all') {
  375. $forPro = Pro::where('uid', $forPro)->first();
  376. $appointments = $appointments->where('pro_id', $forPro->id);
  377. }
  378. if($status !== 'ALL') {
  379. $appointments = $appointments->where('status', $status);
  380. }
  381. $appointments = $appointments->orderBy('raw_date', 'desc')->orderBy('raw_start_time', 'desc');
  382. return $appointments->get();
  383. }
  384. public function upcomingAppointments()
  385. {
  386. return $this->hasMany(Appointment::class, 'client_id', 'id')
  387. ->where('raw_date', '>=', date('Y-m-d'))
  388. ->whereIn('status', ['PENDING', 'CONFIRMED'])
  389. ->orderBy('start_time', 'desc')
  390. ->limit(5);
  391. }
  392. public function nextAppointment() {
  393. return Appointment
  394. ::where('client_id', $this->id)
  395. ->where('raw_date', '>=', DB::raw('NOW()'))
  396. ->whereIn('status', ['PENDING', 'CONFIRMED'])
  397. ->orderBy('start_time')
  398. ->first();
  399. }
  400. public function appointmentsFromLastWeek()
  401. {
  402. $dateLastWeek = date_sub(date_create(), date_interval_create_from_date_string("14 days"));
  403. $dateLastWeek = date_format($dateLastWeek, "Y-m-d");
  404. return $this->hasMany(Appointment::class, 'client_id', 'id')
  405. ->where('raw_date', '>=', $dateLastWeek)
  406. ->orderBy('start_time', 'desc');
  407. }
  408. public function memos()
  409. {
  410. return $this->hasMany(ClientMemo::class, 'client_id', 'id')
  411. ->where('is_cancelled', false)
  412. ->orderBy('created_at', 'desc');
  413. }
  414. public function latestMemo()
  415. {
  416. return ClientMemo::where('client_id', $this->id)
  417. ->where('is_cancelled', false)
  418. ->orderBy('created_at', 'desc')
  419. ->first();
  420. }
  421. public function devices()
  422. {
  423. return $this->hasMany(ClientBDTDevice::class, 'client_id', 'id')
  424. ->where('is_active', true)
  425. ->orderBy('created_at', 'desc');
  426. }
  427. public function deactivatedDevices()
  428. {
  429. return $this->hasMany(ClientBDTDevice::class, 'client_id', 'id')
  430. ->where('is_active', false)
  431. ->orderBy('created_at', 'desc');
  432. }
  433. public function hasDevice($_device)
  434. {
  435. $count = ClientBDTDevice::where('client_id', $this->id)
  436. ->where('device_id', $_device->id)
  437. ->where('is_active', true)
  438. ->count();
  439. return !!$count;
  440. }
  441. public function deviceMeasurements()
  442. {
  443. return $this->hasMany(ClientBDTMeasurement::class, 'client_id', 'id')
  444. ->orderBy('created_at', 'desc');
  445. }
  446. public function activeMcpRequest()
  447. {
  448. return $this->hasOne(McpRequest::class, 'id', 'active_mcp_request_id');
  449. }
  450. public function clientPrograms()
  451. {
  452. return $this->hasMany(ClientProgram::class, 'client_id', 'id')
  453. ->where('is_active', true)
  454. ->orderBy('title', 'desc');
  455. }
  456. public function tickets()
  457. {
  458. return $this->hasMany(Ticket::class, 'client_id', 'id')
  459. ->orderBy('is_open', 'desc')
  460. ->orderBy('created_at', 'desc');
  461. }
  462. public function mcpDisplayName()
  463. {
  464. }
  465. public function rmeDisplayName()
  466. {
  467. }
  468. public function supplyOrderForCellularBPDevice() {
  469. return SupplyOrder::where('product_id', 1)
  470. ->where('is_cancelled', false)
  471. ->where('client_id', $this->id)
  472. ->orderBy('id', 'desc')
  473. ->first();
  474. }
  475. public function supplyOrderForCellularWeightScale() {
  476. return SupplyOrder::where('product_id', 2)
  477. ->where('is_cancelled', false)
  478. ->where('client_id', $this->id)
  479. ->orderBy('id', 'desc')
  480. ->first();
  481. }
  482. public function firstCellularBPDevice()
  483. {
  484. $devices = $this->devices;
  485. $x = null;
  486. foreach($devices as $device){
  487. if($device->device->category == 'BP'){
  488. $x = $device;
  489. break;
  490. }
  491. }
  492. return $x;
  493. }
  494. public function getFirstCellularBPMeasurementAt()
  495. {
  496. }
  497. public function getLatestCellularBPMeasurementAt()
  498. {
  499. }
  500. public function getTotalCellularBPMeasurements()
  501. {
  502. }
  503. public function firstCellularWeightDevice()
  504. {
  505. $devices = $this->devices;
  506. $x = null;
  507. foreach($devices as $device){
  508. if($device->device->category == 'WEIGHT'){
  509. $x = $device;
  510. break;
  511. }
  512. }
  513. return $x;
  514. }
  515. public function getFirstCellularWeightMeasurementAt()
  516. {
  517. }
  518. public function getLatestCellularWeightMeasurementAt()
  519. {
  520. }
  521. public function getTotalCellularWeightMeasurements()
  522. {
  523. }
  524. public function prosWithAccess()
  525. {
  526. $pros = [];
  527. // directly associated pros
  528. $pro = $this->mcp;
  529. if ($pro && $pro->id) $pros[] = ["pro" => $pro->displayName(), "association" => 'MCP'];
  530. $pro = $this->pcp;
  531. if ($pro && $pro->id) $pros[] = ["pro" => $pro->displayName(), "association" => 'PCP (Physician)'];
  532. $pro = $this->cm;
  533. if ($pro && $pro->id) $pros[] = ["pro" => $pro->displayName(), "association" => 'CM'];
  534. $pro = $this->rmm;
  535. if ($pro && $pro->id) $pros[] = ["pro" => $pro->displayName(), "association" => 'RMM'];
  536. $pro = $this->rme;
  537. if ($pro && $pro->id) $pros[] = ["pro" => $pro->displayName(), "association" => 'RME'];
  538. $pro = $this->defaultNaPro;
  539. if ($pro && $pro->id) $pros[] = ["pro" => $pro->displayName(), "association" => 'Care Coordinator'];
  540. // via client pro access
  541. $cpAccesses = ClientProAccess::where('client_id', $this->id)->where('is_active', true)->get();
  542. foreach ($cpAccesses as $cpAccess) {
  543. if (!$cpAccess->pro) continue;
  544. $pros[] = ["pro" => $cpAccess->pro->displayName(), "association" => $cpAccess->reason_category. ' - Via Client Pro Access', 'isClientProAccess'=>true, 'clientProAccess'=>$cpAccess];
  545. }
  546. // via appointments
  547. $appointments = Appointment::where('client_id', $this->id)->get();
  548. foreach ($appointments as $appointment) {
  549. if (!$appointment->pro) continue;
  550. $pros[] = ["pro" => $appointment->pro->displayName(), "association" => 'Via Appointment: ' . $appointment->raw_date];
  551. }
  552. // via client program
  553. $clientPrograms = ClientProgram::where('client_id', $this->id)->where('is_active', true)->get();
  554. foreach ($clientPrograms as $clientProgram) {
  555. if ($clientProgram->mcp)
  556. $pros[] = ["pro" => $clientProgram->mcp->displayName(), "association" => 'Program MCP: ' . $clientProgram->title];
  557. if ($clientProgram->manager)
  558. $pros[] = ["pro" => $clientProgram->manager->displayName(), "association" => 'Program Manager: ' . $clientProgram->title];
  559. }
  560. // sort by pro name
  561. $name = array_column($pros, 'pro');
  562. array_multisort($name, SORT_ASC, $pros);
  563. return $pros;
  564. }
  565. public function mcpRequests()
  566. {
  567. return $this->hasMany(McpRequest::class, 'for_client_id', 'id')
  568. ->orderBy('created_at', 'desc');
  569. }
  570. public function eligibleRefreshes()
  571. {
  572. return $this->hasMany(ClientEligibleRefresh::class, 'client_id', 'id')
  573. ->orderBy('created_at', 'desc');
  574. }
  575. public function mbPayerValidationResults()
  576. {
  577. return $this->hasMany(ClientMBPayerValidationResult::class, 'client_id', 'id')
  578. ->orderBy('created_at', 'desc');
  579. }
  580. public function payer()
  581. {
  582. return $this->hasOne(MBPayer::class, 'id', 'mb_payer_id');
  583. }
  584. public function supplyOrders()
  585. {
  586. return $this->hasMany(SupplyOrder::class, 'client_id', 'id')
  587. ->orderBy('created_at', 'desc');
  588. }
  589. public function activeSupplyOrders()
  590. {
  591. return $this->hasMany(SupplyOrder::class, 'client_id', 'id')
  592. ->where('is_cancelled', false)
  593. ->orderBy('created_at', 'desc');
  594. }
  595. public function cancelledSupplyOrders()
  596. {
  597. return $this->hasMany(SupplyOrder::class, 'client_id', 'id')
  598. ->where('is_cancelled', true)
  599. ->orderBy('created_at', 'desc');
  600. }
  601. public function readyToShipSupplyOrders()
  602. {
  603. return $this->hasMany(SupplyOrder::class, 'client_id', 'id')
  604. ->where('is_cancelled', false)
  605. ->where('is_cleared_for_shipment', true)
  606. ->whereNull('shipment_id')
  607. ->orderBy('created_at', 'desc');
  608. }
  609. public function shipments()
  610. {
  611. return $this->hasMany(Shipment::class, 'client_id', 'id')
  612. ->where('is_cancelled', false)
  613. ->orderBy('created_at', 'desc');
  614. }
  615. public function numSignedNotes() {
  616. return Note::where('client_id', $this->id)
  617. ->where('is_cancelled', false)
  618. ->where('is_signed_by_hcp', true)
  619. ->count();
  620. }
  621. public function smsReminders()
  622. {
  623. return $this->hasMany(SimpleSMSReminder::class, 'client_id', 'id')
  624. ->orderBy('created_at', 'asc');
  625. }
  626. public function measurementConfirmationNumbers()
  627. {
  628. return $this->hasMany(MeasurementConfirmationNumber::class, 'client_id', 'id')
  629. ->orderBy('created_at', 'asc');
  630. }
  631. public function shadowOfPro() {
  632. return $this->hasOne(Pro::class, 'id', 'shadow_pro_id');
  633. }
  634. public function clientTags()
  635. {
  636. return $this->hasMany(ClientTag::class, 'client_id', 'id')
  637. ->where('is_cancelled', false)
  638. ->orderBy('tag', 'asc');
  639. }
  640. public function medicalTeam()
  641. {
  642. return $this->hasMany(ClientProAccess::class, 'client_id', 'id')
  643. ->where('is_active', true)
  644. ->whereNotNull('pro_id')
  645. ->orderBy('created_at', 'asc');
  646. }
  647. public function accountInvites()
  648. {
  649. return $this->hasMany(AccountInvite::class, 'for_client_id', 'id')
  650. ->orderBy('created_at', 'desc');
  651. }
  652. public function linkedAccounts()
  653. {
  654. return $this->hasMany(AccountClient::class, 'client_id', 'id')
  655. ->orderBy('created_at', 'desc');
  656. }
  657. public function pages($_type, $_returnShadows, $_note) {
  658. return Page
  659. ::where('client_id', $this->id)
  660. ->where('note_id', $_note->id)
  661. ->where('category', $_type)
  662. ->where('is_shadow', !!$_returnShadows)
  663. ->orderBy('key', 'ASC')
  664. ->get();
  665. }
  666. public function firstPageByCategoryAndKey($_category, $_key) {
  667. return Page
  668. ::where('client_id', $this->id)
  669. ->where('category', $_category)
  670. ->where('key', $_key)
  671. ->first();
  672. }
  673. public function cmReasons()
  674. {
  675. return $this->hasMany(ClientCmRmReason::class, 'client_id', 'id')
  676. ->where('cm_or_rm', 'CM')
  677. ->where('is_removed', false)
  678. ->orderBy('position_index', 'ASC')
  679. ->orderBy('code', 'ASC');
  680. }
  681. public function rmReasons()
  682. {
  683. return $this->hasMany(ClientCmRmReason::class, 'client_id', 'id')
  684. ->where('cm_or_rm', 'RM')
  685. ->where('is_removed', false)
  686. ->orderBy('position_index', 'ASC')
  687. ->orderBy('code', 'ASC');
  688. }
  689. public function cmSetupNote()
  690. {
  691. return $this->hasOne(Note::class, 'id', 'cm_setup_note_id');
  692. }
  693. public function rmSetupCareMonth()
  694. {
  695. return $this->hasOne(CareMonth::class, 'id', 'rm_setup_care_month_id');
  696. }
  697. public function defaultMcpCompanyPro()
  698. {
  699. return $this->hasOne(CompanyPro::class, 'id', 'default_mcp_company_pro_id');
  700. }
  701. public function defaultMcpCompanyProPayer()
  702. {
  703. return $this->hasOne(CompanyProPayer::class, 'id', 'default_mcp_company_pro_payer_id');
  704. }
  705. public function defaultMcpCompanyLocation()
  706. {
  707. return $this->hasOne(CompanyLocation::class, 'id', 'default_mcp_company_location_id');
  708. }
  709. public function hasNewNoteForPro($_pro) {
  710. $count = Note::where('client_id', $this->id)->where('hcp_pro_id', $_pro->id)->where('is_cancelled', false)->where('new_or_fu_or_na', 'NEW')->count();
  711. return !!$count;
  712. }
  713. public function systemSourcePro()
  714. {
  715. return $this->hasOne(Pro::class, 'id', 'system_source_pro_id');
  716. }
  717. public function systemSourceProTeam()
  718. {
  719. return $this->hasOne(ProTeam::class, 'id', 'system_source_pro_team_id');
  720. }
  721. public function adminEngagementAssessmentStatus(){
  722. return $this->hasOne(Status::class, 'id', 'admin_engagement_assessment_status_id');
  723. }
  724. public function mcpEngagementAssessmentStatus(){
  725. return $this->hasOne(Status::class, 'id', 'mcp_engagement_assessment_status_id');
  726. }
  727. public function defaultNaEngagementAssessmentStatus(){
  728. return $this->hasOne(Status::class, 'id', 'default_na_engagement_assessment_status_id');
  729. }
  730. public function clientSelfSatisfactionStatus(){
  731. return $this->hasOne(Status::class, 'id', 'client_self_satisfaction_status_id');
  732. }
  733. public function recentNotes($_pro = null) {
  734. $notes = Note::where('client_id', $this->id)->where('is_cancelled', false);
  735. if($_pro) {
  736. $notes = $notes->where('hcp_pro_id', $_pro->id);
  737. }
  738. $notes = $notes->orderBy('effective_dateest', 'DESC')->limit(5)->get();
  739. return $notes;
  740. }
  741. public function cmMeasurementsMatrix($_careMonth, $pro = null) {
  742. $days = [];
  743. $matches = DB::select(
  744. "
  745. SELECT m.id AS measurement_id,
  746. m.uid AS measurement_uid,
  747. cm.id AS care_month_id,
  748. cm.uid AS care_month_uid,
  749. m.label,
  750. m.value,
  751. m.dbp_mm_hg,
  752. m.sbp_mm_hg,
  753. m.value_pulse,
  754. m.value_irregular,
  755. m.numeric_value,
  756. m.effective_date,
  757. m.ts,
  758. m.has_been_stamped_by_mcp,
  759. m.has_been_stamped_by_rmm,
  760. m.has_been_stamped_by_non_hcp
  761. FROM measurement m
  762. JOIN care_month cm ON m.care_month_id = cm.id
  763. WHERE m.care_month_id = :careMonthID
  764. AND m.label NOT IN ('SBP', 'DBP')
  765. AND m.bdt_measurement_id IS NOT NULL
  766. AND m.is_active IS TRUE
  767. AND (m.is_cellular_zero = FALSE or m.is_cellular_zero IS NULL)
  768. AND m.ts IS NOT NULL
  769. AND m.client_bdt_measurement_id IS NOT NULL
  770. ORDER BY m.ts DESC
  771. ",
  772. ['careMonthID' => $_careMonth->id]
  773. );
  774. foreach ($matches as $match) {
  775. $time = (floor($match->ts / 1000));
  776. $realTimezone = resolve_timezone('EASTERN');
  777. $date = new \DateTime("@$time");
  778. $date->setTimezone(new \DateTimeZone($realTimezone));
  779. $match->date = $date->format("m/d/Y");
  780. $match->dateYMD = $date->format("Y-m-d");
  781. $match->time = $date->format("h:i A");
  782. // get existing entries for listing
  783. $match->entries = CareMonthEntry::where('care_month_id', $match->care_month_id)
  784. ->where('is_removed', false)
  785. ->where('effective_date', $match->dateYMD);
  786. if(!!$pro) {
  787. $match->entries = $match->entries->where('pro_id', $pro->id);
  788. }
  789. $match->entries = $match->entries->orderBy('created_at')->get();
  790. if(!isset($days[$match->date])) {
  791. $days[$match->date] = [];
  792. }
  793. $days[$match->date][] = $match;
  794. }
  795. return $days;
  796. }
  797. public function getPrimaryCoverage()
  798. {
  799. return $this->effectiveClientPrimaryCoverage;
  800. }
  801. // return value will be YES, NO or UNKNOWN
  802. public function getPrimaryCoverageStatus() {
  803. $coverage = $this->getPrimaryCoverage();
  804. if(!$coverage) return 'NO';
  805. return $coverage->getStatus();
  806. }
  807. public function getMcpAssignedOn() {
  808. $change = ClientProChange::where('client_id', $this->id)
  809. ->where('new_pro_id', $this->mcp_pro_id)
  810. ->where('responsibility_type', 'MCP')
  811. ->orderBy('created_at', 'DESC')
  812. ->first();
  813. if(!!$change) {
  814. return friendlier_date($change->created_at);
  815. }
  816. return '-';
  817. }
  818. public function coreNote(){
  819. return $this->hasOne(Note::class, 'id', 'core_note_id');
  820. }
  821. public function nonCoreVisitNotes() {
  822. return $this->hasMany(Note::class, 'client_id', 'id')
  823. ->where('id', '<>', $this->core_note_id)
  824. ->whereNotNull('visit_template_id')
  825. ->orderBy('created_at', 'desc');
  826. }
  827. public function clientProChanges() {
  828. return $this->hasMany(ClientProChange::class, 'client_id', 'id')
  829. ->orderBy('created_at', 'desc');
  830. }
  831. public function mostRecentWeightMeasurement(){
  832. return $this->hasOne(Measurement::class, 'id', 'most_recent_weight_measurement_id');
  833. }
  834. public function hasBPDevice() {
  835. $cbds = ClientBDTDevice::where('client_id', $this->id)->get();
  836. foreach ($cbds as $cbd) {
  837. if($cbd->is_active && !!$cbd->device && $cbd->device->is_active && $cbd->device->category === 'BP') return true;
  838. }
  839. return false;
  840. }
  841. public function hasWeightScaleDevice() {
  842. $cbds = ClientBDTDevice::where('client_id', $this->id)->get();
  843. foreach ($cbds as $cbd) {
  844. if($cbd->is_active && !!$cbd->device && $cbd->device->is_active && $cbd->device->category === 'WEIGHT') return true;
  845. }
  846. return false;
  847. }
  848. public function clientEngagementStatus(){
  849. return $this->hasOne(Status::class, 'id', 'client_engagement_status_id');
  850. }
  851. public function clientBpWeightPhoneNumberStatus(){
  852. return $this->hasOne(ClientBpWeightPhoneNumberStatus::class, 'id', 'client_bp_weight_phone_number_status_id');
  853. }
  854. public function getDeviceDeliveryStatus($productId){
  855. $result = DB::select("SELECT sh.status FROM shipment sh LEFT JOIN supply_order so ON so.shipment_id = sh.id WHERE so.product_id = ".$productId." AND so.client_id = ".$this->id." ORDER BY sh.created_at DESC LIMIT 1");
  856. if (count($result)){
  857. return $result[0]->status;
  858. }
  859. return '';
  860. }
  861. public function hasDataInCanvas($_type) {
  862. $page = Page::where('client_id', $this->id)->where('category', 'CANVAS')->where('key', $_type)->first();
  863. $contentData = [];
  864. if($page){
  865. $contentData = json_decode($page->data, true);
  866. }else{
  867. if($this->canvas_data) {
  868. $canvasData = json_decode($this->canvas_data, true);
  869. if(isset($canvasData[$_type])) {
  870. $contentData = $canvasData[$_type];
  871. if($_type !== 'vitals') {
  872. if(!isset($contentData['items'])){
  873. $contentData['items'] = [];
  874. }
  875. }
  876. }
  877. }
  878. }
  879. if($_type !== 'vitals') {
  880. if (isset($contentData['items']) && count($contentData['items'])) {
  881. return true;
  882. }
  883. }
  884. else {
  885. foreach ($contentData as $cd) {
  886. if(isset($cd['value']) && !empty($cd['value'])) return true;
  887. }
  888. }
  889. return false;
  890. }
  891. // 4 Infra-red Temperature gun
  892. public function temparatureGunDeliveryStatus(){
  893. return $this->getDeviceDeliveryStatus(4);
  894. }
  895. // 3 Pulse Oximeter (
  896. public function pulseOximeterDeliveryStatus(){
  897. return $this->getDeviceDeliveryStatus(3);
  898. }
  899. // 1 Cellular BP - Standard Arm Cuff (if delivered, then it should show its status as Delivered, Dispatched, In-transit, Returned)
  900. public function cellularBPDeliveryStatus(){
  901. return $this->getDeviceDeliveryStatus(1);
  902. }
  903. // 2 Weight scale
  904. public function weightScaleDeliveryStatus(){
  905. return $this->getDeviceDeliveryStatus(2);
  906. }
  907. public function carePlanFlaggedBy(){
  908. return $this->hasOne(Pro::class, 'id', 'flagged_by_pro_id');
  909. }
  910. public function carePlanFlagAcknowledgedBy(){
  911. return $this->hasOne(Pro::class, 'id', 'flag_acknowledged_by_pro_id');
  912. }
  913. public function clientRepFollowUp(){
  914. return $this->hasOne(ClientRepFollowUp::class, 'id', 'client_rep_follow_up_id');
  915. }
  916. public function customers() {
  917. return $this->hasMany(Customer::class, 'client_id', 'id')
  918. ->orderBy('created_at', 'desc');
  919. }
  920. }