|
@@ -0,0 +1,762 @@
|
|
|
|
+@extends ('layouts.patient')
|
|
|
|
+@section('inner-content')
|
|
|
|
+
|
|
|
|
+ <?php
|
|
|
|
+
|
|
|
|
+ $categories = ['erx', 'lab', 'imaging', 'equipment'];
|
|
|
|
+
|
|
|
|
+ function adjustBrightness($hex, $steps) {
|
|
|
|
+ $steps = max(-255, min(255, $steps));
|
|
|
|
+ $hex = str_replace('#', '', $hex);
|
|
|
|
+ if (strlen($hex) == 3) {
|
|
|
|
+ $hex = str_repeat(substr($hex,0,1), 2).str_repeat(substr($hex,1,1), 2).str_repeat(substr($hex,2,1), 2);
|
|
|
|
+ }
|
|
|
|
+ $color_parts = str_split($hex, 2);
|
|
|
|
+ $return = '#';
|
|
|
|
+ foreach ($color_parts as $color) {
|
|
|
|
+ $color = hexdec($color); // Convert to decimal
|
|
|
|
+ $color = max(0,min(255,$color + $steps)); // Adjust color
|
|
|
|
+ $return .= str_pad(dechex($color), 2, '0', STR_PAD_LEFT); // Make two char hex code
|
|
|
|
+ }
|
|
|
|
+ return $return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $palette = [
|
|
|
|
+ ["bc" => '#522e92', "fc" => "#ffffff", "ac" => adjustBrightness('#522e92', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#003152', "fc" => "#ffffff", "ac" => adjustBrightness('#003152', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#111e6c', "fc" => "#ffffff", "ac" => adjustBrightness('#111e6c', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#1034a6', "fc" => "#ffffff", "ac" => adjustBrightness('#1034a6', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#0f52ba', "fc" => "#ffffff", "ac" => adjustBrightness('#0f52ba', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#447684', "fc" => "#ffffff", "ac" => adjustBrightness('#447684', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#d86700', "fc" => "#ffffff", "ac" => adjustBrightness('#d86700', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#643c07', "fc" => "#ffffff", "ac" => adjustBrightness('#643c07', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#ff3f3f', "fc" => "#ffffff", "ac" => adjustBrightness('#ff3f3f', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#ffa395', "fc" => "#222222", "ac" => adjustBrightness('#ffa395', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#6450ff', "fc" => "#ffffff", "ac" => adjustBrightness('#6450ff', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#8ec7f4', "fc" => "#222222", "ac" => adjustBrightness('#8ec7f4', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#522e92', "fc" => "#ffffff", "ac" => adjustBrightness('#522e92', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#111e6c', "fc" => "#ffffff", "ac" => adjustBrightness('#111e6c', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#003152', "fc" => "#ffffff", "ac" => adjustBrightness('#003152', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#1034a6', "fc" => "#ffffff", "ac" => adjustBrightness('#1034a6', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#0f52ba', "fc" => "#ffffff", "ac" => adjustBrightness('#0f52ba', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#447684', "fc" => "#ffffff", "ac" => adjustBrightness('#447684', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#d86700', "fc" => "#ffffff", "ac" => adjustBrightness('#d86700', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#643c07', "fc" => "#ffffff", "ac" => adjustBrightness('#643c07', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#ff3f3f', "fc" => "#ffffff", "ac" => adjustBrightness('#ff3f3f', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#ffa395', "fc" => "#222222", "ac" => adjustBrightness('#ffa395', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#6450ff', "fc" => "#ffffff", "ac" => adjustBrightness('#6450ff', 180) . 'aa'],
|
|
|
|
+ ["bc" => '#8ec7f4', "fc" => "#222222", "ac" => adjustBrightness('#8ec7f4', 180) . 'aa'],
|
|
|
|
+ ];
|
|
|
|
+ ?>
|
|
|
|
+
|
|
|
|
+ <link href="/select2/select2.min.css" rel="stylesheet" />
|
|
|
|
+ <script src="/select2/select2.min.js"></script>
|
|
|
|
+ <div id="ticketsApp" v-cloak>
|
|
|
|
+ <div class="d-flex align-items-end pb-0">
|
|
|
|
+ <h4 class="font-weight-bold m-0 font-size-14">Tickets</h4>
|
|
|
|
+ <select class="ml-auto max-width-300px form-control form-control-sm pr-2"
|
|
|
|
+ v-model="statusFilter">
|
|
|
|
+ <option value="open">Open tickets (@{{ numOpen }})</option>
|
|
|
|
+ <option value="closed">Closed tickets (@{{ numClosed }})</option>
|
|
|
|
+ <option value="all">All tickets (@{{ numAll }})</option>
|
|
|
|
+ </select>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ @include('app.patient.tickets.erx')
|
|
|
|
+ @include('app.patient.tickets.lab')
|
|
|
|
+ @include('app.patient.tickets.imaging')
|
|
|
|
+ @include('app.patient.tickets.equipment')
|
|
|
|
+
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <script>
|
|
|
|
+ (function() {
|
|
|
|
+ const debounce = (func, delay) => {
|
|
|
|
+ let debounceTimer
|
|
|
|
+ return function() {
|
|
|
|
+ const context = this
|
|
|
|
+ const args = arguments
|
|
|
|
+ clearTimeout(debounceTimer)
|
|
|
|
+ debounceTimer
|
|
|
|
+ = setTimeout(() => func.apply(context, args), delay)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ <?php
|
|
|
|
+ $tickets = $patient->tickets;
|
|
|
|
+
|
|
|
|
+ $ticketsByType = [
|
|
|
|
+ "erx" => [],
|
|
|
|
+ "lab" => [],
|
|
|
|
+ "imaging" => [],
|
|
|
|
+ "equipment" => [],
|
|
|
|
+ ];
|
|
|
|
+
|
|
|
|
+ $ticketsArray = [];
|
|
|
|
+ foreach ($tickets as $ticket) {
|
|
|
|
+ $ticket->data = json_decode($ticket->data);
|
|
|
|
+ $ticket->created_at = friendly_date_time($ticket->created_at);
|
|
|
|
+ $ticket->assignedPro;
|
|
|
|
+ $ticket->managerPro;
|
|
|
|
+ $ticket->orderingPro;
|
|
|
|
+ $ticket->initiatingPro;
|
|
|
|
+ $ticketsByType[$ticket->category][] = $ticket;
|
|
|
|
+ $ticketsArray[] = $ticket;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $reportsArray = [];
|
|
|
|
+ foreach ($patient->incomingReports as $report) {
|
|
|
|
+ $report->created_at = friendly_date_time($report->created_at);
|
|
|
|
+ $report->hcp;
|
|
|
|
+ $reportsArray[] = $report;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $allProsFlat = [];
|
|
|
|
+ $paletteIndex = 0;
|
|
|
|
+ foreach ($allPros as $allPro) {
|
|
|
|
+ $allPro->displayedName = $allPro->displayName();
|
|
|
|
+ $allPro->displayedInitials = $allPro->initials();
|
|
|
|
+ $allProsFlat["pro_" . $allPro->id] = $allPro;
|
|
|
|
+ $allProsFlat["pro_" . $allPro->id]['colors'] = $palette[$paletteIndex++];
|
|
|
|
+ if($paletteIndex >= count($palette)) $paletteIndex = 0;
|
|
|
|
+ }
|
|
|
|
+ ?>
|
|
|
|
+ function init() {
|
|
|
|
+ window.ticketsApp = new Vue({
|
|
|
|
+ el: '#ticketsApp',
|
|
|
|
+ delimiters: ['@{{', '}}'],
|
|
|
|
+ data: {
|
|
|
|
+
|
|
|
|
+ own_pro_id: {{ $pro->id }},
|
|
|
|
+
|
|
|
|
+ tickets: {!! json_encode($ticketsArray) !!},
|
|
|
|
+ ticketsByType: {!! json_encode($ticketsByType) !!},
|
|
|
|
+
|
|
|
|
+ statusFilter: 'open',
|
|
|
|
+
|
|
|
|
+ // category specific fields
|
|
|
|
+ @include('app.patient.tickets.erx-data')
|
|
|
|
+ @include('app.patient.tickets.lab-data')
|
|
|
|
+ @include('app.patient.tickets.imaging-data')
|
|
|
|
+ @include('app.patient.tickets.equipment-data')
|
|
|
|
+
|
|
|
|
+ // common
|
|
|
|
+ currentCategory: '',
|
|
|
|
+ currentItemUid: '',
|
|
|
|
+ allPros: {!! json_encode($allPros) !!},
|
|
|
|
+ allProsFlat: {!! json_encode($allProsFlat) !!},
|
|
|
|
+ proToUpdate: '',
|
|
|
|
+ proTypes: ['Assigned', 'Manager', 'Initiating', 'Ordering'],
|
|
|
|
+ newProUid: '',
|
|
|
|
+ reloading: false,
|
|
|
|
+ comment: '',
|
|
|
|
+ preparing: false,
|
|
|
|
+ reports: {!! json_encode($reportsArray) !!},
|
|
|
|
+ addingReport: false,
|
|
|
|
+
|
|
|
|
+ // debounced auto-saver
|
|
|
|
+ <?php for ($i=0; $i<count($categories); $i++) { ?>
|
|
|
|
+ {{ $categories[$i] }}AutoSave: null,
|
|
|
|
+ <?php } ?>
|
|
|
|
+ },
|
|
|
|
+ computed: {
|
|
|
|
+ numAll: function() {
|
|
|
|
+ return this.tickets.length;
|
|
|
|
+ },
|
|
|
|
+ numOpen: function() {
|
|
|
|
+ return this.tickets.filter(_x => _x.is_open).length;
|
|
|
|
+ },
|
|
|
|
+ numClosed: function() {
|
|
|
|
+ return this.tickets.filter(_x => !_x.is_open).length;
|
|
|
|
+ },
|
|
|
|
+ <?php for ($i=0; $i<count($categories); $i++) { ?>
|
|
|
|
+ {{ $categories[$i] }}NumAll: function() {
|
|
|
|
+ return this.ticketsByType.{{ $categories[$i] }}.length;
|
|
|
|
+ },
|
|
|
|
+ {{ $categories[$i] }}NumOpen: function() {
|
|
|
|
+ return this.ticketsByType.{{ $categories[$i] }}.filter(_x => _x.is_open).length;
|
|
|
|
+ },
|
|
|
|
+ {{ $categories[$i] }}NumClosed: function() {
|
|
|
|
+ return this.ticketsByType.{{ $categories[$i] }}.filter(_x => !_x.is_open).length;
|
|
|
|
+ },
|
|
|
|
+ {{ $categories[$i] }}CurrentItemData: function() {
|
|
|
|
+ return this.{{ $categories[$i] }}PopupItem.data;
|
|
|
|
+ },
|
|
|
|
+ <?php } ?>
|
|
|
|
+ },
|
|
|
|
+ watch: {
|
|
|
|
+ <?php for ($i=0; $i<count($categories); $i++) { ?>
|
|
|
|
+ {{ $categories[$i] }}CurrentItemData: { // ex: erxCurrentItemData, labCurrentItemData, etc.
|
|
|
|
+ handler: function(val, oldVal) {
|
|
|
|
+ if (this.{{ $categories[$i] }}PopupMode !== 'edit' || !this.currentItemUid || this.reloading) return;
|
|
|
|
+ this.{{ $categories[$i] }}AutoSave();
|
|
|
|
+ },
|
|
|
|
+ deep: true
|
|
|
|
+ },
|
|
|
|
+ <?php } ?>
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+
|
|
|
|
+ // common show popup
|
|
|
|
+ preparePopup: function(_type, _item) {
|
|
|
|
+ this.preparing = true;
|
|
|
|
+ this[_type + 'PopupMode'] = _item ? 'edit' : 'add';
|
|
|
|
+ this[_type + 'PopupItem'] = _item ? JSON.parse(JSON.stringify(_item)) : JSON.parse(JSON.stringify(this[_type + 'Model']));
|
|
|
|
+ this[_type + 'PopupItem'].assigned_pro_uid = '';
|
|
|
|
+ this[_type + 'PopupItem'].ordering_pro_uid = '';
|
|
|
|
+ if(!this[_type + 'PopupItem'].data.comments) {
|
|
|
|
+ this[_type + 'PopupItem'].data.comments = [];
|
|
|
|
+ }
|
|
|
|
+ else if(this[_type + 'PopupItem'].data.comments.length === 1 && !this[_type + 'PopupItem'].data.comments[0].pro_id) {
|
|
|
|
+ this[_type + 'PopupItem'].data.comments = [];
|
|
|
|
+ }
|
|
|
|
+ this.comment = '';
|
|
|
|
+ this.preparing = false;
|
|
|
|
+ },
|
|
|
|
+ reinitProSuggest: function() {
|
|
|
|
+ $('#ticketsApp [pro-suggest-initialized]').removeAttr('pro-suggest-initialized');
|
|
|
|
+ initProSuggest();
|
|
|
|
+ },
|
|
|
|
+ postShowPopup: function(_type, _item) {
|
|
|
|
+ if (_item) {
|
|
|
|
+ this.currentCategory = _type;
|
|
|
|
+ this.currentItemUid = _item.uid;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // category specific show popup
|
|
|
|
+ erxShowPopup: function(_item) {
|
|
|
|
+ this.preparePopup('erx', _item);
|
|
|
|
+ Vue.nextTick(() => {
|
|
|
|
+ showStagPopup('erx-popup', true);
|
|
|
|
+ this.reinitProSuggest();
|
|
|
|
+ this.postShowPopup('erx', _item);
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ labShowPopup: function(_item) {
|
|
|
|
+ this.preparePopup('lab', _item);
|
|
|
|
+ Vue.nextTick(() => {
|
|
|
|
+ showStagPopup('lab-popup', true);
|
|
|
|
+ this.reinitProSuggest();
|
|
|
|
+ this.labInitICDAutoSuggest();
|
|
|
|
+ this.postShowPopup('lab', _item);
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ imagingShowPopup: function(_item) {
|
|
|
|
+ this.preparePopup('imaging', _item);
|
|
|
|
+ Vue.nextTick(() => {
|
|
|
|
+ showStagPopup('imaging-popup', true);
|
|
|
|
+ this.reinitProSuggest();
|
|
|
|
+ this.imagingInitICDAutoSuggest();
|
|
|
|
+ this.postShowPopup('imaging', _item);
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ equipmentShowPopup: function(_item) {
|
|
|
|
+ this.preparePopup('equipment', _item);
|
|
|
|
+ Vue.nextTick(() => {
|
|
|
|
+ showStagPopup('equipment-popup', true);
|
|
|
|
+ this.reinitProSuggest();
|
|
|
|
+ this.postShowPopup('equipment', _item);
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ erxSavePopupItem: function(_autoSave = false) {
|
|
|
|
+ let form = $('#ticketsApp [stag-popup-key="erx-popup"] form').first();
|
|
|
|
+ if(!_autoSave) {
|
|
|
|
+ if(!form[0].checkValidity()) {
|
|
|
|
+ form[0].reportValidity();
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if(!_autoSave) showMask();
|
|
|
|
+ let payload = {};
|
|
|
|
+ if(this.erxPopupMode === 'add') {
|
|
|
|
+ payload.clientUid = '{{ $patient->uid }}';
|
|
|
|
+ payload.category = 'erx';
|
|
|
|
+ payload.assignedProUid = '{{ $pro->uid }}';
|
|
|
|
+ payload.managerProUid = '{{ $pro->uid }}';
|
|
|
|
+ payload.orderingProUid = '{{ $pro->uid }}';
|
|
|
|
+ payload.initiatingProUid = '{{ $pro->uid }}';
|
|
|
|
+ payload.data = JSON.stringify(this.erxPopupItem.data);
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ payload.uid = this.erxPopupItem.uid;
|
|
|
|
+ payload.newData = JSON.stringify(this.erxPopupItem.data);
|
|
|
|
+ }
|
|
|
|
+ $.post(
|
|
|
|
+ '/api/ticket/' + (this.erxPopupMode === 'add' ? 'create' : 'updateData'),
|
|
|
|
+ payload,
|
|
|
|
+ (_data) => {
|
|
|
|
+ console.log(_data);
|
|
|
|
+ if(!_autoSave) {
|
|
|
|
+ fastReload();
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ this.reloadPopupItem('erx');
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ 'json');
|
|
|
|
+ return false;
|
|
|
|
+ },
|
|
|
|
+ erxSaveComment: function() {
|
|
|
|
+ if(!this.comment) return;
|
|
|
|
+ let comment = {
|
|
|
|
+ pro_id: this.own_pro_id,
|
|
|
|
+ created_at: new Date().toLocaleString(),
|
|
|
|
+ message: this.comment
|
|
|
|
+ };
|
|
|
|
+ if(!this.erxPopupItem.data.comments) {
|
|
|
|
+ this.erxPopupItem.data.comments = [];
|
|
|
|
+ }
|
|
|
|
+ this.erxPopupItem.data.comments.push(comment);
|
|
|
|
+ this.erxSavePopupItem(true);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ labSavePopupItem: function(_autoSave = false) {
|
|
|
|
+ let form = $('#ticketsApp [stag-popup-key="lab-popup"] form').first();
|
|
|
|
+ if(!form[0].checkValidity()) {
|
|
|
|
+ if(!_autoSave) form[0].reportValidity();
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ if(!_autoSave) showMask();
|
|
|
|
+ let payload = {};
|
|
|
|
+ if(this.labPopupMode === 'add') {
|
|
|
|
+ payload.clientUid = '{{ $patient->uid }}';
|
|
|
|
+ payload.category = 'lab';
|
|
|
|
+ payload.assignedProUid = '{{ $pro->uid }}';
|
|
|
|
+ payload.managerProUid = '{{ $pro->uid }}';
|
|
|
|
+ payload.orderingProUid = '{{ $pro->uid }}';
|
|
|
|
+ payload.initiatingProUid = '{{ $pro->uid }}';
|
|
|
|
+ payload.data = JSON.stringify(this.labPopupItem.data);
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ payload.uid = this.labPopupItem.uid;
|
|
|
|
+ payload.newData = JSON.stringify(this.labPopupItem.data);
|
|
|
|
+ }
|
|
|
|
+ $.post(
|
|
|
|
+ '/api/ticket/' + (this.labPopupMode === 'add' ? 'create' : 'updateData'),
|
|
|
|
+ payload,
|
|
|
|
+ (_data) => {
|
|
|
|
+ console.log(_data);
|
|
|
|
+ if(!_autoSave) {
|
|
|
|
+ fastReload();
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ this.reloadPopupItem('lab');
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ 'json');
|
|
|
|
+ return false;
|
|
|
|
+ },
|
|
|
|
+ labSaveComment: function() {
|
|
|
|
+ if(!this.comment) return;
|
|
|
|
+ let comment = {
|
|
|
|
+ pro_id: this.own_pro_id,
|
|
|
|
+ created_at: new Date().toLocaleString(),
|
|
|
|
+ message: this.comment
|
|
|
|
+ };
|
|
|
|
+ if(!this.labPopupItem.data.comments) {
|
|
|
|
+ this.labPopupItem.data.comments = [];
|
|
|
|
+ }
|
|
|
|
+ this.labPopupItem.data.comments.push(comment);
|
|
|
|
+ this.labSavePopupItem(true);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ imagingSavePopupItem: function(_autoSave = false) {
|
|
|
|
+ let form = $('#ticketsApp [stag-popup-key="imaging-popup"] form').first();
|
|
|
|
+ if(!_autoSave) {
|
|
|
|
+ if(!form[0].checkValidity()) {
|
|
|
|
+ form[0].reportValidity();
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if(!_autoSave) showMask();
|
|
|
|
+ let payload = {};
|
|
|
|
+ if(this.imagingPopupMode === 'add') {
|
|
|
|
+ payload.clientUid = '{{ $patient->uid }}';
|
|
|
|
+ payload.category = 'imaging';
|
|
|
|
+ payload.assignedProUid = '{{ $pro->uid }}';
|
|
|
|
+ payload.managerProUid = '{{ $pro->uid }}';
|
|
|
|
+ payload.orderingProUid = '{{ $pro->uid }}';
|
|
|
|
+ payload.initiatingProUid = '{{ $pro->uid }}';
|
|
|
|
+ payload.data = JSON.stringify(this.imagingPopupItem.data);
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ payload.uid = this.imagingPopupItem.uid;
|
|
|
|
+ payload.newData = JSON.stringify(this.imagingPopupItem.data);
|
|
|
|
+ }
|
|
|
|
+ $.post(
|
|
|
|
+ '/api/ticket/' + (this.imagingPopupMode === 'add' ? 'create' : 'updateData'),
|
|
|
|
+ payload,
|
|
|
|
+ (_data) => {
|
|
|
|
+ console.log(_data);
|
|
|
|
+ if(!_autoSave) {
|
|
|
|
+ fastReload();
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ this.reloadPopupItem('imaging');
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ 'json');
|
|
|
|
+ return false;
|
|
|
|
+ },
|
|
|
|
+ imagingSaveComment: function() {
|
|
|
|
+ if(!this.comment) return;
|
|
|
|
+ let comment = {
|
|
|
|
+ pro_id: this.own_pro_id,
|
|
|
|
+ created_at: new Date().toLocaleString(),
|
|
|
|
+ message: this.comment
|
|
|
|
+ };
|
|
|
|
+ if(!this.imagingPopupItem.data.comments) {
|
|
|
|
+ this.imagingPopupItem.data.comments = [];
|
|
|
|
+ }
|
|
|
|
+ this.imagingPopupItem.data.comments.push(comment);
|
|
|
|
+ this.imagingSavePopupItem(true);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ equipmentSavePopupItem: function(_autoSave = false) {
|
|
|
|
+ let form = $('#ticketsApp [stag-popup-key="equipment-popup"] form').first();
|
|
|
|
+ if(!_autoSave) {
|
|
|
|
+ if(!form[0].checkValidity()) {
|
|
|
|
+ form[0].reportValidity();
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if(!_autoSave) showMask();
|
|
|
|
+ let payload = {};
|
|
|
|
+ if(this.equipmentPopupMode === 'add') {
|
|
|
|
+ payload.clientUid = '{{ $patient->uid }}';
|
|
|
|
+ payload.category = 'equipment';
|
|
|
|
+ payload.assignedProUid = '{{ $pro->uid }}';
|
|
|
|
+ payload.managerProUid = '{{ $pro->uid }}';
|
|
|
|
+ payload.orderingProUid = '{{ $pro->uid }}';
|
|
|
|
+ payload.initiatingProUid = '{{ $pro->uid }}';
|
|
|
|
+ payload.data = JSON.stringify(this.equipmentPopupItem.data);
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ payload.uid = this.equipmentPopupItem.uid;
|
|
|
|
+ payload.newData = JSON.stringify(this.equipmentPopupItem.data);
|
|
|
|
+ }
|
|
|
|
+ $.post(
|
|
|
|
+ '/api/ticket/' + (this.equipmentPopupMode === 'add' ? 'create' : 'updateData'),
|
|
|
|
+ payload,
|
|
|
|
+ (_data) => {
|
|
|
|
+ console.log(_data);
|
|
|
|
+ if(!_autoSave) {
|
|
|
|
+ fastReload();
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ this.reloadPopupItem('equipment');
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ 'json');
|
|
|
|
+ return false;
|
|
|
|
+ },
|
|
|
|
+ equipmentSaveComment: function() {
|
|
|
|
+ if(!this.comment) return;
|
|
|
|
+ let comment = {
|
|
|
|
+ pro_id: this.own_pro_id,
|
|
|
|
+ created_at: new Date().toLocaleString(),
|
|
|
|
+ message: this.comment
|
|
|
|
+ };
|
|
|
|
+ if(!this.equipmentPopupItem.data.comments) {
|
|
|
|
+ this.equipmentPopupItem.data.comments = [];
|
|
|
|
+ }
|
|
|
|
+ this.equipmentPopupItem.data.comments.push(comment);
|
|
|
|
+ this.equipmentSavePopupItem(true);
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // common
|
|
|
|
+ reloadPopupItem: function(_type, _close = false) {
|
|
|
|
+ this.reloading = true;
|
|
|
|
+ $.get('/get-ticket/' + this[_type + 'PopupItem'].uid, (_data) => {
|
|
|
|
+ this[_type + 'PopupItem'] = _data;
|
|
|
|
+
|
|
|
|
+ // also update in main list
|
|
|
|
+ for (let i=0; i < this.ticketsByType[_type].length; i++) {
|
|
|
|
+ if (this.ticketsByType[_type][i].uid === this[_type + 'PopupItem'].uid) {
|
|
|
|
+ this.ticketsByType[_type].splice(i, 1, _data);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Vue.nextTick(() => {
|
|
|
|
+ this.reloading = false;
|
|
|
|
+ if(_close) {
|
|
|
|
+ closeStagPopup();
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ }, 'json');
|
|
|
|
+ },
|
|
|
|
+ closeItem: function(_item) {
|
|
|
|
+ $.post('/api/ticket/close', {
|
|
|
|
+ uid: _item.uid
|
|
|
|
+ }, (_data) => {
|
|
|
|
+ this.reloadPopupItem(this.currentCategory, true);
|
|
|
|
+ }, 'json');
|
|
|
|
+ },
|
|
|
|
+ openItem: function(_item) {
|
|
|
|
+ $.post('/api/ticket/open', {
|
|
|
|
+ uid: _item.uid
|
|
|
|
+ }, (_data) => {
|
|
|
|
+ this.reloadPopupItem(this.currentCategory);
|
|
|
|
+ }, 'json');
|
|
|
|
+ },
|
|
|
|
+ signAsOrderingPro: function(_item) {
|
|
|
|
+ $.post('/api/ticket/signAsOrderingPro', {
|
|
|
|
+ uid: _item.uid
|
|
|
|
+ }, (_data) => {
|
|
|
|
+ this.reloadPopupItem(this.currentCategory);
|
|
|
|
+ }, 'json');
|
|
|
|
+ },
|
|
|
|
+ undoSignAsOrderingPro: function(_item) {
|
|
|
|
+ $.post('/api/ticket/undoSignAsOrderingPro', {
|
|
|
|
+ uid: _item.uid
|
|
|
|
+ }, (_data) => {
|
|
|
|
+ this.reloadPopupItem(this.currentCategory);
|
|
|
|
+ }, 'json');
|
|
|
|
+ },
|
|
|
|
+ toggleAddingReport: function() {
|
|
|
|
+ this.addingReport = !this.addingReport;
|
|
|
|
+ Vue.nextTick(() => {
|
|
|
|
+ if(this.addingReport) {
|
|
|
|
+ $('[stag-popup-key="'+ this.currentCategory +'-popup"] .adding-report-section').first()[0].scrollIntoView();
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ addReportToItem: function(_item, _report) {
|
|
|
|
+ if(!this[this.currentCategory + 'PopupItem'].data.attachments) {
|
|
|
|
+ this[this.currentCategory + 'PopupItem'].data.attachments = [];
|
|
|
|
+ }
|
|
|
|
+ this[this.currentCategory + 'PopupItem'].data.attachments.push(_report);
|
|
|
|
+ this[this.currentCategory + 'SavePopupItem'](true);
|
|
|
|
+ this.addingReport = false;
|
|
|
|
+ Vue.nextTick(() => {
|
|
|
|
+ $('[stag-popup-key="'+ this.currentCategory +'-popup"] .listing-attachments-section').first()[0].scrollIntoView();
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ removeAttachmentFromItem: function(_item, _attachment) {
|
|
|
|
+ if(!this[this.currentCategory + 'PopupItem'].data.attachments) {
|
|
|
|
+ this[this.currentCategory + 'PopupItem'].data.attachments = [];
|
|
|
|
+ }
|
|
|
|
+ this[this.currentCategory + 'PopupItem'].data.attachments =
|
|
|
|
+ this[this.currentCategory + 'PopupItem'].data.attachments.filter((_x) => {
|
|
|
|
+ return _x.uid !== _attachment.uid;
|
|
|
|
+ });
|
|
|
|
+ this[this.currentCategory + 'SavePopupItem'](true);
|
|
|
|
+ },
|
|
|
|
+ initRxAutoSuggest: function() {
|
|
|
|
+ let self = this;
|
|
|
|
+ $('#ticketsApp input[type="text"][data-field="medication"]:not([ac-initialized])').each(function() {
|
|
|
|
+ let elem = this,
|
|
|
|
+ randPart = Math.ceil(Math.random() * 1000000),
|
|
|
|
+ dynID = 'rx-' + randPart;
|
|
|
|
+ $(elem).attr('id', dynID);
|
|
|
|
+ var strengthElem = $(elem).closest('.stag-popup').find('[data-field="strength"]')[0],
|
|
|
|
+ dynStrengthsID = 'rx-' + randPart + '-strengths';
|
|
|
|
+ $(strengthElem).attr('id', dynStrengthsID);
|
|
|
|
+ $(strengthElem).attr('rx-id', dynID);
|
|
|
|
+ new window.Def.Autocompleter.Prefetch(dynStrengthsID, []);
|
|
|
|
+ new window.Def.Autocompleter.Search(dynID,
|
|
|
|
+ 'https://clinicaltables.nlm.nih.gov/api/rxterms/v3/search?ef=STRENGTHS_AND_FORMS');
|
|
|
|
+ window.Def.Autocompleter.Event.observeListSelections(dynID, function() {
|
|
|
|
+ var autocomp = elem.autocomp, acData = autocomp.getSelectedItemData();
|
|
|
|
+ var strengths = acData[0].data['STRENGTHS_AND_FORMS'];
|
|
|
|
+ if (strengths) {
|
|
|
|
+ strengthElem.autocomp.setListAndField(strengths, '');
|
|
|
|
+ }
|
|
|
|
+ self.erxPopupItem.data.medication = $(elem).val();
|
|
|
|
+ });
|
|
|
|
+ window.Def.Autocompleter.Event.observeListSelections(dynStrengthsID, function() {
|
|
|
|
+ var autocomp = elem.autocomp, acData = autocomp.getSelectedItemData();
|
|
|
|
+ self.erxPopupItem.data.strength = $(strengthElem).val();
|
|
|
|
+ });
|
|
|
|
+ $(elem).attr('ac-initialized', 1);
|
|
|
|
+ $(strengthElem).attr('ac-initialized', 1);
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ labAddICD: function() {
|
|
|
|
+ this.labPopupItem.data.icds.push('');
|
|
|
|
+ Vue.nextTick(() => {
|
|
|
|
+ this.labInitICDAutoSuggest();
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ imagingAddICD: function() {
|
|
|
|
+ this.imagingPopupItem.data.icds.push('');
|
|
|
|
+ Vue.nextTick(() => {
|
|
|
|
+ this.imagingInitICDAutoSuggest();
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ erxInitICDAutoSuggest: function() {
|
|
|
|
+ let self = this;
|
|
|
|
+ $('#ticketsApp [stag-popup-key="erx-popup"] input[type="text"][data-field="icd"]:not([ac-initialized])').each(function() {
|
|
|
|
+ var elem = this,
|
|
|
|
+ dynID = 'icd-' + Math.ceil(Math.random() * 1000000),
|
|
|
|
+ vueIndex = $(this).attr('data-index');
|
|
|
|
+ $(elem).attr('id', dynID);
|
|
|
|
+ new window.Def.Autocompleter.Search(dynID,
|
|
|
|
+ 'https://clinicaltables.nlm.nih.gov/api/icd10cm/v3/search?sf=code,name&ef=name', {
|
|
|
|
+ tableFormat: true,
|
|
|
|
+ valueCols: [0],
|
|
|
|
+ colHeaders: ['Code', 'Name'],
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ window.Def.Autocompleter.Event.observeListSelections(dynID, function() {
|
|
|
|
+ let autocomp = elem.autocomp, acData = autocomp.getSelectedItemData();
|
|
|
|
+ self.erxPopupItem.data.purpose = acData[0].code + ' - ' + acData[0].data.name;
|
|
|
|
+ return false;
|
|
|
|
+ });
|
|
|
|
+ $(elem).attr('ac-initialized', 1);
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ labInitICDAutoSuggest: function() {
|
|
|
|
+ let self = this;
|
|
|
|
+ $('#ticketsApp [stag-popup-key="lab-popup"] input[type="text"][data-field="icd"]:not([ac-initialized])').each(function() {
|
|
|
|
+ var elem = this,
|
|
|
|
+ dynID = 'icd-' + Math.ceil(Math.random() * 1000000),
|
|
|
|
+ vueIndex = $(this).attr('data-index');
|
|
|
|
+ $(elem).attr('id', dynID);
|
|
|
|
+ new window.Def.Autocompleter.Search(dynID,
|
|
|
|
+ 'https://clinicaltables.nlm.nih.gov/api/icd10cm/v3/search?sf=code,name&ef=name', {
|
|
|
|
+ tableFormat: true,
|
|
|
|
+ valueCols: [0],
|
|
|
|
+ colHeaders: ['Code', 'Name'],
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ window.Def.Autocompleter.Event.observeListSelections(dynID, function() {
|
|
|
|
+ let autocomp = elem.autocomp, acData = autocomp.getSelectedItemData();
|
|
|
|
+ self.labPopupItem.data.icds[vueIndex] = acData[0].code;
|
|
|
|
+ return false;
|
|
|
|
+ });
|
|
|
|
+ $(elem).attr('ac-initialized', 1);
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ imagingInitICDAutoSuggest: function() {
|
|
|
|
+ let self = this;
|
|
|
|
+ $('#ticketsApp [stag-popup-key="imaging-popup"] input[type="text"][data-field="icd"]:not([ac-initialized])').each(function() {
|
|
|
|
+ var elem = this,
|
|
|
|
+ dynID = 'icd-' + Math.ceil(Math.random() * 1000000),
|
|
|
|
+ vueIndex = $(this).attr('data-index');
|
|
|
|
+ $(elem).attr('id', dynID);
|
|
|
|
+ new window.Def.Autocompleter.Search(dynID,
|
|
|
|
+ 'https://clinicaltables.nlm.nih.gov/api/icd10cm/v3/search?sf=code,name&ef=name', {
|
|
|
|
+ tableFormat: true,
|
|
|
|
+ valueCols: [0],
|
|
|
|
+ colHeaders: ['Code', 'Name'],
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ window.Def.Autocompleter.Event.observeListSelections(dynID, function() {
|
|
|
|
+ let autocomp = elem.autocomp, acData = autocomp.getSelectedItemData();
|
|
|
|
+ self.imagingPopupItem.data.icds[vueIndex] = acData[0].code;
|
|
|
|
+ return false;
|
|
|
|
+ });
|
|
|
|
+ $(elem).attr('ac-initialized', 1);
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ initDomElementEvents: function() {
|
|
|
|
+ let self = this;
|
|
|
|
+ $(document).off('pro-changed', '#ticketsApp select[provider-search]')
|
|
|
|
+ $(document).on('pro-changed', '#ticketsApp select[provider-search]', function() {
|
|
|
|
+ console.log('ALIX pro-changed', $(this).attr('data-field'), $(this).val());
|
|
|
|
+ if(!!$(this).val()) {
|
|
|
|
+ self[self.currentCategory + 'PopupItem'][$(this).attr('data-field')] = $(this).val();
|
|
|
|
+
|
|
|
|
+ // save
|
|
|
|
+ let proType = '';
|
|
|
|
+ switch($(this).attr('data-field')) {
|
|
|
|
+ case 'assigned_pro_uid':
|
|
|
|
+ proType = 'Assigned';
|
|
|
|
+ break;
|
|
|
|
+ case 'ordering_pro_uid':
|
|
|
|
+ proType = 'Ordering';
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ if (proType) {
|
|
|
|
+ $.post('/api/ticket/update' + proType + 'Pro', {
|
|
|
|
+ uid: self[self.currentCategory + 'PopupItem'].uid,
|
|
|
|
+ newProUid: $(this).val()
|
|
|
|
+ }, function(_data) {
|
|
|
|
+ if (!self.hasError(_data)) {
|
|
|
|
+ // toastr.success(proType + ' pro updated');
|
|
|
|
+ self.reloadPopupItem(self.currentCategory);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ $(document).off('stag-popup-closed')
|
|
|
|
+ $(document).on('stag-popup-closed', function() {
|
|
|
|
+ self.currentItemUid = '';
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ $('input.date-input')
|
|
|
|
+ .datepicker({
|
|
|
|
+ autoclose: true,
|
|
|
|
+ todayHighlight: true,
|
|
|
|
+ format: 'yyyy-mm-dd'
|
|
|
|
+ })
|
|
|
|
+ .off('changeDate')
|
|
|
|
+ .on('changeDate', function() {
|
|
|
|
+ self[self.currentCategory + 'PopupItem'].data.due_date = $(this).val();
|
|
|
|
+ self[self.currentCategory + 'SavePopupItem'].call(self, true);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ $(document).off('focus', '#ticketsApp input.form-control');
|
|
|
|
+ $(document).on('focus', '#ticketsApp input.form-control', function() {
|
|
|
|
+ $(this).select();
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ inWords: function (num) {
|
|
|
|
+ try {
|
|
|
|
+ num = +num;
|
|
|
|
+ var a = ['','one ','two ','three ','four ', 'five ','six ','seven ','eight ','nine ','ten ','eleven ','twelve ','thirteen ','fourteen ','fifteen ','sixteen ','seventeen ','eighteen ','nineteen '];
|
|
|
|
+ var b = ['', '', 'twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'];
|
|
|
|
+ if ((num = num.toString()).length > 3) return 'overflow';
|
|
|
|
+ let n = ('000000000' + num).substr(-9).match(/^(\d{2})(\d{2})(\d{2})(\d{1})(\d{2})$/);
|
|
|
|
+ if (!n) return; var str = '';
|
|
|
|
+ str += (n[1] != 0) ? (a[Number(n[1])] || b[n[1][0]] + ' ' + a[n[1][1]]) + 'crore ' : '';
|
|
|
|
+ str += (n[2] != 0) ? (a[Number(n[2])] || b[n[2][0]] + ' ' + a[n[2][1]]) + 'lakh ' : '';
|
|
|
|
+ str += (n[3] != 0) ? (a[Number(n[3])] || b[n[3][0]] + ' ' + a[n[3][1]]) + 'thousand ' : '';
|
|
|
|
+ str += (n[4] != 0) ? (a[Number(n[4])] || b[n[4][0]] + ' ' + a[n[4][1]]) + 'hundred ' : '';
|
|
|
|
+ str += (n[5] != 0) ? ((str != '') ? 'and ' : '') + (a[Number(n[5])] || b[n[5][0]] + ' ' + a[n[5][1]]) : '';
|
|
|
|
+ return str ? '(' + $.trim(str) + ')' : '';
|
|
|
|
+ }
|
|
|
|
+ catch (e) {
|
|
|
|
+ return '';
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ pharmacy: function(_item) {
|
|
|
|
+ return [
|
|
|
|
+ _item.pharmacyName,
|
|
|
|
+ _item.pharmacyCity,
|
|
|
|
+ /*_item.pharmacyState,
|
|
|
|
+ _item.pharmacyAddressMemo,
|
|
|
|
+ _item.pharmacyPhone,
|
|
|
|
+ _item.pharmacyFax,*/
|
|
|
|
+ ].filter(Boolean).join(', ');
|
|
|
|
+ },
|
|
|
|
+ @include('app.patient.tickets.pharmacy-suggest')
|
|
|
|
+ @include('app.patient.tickets.ticket_vue_methods')
|
|
|
|
+ },
|
|
|
|
+ mounted: function () {
|
|
|
|
+ this.initRxAutoSuggest();
|
|
|
|
+ this.erxInitICDAutoSuggest();
|
|
|
|
+ this.labInitICDAutoSuggest();
|
|
|
|
+ this.initPharmacySearch();
|
|
|
|
+ this.initDomElementEvents();
|
|
|
|
+
|
|
|
|
+ <?php for ($i=0; $i<count($categories); $i++) { ?>
|
|
|
|
+ this.{{ $categories[$i] }}AutoSave = debounce(() => {
|
|
|
|
+ this.{{ $categories[$i] }}SavePopupItem(true);
|
|
|
|
+ }, 1000);
|
|
|
|
+ <?php } ?>
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ addMCInitializer('patient-tickets', init, '#ticketsApp');
|
|
|
|
+ })();
|
|
|
|
+ </script>
|
|
|
|
+
|
|
|
|
+@endsection
|