patients.blade.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. @extends ('layouts/template')
  2. @section('content')
  3. <?php
  4. $showProgramsColumn = false;
  5. foreach($patients as $patient) {
  6. if(count($patient->clientPrograms)) {
  7. if($pro->pro_type === 'ADMIN') {
  8. $showProgramsColumn = true;
  9. break;
  10. }
  11. else {
  12. foreach($patient->clientPrograms as $clientProgram) {
  13. if(in_array($pro->id, [$clientProgram->mcp_pro_id, $clientProgram->manager_pro_id])) {
  14. $showProgramsColumn = true;
  15. break;
  16. }
  17. }
  18. if($showProgramsColumn) break;
  19. }
  20. }
  21. }
  22. ?>
  23. <div class="p-3 mcp-theme-1" id="patients-list">
  24. <div class="card">
  25. <div class="card-header px-3 py-2 d-flex align-items-center">
  26. <strong class="mr-4">
  27. <i class="fas fa-user"></i>
  28. Patients
  29. </strong>
  30. <div class="ml-auto d-flex align-items-center search-form">
  31. <form action="" method="get" class="mr-2" id="patients-search">
  32. <input type="text" name="q" value="{{request()->input('q')}}" class="form-control form-control-sm"
  33. placeholder="Name / Email / Tags">
  34. </form>
  35. <select class="ml-auto max-width-300px form-control form-control-sm"
  36. id="patients-filter">
  37. <option value="" {{ $filter === '' ? 'selected' : '' }}>All patients</option>
  38. <option value="not-yet-seen" {{ $filter === 'not-yet-seen' ? 'selected' : '' }}>Patients I have not seen yet</option>
  39. <option value="having-birthday-today" {{ $filter === 'having-birthday-today' ? 'selected' : '' }}>Patients having birthday today</option>
  40. </select>
  41. </div>
  42. </div>
  43. <div class="card-body p-0">
  44. <table class="table table-sm table-bordered p-0 m-0">
  45. <thead class="bg-light">
  46. <tr>
  47. @if($pro->pro_type === 'ADMIN')
  48. <th class="border-0"></th>
  49. @endif
  50. <th class="px-3 border-0">Chart #</th>
  51. <th class="border-0">Patient</th>
  52. @if($pro->isDefaultNA() || $pro->pro_type === 'ADMIN')
  53. <th class="border-0">Source</th>
  54. @endif
  55. <th class="border-0 px-1">OB</th>
  56. <th class="border-0">Signed<br>Notes</th>
  57. <th class="border-0">CM<br>Setup</th>
  58. <th class="border-0">Created At</th>
  59. <th class="border-0">Address</th>
  60. @if($showProgramsColumn)
  61. <th class="border-0">Program(s)</th>@endif
  62. <th class="border-0">MCN</th>
  63. <th class="border-0">PCP</th>
  64. <th class="border-0"><span class="text-nowrap">Recent Notes</span><br>(overall)</th>
  65. <th class="border-0"><span class="text-nowrap">Recent Notes</span><br>(me)</th>
  66. <th class="border-0">Appointments</th>
  67. <th class="border-0">Account</th>
  68. <th class="border-0">Tags</th>
  69. </tr>
  70. </thead>
  71. <tbody>
  72. @foreach($patients as $patient)
  73. <tr>
  74. @if($pro->pro_type === 'ADMIN')
  75. <td>{{$loop->index + 1}}</td>
  76. @endif
  77. <td class="px-3">
  78. <a href="{{route('patients.view.dashboard', $patient)}}">
  79. {{$patient->chart_number}}
  80. </a>
  81. </td>
  82. <td>
  83. {{$patient->displayName()}}
  84. <div>{{ friendly_date_time($patient->dob, false) }}{{ $patient->sex === 'M' ? ', Male' : ($patient->sex === ', F' ? 'Female' : '') }}</div>
  85. </td>
  86. @if($pro->isDefaultNA() || $pro->pro_type === 'ADMIN')
  87. <td>
  88. @if($patient->has_system_source)
  89. @if($patient->system_source_category === 'PRO_TEAM' && $patient->systemSourceProTeam)
  90. <div class="text-nowrap">Via team profile</div>
  91. <a native target="_blank" href="{{config('app.stagfe6_url')}}/{{$patient->systemSourceProTeam->slug}}">{{$patient->systemSourceProTeam->slug}}</a>
  92. @elseif($patient->system_source_category === 'PRO' && $patient->systemSourcePro)
  93. <div class="text-nowrap">Via pro profile</div>
  94. <a native target="_blank" href="{{config('app.stagfe6_url')}}/{{$patient->systemSourcePro->slug}}">{{$patient->systemSourcePro->slug}}</a>
  95. @endif
  96. @endif
  97. </td>
  98. @endif
  99. <td class="px-1">
  100. @if($patient->has_mcp_done_onboarding_visit !== 'YES')
  101. <span title="MCP Onboarding Visit Pending"><i class="fa fa-exclamation-triangle"></i></span>
  102. @else
  103. <i class="fa fa-check text-secondary on-hover-opaque"></i>
  104. @endif
  105. </td>
  106. <td>
  107. <?php $numSignedNotes = $patient->numSignedNotes(); ?>
  108. <span class="{{$numSignedNotes && $patient->has_mcp_done_onboarding_visit !== 'YES' ? 'font-weight-bold text-warning-mellow' : 'text-secondary'}}">
  109. {{$numSignedNotes ? $numSignedNotes :'-'}}
  110. </span>
  111. </td>
  112. <td>
  113. @if($patient->has_cm_setup_been_performed && $patient->cmSetupNote)
  114. <i class="fa fa-check text-secondary on-hover-opaque"></i>
  115. <br>
  116. <a href="{{route('patients.view.notes.view.dashboard', ['patient' => $patient, 'note' => $patient->cmSetupNote])}}">Note</a>
  117. @else
  118. -
  119. @endif
  120. </td>
  121. <td>
  122. {{ friendly_date_time_short_with_tz($patient->created_at, true, 'EASTERN') }}
  123. <hr>
  124. @if($pro->pro_type === 'ADMIN')
  125. {{ $patient->initiative }}
  126. @endif
  127. </td>
  128. <td>
  129. <?php
  130. $addressParts = [];
  131. if (!!$patient->mailing_address_line1) $addressParts[] = $patient->mailing_address_line1;
  132. if (!!$patient->mailing_address_line2) $addressParts[] = $patient->mailing_address_line2;
  133. $addressParts = implode(", ", $addressParts) . "<br/>";
  134. $addressPart2 = [];
  135. if (!!$patient->mailing_address_city) $addressPart2[] = $patient->mailing_address_city;
  136. if (!!$patient->mailing_address_state) $addressPart2[] = $patient->mailing_address_state;
  137. $addressParts .= implode(", ", $addressPart2);
  138. echo $addressParts;
  139. ?>
  140. </td>
  141. @if($showProgramsColumn)
  142. <td>
  143. <?php $programNumber = 0; ?>
  144. @foreach($patient->clientPrograms as $clientProgram)
  145. <?php
  146. if($pro->pro_type === 'ADMIN' ||
  147. in_array($pro->id, [$clientProgram->mcp_pro_id, $clientProgram->manager_pro_id])
  148. ) {
  149. // $program = $clientProgram->program;
  150. $programNumber++;
  151. ?>
  152. <div class="mb-1 text-nowrap">
  153. {{ $programNumber }}. {{ $clientProgram->title }}
  154. @if($clientProgram->has_mcp_done_onboarding_visit !== 'YES')
  155. <span title="Onboarding Pending" class="ml-1"><i class="fa fa-exclamation-triangle"></i></span>
  156. @else
  157. <span title="Onboarding Complete" class="ml-1 text-secondary"><i class="fa fa-check"></i></span>
  158. @endif
  159. </div>
  160. <?php } ?>
  161. @endforeach
  162. </td>
  163. @endif
  164. <td>
  165. <?php $coverageStatus = $patient->getPrimaryCoverageStatus(); ?>
  166. @if($coverageStatus === 'YES')
  167. <div class="text-nowrap">Covered <i class="fa fa-check-circle text-success"></i>
  168. </div>
  169. @elseif($coverageStatus === 'NO')
  170. <div class="text-nowrap">Not Covered <i class="fa fa-times text-danger"></i></div>
  171. @else
  172. <div class="text-nowrap">Unknown <i
  173. class="fa fa-exclamation-triangle text-warning-mellow"></i></div>
  174. @endif
  175. <?php $coverage = $patient->getPrimaryCoverage(); ?>
  176. @if($coverage)
  177. {{$coverage->insuranceDisplayName()}}
  178. @endif
  179. @include('app.patient.coverage-status')
  180. </td>
  181. <td>
  182. {{ $patient->mcp ? $patient->mcp->displayName() : '-' }}
  183. </td>
  184. <td class="p-0">
  185. <?php $allNotes = $patient->recentNotes(); ?>
  186. <table class="table table-sm table-condensed table-bordered m-0 width-200px">
  187. <tbody>
  188. @foreach($allNotes as $note)
  189. <tr>
  190. <td>
  191. <a href="{{route('patients.view.notes.view.dashboard', ['patient' => $patient, 'note' => $note])}}"><b class="text-nowrap">{{friendlier_date($note->effective_dateest)}}</b></a>
  192. <br>
  193. <span class="text-nowrap">{{$note->hcpPro->displayName()}}</span>
  194. </td>
  195. <td>{{$note->new_or_fu_or_na}}</td>
  196. </tr>
  197. @endforeach
  198. </tbody>
  199. </table>
  200. </td>
  201. <td class="py-0 pl-2">
  202. <?php $myNotes = $patient->recentNotes($pro); ?>
  203. <table class="table table-sm table-condensed table-bordered m-0 width-200px">
  204. <tbody>
  205. @foreach($myNotes as $note)
  206. <tr>
  207. <td>
  208. <a href="{{route('patients.view.notes.view.dashboard', ['patient' => $patient, 'note' => $note])}}"><b class="text-nowrap">{{friendlier_date($note->effective_dateest)}}</b></a>
  209. </td>
  210. <td>{{$note->new_or_fu_or_na}}</td>
  211. </tr>
  212. @endforeach
  213. </tbody>
  214. </table>
  215. </td>
  216. <td>
  217. <table class="table table-sm border-0 my-0">
  218. <tbody>
  219. <?php $numAppts = 0; ?>
  220. @foreach($patient->upcomingAppointments as $appointment)
  221. @if($appointment->status !== 'CANCELLED' && $appointment->status !== 'ABANDONED')
  222. <tr>
  223. <td class="text-black p-0 border-0">
  224. <div class="pb-0">
  225. {{ friendly_date_time($appointment->start_time, false) }}, {{ friendly_time($appointment->raw_start_time) }}
  226. <span class="d-inline-block text-secondary text-sm">({{ $appointment->timezone }})</span>
  227. <br>
  228. <b class="mr-1">{{$appointment->pro->displayName()}}</b>
  229. <span class="text-secondary text-sm">({{ $appointment->status }})</span>
  230. </div>
  231. </td>
  232. </tr>
  233. <?php $numAppts++; ?>
  234. @endif
  235. @endforeach
  236. @if(!$numAppts)
  237. <tr>
  238. <td class="text-secondary p-0 border-0">
  239. No upcoming appointments
  240. </td>
  241. </tr>
  242. @endif
  243. </tbody>
  244. </table>
  245. </td>
  246. <td>
  247. @if($patient->linkedAccounts && count($patient->linkedAccounts))
  248. <span class="font-weight-bold text-info"><i class="fa fa-check"></i></span>
  249. @else
  250. <span class="text-secondary">-</span>
  251. @endif
  252. </td>
  253. <td>
  254. @if($patient->tags)
  255. <?php
  256. $tags = explode("|", $patient->tags);
  257. $tags = array_filter($tags, function($_x) {
  258. return !empty($_x);
  259. });
  260. $tags = implode(", ", $tags);
  261. ?>
  262. {{ $tags }}
  263. @endif
  264. </td>
  265. </tr>
  266. @endforeach
  267. </tbody>
  268. </table>
  269. <div class="ml-2 mt-2">
  270. {{$patients->links()}}
  271. </div>
  272. </div>
  273. </div>
  274. </div>
  275. <script>
  276. (function() {
  277. function init() {
  278. function submit() {
  279. let url = '/patients' +
  280. ($('#patients-filter').val() ? '/' + $('#patients-filter').val() : '') +
  281. ($('#patients-search input').val() ? '?q=' + encodeURIComponent($('#patients-search input').val()) : '');
  282. fastLoad(url);
  283. return false;
  284. }
  285. $('#patients-search').off('submit').on('submit', submit);
  286. $('#patients-filter').off('change').on('change', submit);
  287. @if($pro->id === 1 || $pro->id === 16)
  288. patientAcquisitionChart();
  289. @endif
  290. }
  291. @if($pro->pro_type === 'ADMIN')
  292. <?php
  293. $dates = [];
  294. $acquisitions = [];
  295. for ($i = count($patientAcquisitionData) - 1; $i >= 0; $i--) {
  296. $dates[] = $patientAcquisitionData[$i]->date;
  297. $acquisitions[] = $patientAcquisitionData[$i]->count;
  298. }
  299. ?>
  300. function patientAcquisitionChart() {
  301. var chart = c3.generate({
  302. bindto: '#patientAcquisitionChart',
  303. data: {
  304. x: 'x',
  305. // xFormat: '%Y%m%d', // 'xFormat' can be used as custom format of 'x'
  306. columns: [
  307. ['x', <?= implode(", ", array_map(function($_x) { return "'" . $_x . "'"; }, $dates)) ?>],
  308. ['New Patients', <?= implode(", ", array_map(function($_x) { return "'" . $_x . "'"; }, $acquisitions)) ?>],
  309. ]
  310. },
  311. axis: {
  312. x: {
  313. type: 'timeseries',
  314. tick: {
  315. format: '%Y-%m-%d',
  316. multiline: true,
  317. fit: true,
  318. rotate: -45
  319. },
  320. },
  321. }
  322. });
  323. }
  324. @endif
  325. addMCInitializer('patients-list', init, '#patients-list');
  326. }).call(window);
  327. </script>
  328. @endsection