Merge branch 'create_episode_inpatient' into 'development'

Create episode inpatient

See merge request Cloud_Solution/doctor_app_flutter!816
merge-requests/817/merge
Mohammad Aljammal 4 years ago
commit 382d6935ba

@ -5,8 +5,8 @@ const ONLY_NUMBERS = "[0-9]";
const ONLY_LETTERS = "[a-zA-Z &'\"]";
const ONLY_DATE = "[0-9/]";
const BASE_URL_LIVE_CARE = 'https://livecare.hmg.com/';
const BASE_URL = 'https://hmgwebservices.com/';
// const BASE_URL = 'https://uat.hmgwebservices.com/';
// const BASE_URL = 'https://hmgwebservices.com/';
const BASE_URL = 'https://uat.hmgwebservices.com/';
const PHARMACY_ITEMS_URL = "Services/Lists.svc/REST/GetPharmcyItems_Region_enh";
const PHARMACY_LIST_URL = "Services/Patients.svc/REST/GetPharmcyList";
const PATIENT_PROGRESS_NOTE_URL = "Services/DoctorApplication.svc/REST/GetProgressNoteForInPatient";
@ -134,6 +134,7 @@ const GET_ALLERGIES = 'Services/DoctorApplication.svc/REST/GetAllergies';
const GET_MASTER_LOOKUP_LIST = 'Services/DoctorApplication.svc/REST/GetMasterLookUpList';
const POST_EPISODE = 'Services/DoctorApplication.svc/REST/PostEpisode';
const POST_EPISODE_FOR_IN_PATIENT = 'Services/DoctorApplication.svc/REST/PostEpisodeForInpatient';
const POST_ALLERGY = 'Services/DoctorApplication.svc/REST/PostAllergies';
const POST_HISTORY = 'Services/DoctorApplication.svc/REST/PostHistory';
@ -239,6 +240,7 @@ const REMOVE_PATIENT_FROM_DOCTOR = "LiveCareApi/DoctorApp/BackPatientToQueue";
const CREATE_DOCTOR_RESPONSE = "Services/DoctorApplication.svc/REST/CreateDoctorResponse";
const GET_DOCTOR_NOT_REPLIED_COUNTS = "Services/DoctorApplication.svc/REST/DoctorApp_GetDoctorNotRepliedCounts";
const ALL_SPECIAL_LAB_RESULT = "services/Patients.svc/REST/GetPatientLabSpecialResultsALL";
const GET_EPISODE_FOR_INPATIENT = "/Services/DoctorApplication.svc/REST/DoctorApp_GetEpisodeForInpatient";
var selectedPatientType = 1;

@ -14,6 +14,8 @@ import 'package:doctor_app_flutter/models/SOAP/GetPhysicalExamReqModel.dart';
import 'package:doctor_app_flutter/models/SOAP/PatchAssessmentReqModel.dart';
import 'package:doctor_app_flutter/models/SOAP/PostEpisodeReqModel.dart';
import 'package:doctor_app_flutter/models/SOAP/get_Allergies_request_model.dart';
import 'package:doctor_app_flutter/models/SOAP/in_patient/GetEpisodeForInpatientReqModel.dart';
import 'package:doctor_app_flutter/models/SOAP/in_patient/PostEpisodeForInpatientRequestModel.dart';
import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart';
import 'package:doctor_app_flutter/models/SOAP/post_allergy_request_model.dart';
import 'package:doctor_app_flutter/models/SOAP/post_assessment_request_model.dart';
@ -63,6 +65,18 @@ class SOAPService extends LookupService {
}, body: postEpisodeReqModel.toJson());
}
Future postEpisodeForInPatient(PostEpisodeForInpatientRequestModel postEpisodeForInpatientRequestModel) async {
hasError = false;
await baseAppClient.post(POST_EPISODE_FOR_IN_PATIENT,
onSuccess: (dynamic response, int statusCode) {
episodeID = response['EpisodeID'];
}, onFailure: (String error, int statusCode) {
hasError = true;
super.error = error;
}, body: postEpisodeForInpatientRequestModel.toJson());
}
Future postAllergy(PostAllergyRequestModel postAllergyRequestModel) async {
hasError = false;
@ -302,4 +316,19 @@ class SOAPService extends LookupService {
super.error = error;
}, body: getAssessmentReqModel.toJson());
}
Future getEpisodeForInpatient(
GetEpisodeForInpatientReqModel getEpisodeForInpatientReqModel) async {
hasError = false;
await baseAppClient.post(GET_EPISODE_FOR_INPATIENT,
onSuccess: (dynamic response, int statusCode) {
print("Success");
episodeID = response["GetEpisodeNo"];
}, onFailure: (String error, int statusCode) {
hasError = true;
super.error = error;
}, body: getEpisodeForInpatientReqModel.toJson());
}
}

@ -19,6 +19,8 @@ import 'package:doctor_app_flutter/models/SOAP/GetPhysicalExamReqModel.dart';
import 'package:doctor_app_flutter/models/SOAP/PatchAssessmentReqModel.dart';
import 'package:doctor_app_flutter/models/SOAP/PostEpisodeReqModel.dart';
import 'package:doctor_app_flutter/models/SOAP/get_Allergies_request_model.dart';
import 'package:doctor_app_flutter/models/SOAP/in_patient/GetEpisodeForInpatientReqModel.dart';
import 'package:doctor_app_flutter/models/SOAP/in_patient/PostEpisodeForInpatientRequestModel.dart';
import 'package:doctor_app_flutter/models/SOAP/master_key_model.dart';
import 'package:doctor_app_flutter/models/SOAP/post_allergy_request_model.dart';
import 'package:doctor_app_flutter/models/SOAP/post_assessment_request_model.dart';
@ -89,56 +91,64 @@ class SOAPViewModel extends BaseViewModel {
List<GetAssessmentResModel> get patientAssessmentList =>
_SOAPService.patientAssessmentList;
int get episodeID => _SOAPService.episodeID;
bool isAddProgress = true;
bool isAddExamInProgress = true;
String progressNoteText ="";
String progressNoteText = "";
String complaintsControllerError = '';
String medicationControllerError = '';
String illnessControllerError = '';
get medicationStrengthList => _SOAPService.medicationStrengthListWithModel;
get medicationDoseTimeList => _SOAPService.medicationDoseTimeListWithModel;
get medicationRouteList => _SOAPService.medicationRouteListWithModel;
get medicationFrequencyList => _SOAPService.medicationFrequencyListWithModel;
List<GetMedicationResponseModel> get allMedicationList =>
_prescriptionService.allMedicationList;
SubjectiveCallBack subjectiveCallBack;
setSubjectiveCallBack(SubjectiveCallBack callBack)
{
setSubjectiveCallBack(SubjectiveCallBack callBack) {
this.subjectiveCallBack = callBack;
}
nextOnSubjectPage(model){
nextOnSubjectPage(model) {
subjectiveCallBack.nextFunction(model);
}
}
ObjectiveCallBack objectiveCallBack;
setObjectiveCallBack(ObjectiveCallBack callBack)
{
setObjectiveCallBack(ObjectiveCallBack callBack) {
this.objectiveCallBack = callBack;
}
nextOnObjectivePage(model){
nextOnObjectivePage(model) {
objectiveCallBack.nextFunction(model);
}
AssessmentCallBack assessmentCallBack;
setAssessmentCallBack(AssessmentCallBack callBack)
{
setAssessmentCallBack(AssessmentCallBack callBack) {
this.assessmentCallBack = callBack;
}
nextOnAssessmentPage(model){
nextOnAssessmentPage(model) {
assessmentCallBack.nextFunction(model);
}
PlanCallBack planCallBack;
setPlanCallBack(PlanCallBack callBack)
{
setPlanCallBack(PlanCallBack callBack) {
this.planCallBack = callBack;
}
nextOnPlanPage(model){
nextOnPlanPage(model) {
planCallBack.nextFunction(model);
}
@ -176,6 +186,19 @@ class SOAPViewModel extends BaseViewModel {
setState(ViewState.Idle);
}
Future postEpisodeForInPatient(
PostEpisodeForInpatientRequestModel
postEpisodeForInpatientRequestModel) async {
setState(ViewState.BusyLocal);
await _SOAPService.postEpisodeForInPatient(
postEpisodeForInpatientRequestModel);
if (_SOAPService.hasError) {
error = _SOAPService.error;
setState(ViewState.ErrorLocal);
} else
setState(ViewState.Idle);
}
Future postAllergy(PostAllergyRequestModel postAllergyRequestModel) async {
setState(ViewState.BusyLocal);
await _SOAPService.postAllergy(postAllergyRequestModel);
@ -361,19 +384,22 @@ class SOAPViewModel extends BaseViewModel {
setState(ViewState.Idle);
}
Future getPatientPhysicalExam(PatiantInformtion patientInfo,
) async {
GetPhysicalExamReqModel getPhysicalExamReqModel =
GetPhysicalExamReqModel(
Future getPatientPhysicalExam(
PatiantInformtion patientInfo,
) async {
GetPhysicalExamReqModel getPhysicalExamReqModel = GetPhysicalExamReqModel(
patientMRN: patientInfo.patientMRN,
episodeID: patientInfo.episodeNo == null?"0":patientInfo.episodeNo.toString(),
appointmentNo: patientInfo.appointmentNo == null ?0:int.parse(
patientInfo.appointmentNo.toString(),
),
episodeID: patientInfo.episodeNo == null
? "0"
: patientInfo.episodeNo.toString(),
appointmentNo: patientInfo.appointmentNo == null
? 0
: int.parse(
patientInfo.appointmentNo.toString(),
),
);
if(patientInfo.admissionNo !=null &&patientInfo.admissionNo.isNotEmpty)
getPhysicalExamReqModel.admissionNo =int.parse(patientInfo.admissionNo);
if (patientInfo.admissionNo != null && patientInfo.admissionNo.isNotEmpty)
getPhysicalExamReqModel.admissionNo = int.parse(patientInfo.admissionNo);
else
getPhysicalExamReqModel.admissionNo = 0;
setState(ViewState.Busy);
@ -417,6 +443,24 @@ class SOAPViewModel extends BaseViewModel {
setState(ViewState.Idle);
}
Future getEpisodeForInpatient(PatiantInformtion patient) async {
setState(ViewState.BusyLocal);
GetEpisodeForInpatientReqModel getEpisodeForInpatientReqModel =
GetEpisodeForInpatientReqModel(
patientID: patient.patientId,
admissionNo: int.parse(patient.admissionNo),
patientTypeID: 1);
await _SOAPService.getEpisodeForInpatient(getEpisodeForInpatientReqModel);
if (_SOAPService.hasError) {
error = _SOAPService.error;
setState(ViewState.ErrorLocal);
} else {
patient.episodeNo = _SOAPService.episodeID;
setState(ViewState.Idle);
}
}
// ignore: missing_return
MasterKeyModel getOneMasterKey(
{@required MasterKeysService masterKeys, dynamic id, int typeId}) {
@ -530,14 +574,14 @@ class SOAPViewModel extends BaseViewModel {
}
}
int getFirstIndexForOldExamination(List<MySelectedExamination> mySelectedExamination){
Iterable<MySelectedExamination> examList = mySelectedExamination.where(
(element) => !element.isLocal);
int getFirstIndexForOldExamination(
List<MySelectedExamination> mySelectedExamination) {
Iterable<MySelectedExamination> examList =
mySelectedExamination.where((element) => !element.isLocal);
if (examList.length > 0) {
return mySelectedExamination.indexOf(examList.first);
} else
return -1;
}
}

@ -0,0 +1,22 @@
class GetEpisodeForInpatientReqModel {
int patientID;
int patientTypeID;
int admissionNo;
GetEpisodeForInpatientReqModel(
{this.patientID, this.patientTypeID, this.admissionNo});
GetEpisodeForInpatientReqModel.fromJson(Map<String, dynamic> json) {
patientID = json['PatientID'];
patientTypeID = json['PatientTypeID'];
admissionNo = json['AdmissionNo'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['PatientID'] = this.patientID;
data['PatientTypeID'] = this.patientTypeID;
data['AdmissionNo'] = this.admissionNo;
return data;
}
}

@ -0,0 +1,22 @@
class PostEpisodeForInpatientRequestModel {
int admissionNo;
int patientID;
int patientTypeID;
PostEpisodeForInpatientRequestModel(
{this.admissionNo, this.patientID, this.patientTypeID = 1});
PostEpisodeForInpatientRequestModel.fromJson(Map<String, dynamic> json) {
admissionNo = json['AdmissionNo'];
patientID = json['PatientID'];
patientTypeID = json['PatientTypeID'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['AdmissionNo'] = this.admissionNo;
data['PatientID'] = this.patientID;
data['PatientTypeID'] = this.patientTypeID;
return data;
}
}

@ -6,6 +6,7 @@ import 'package:doctor_app_flutter/core/service/VideoCallService.dart';
import 'package:doctor_app_flutter/core/viewModel/LiveCarePatientViewModel.dart';
import 'package:doctor_app_flutter/core/viewModel/SOAP_view_model.dart';
import 'package:doctor_app_flutter/models/SOAP/PostEpisodeReqModel.dart';
import 'package:doctor_app_flutter/models/SOAP/in_patient/PostEpisodeForInpatientRequestModel.dart';
import 'package:doctor_app_flutter/models/patient/patiant_info_model.dart';
import 'package:doctor_app_flutter/screens/base/base_view.dart';
import 'package:doctor_app_flutter/screens/live_care/end_call_screen.dart';
@ -31,7 +32,8 @@ class PatientProfileScreen extends StatefulWidget {
_PatientProfileScreenState createState() => _PatientProfileScreenState();
}
class _PatientProfileScreenState extends State<PatientProfileScreen> with SingleTickerProviderStateMixin {
class _PatientProfileScreenState extends State<PatientProfileScreen>
with SingleTickerProviderStateMixin {
PatiantInformtion patient;
LiveCarePatientViewModel _liveCareViewModel = LiveCarePatientViewModel();
@ -54,6 +56,7 @@ class _PatientProfileScreenState extends State<PatientProfileScreen> with Single
StreamController<String> videoCallDurationStreamController;
Stream<String> videoCallDurationStream = (() async* {})();
@override
void initState() {
_tabController = TabController(length: 2, vsync: this);
@ -108,15 +111,17 @@ class _PatientProfileScreenState extends State<PatientProfileScreen> with Single
}
StreamSubscription callTimer;
callConnected() {
callTimer = CountdownTimer(Duration(minutes: 90), Duration(seconds: 1)).listen(null)
..onDone(() {
callTimer.cancel();
})
..onData((data) {
var t = Helpers.timeFrom(duration: data.elapsed);
videoCallDurationStreamController.sink.add(t);
});
callTimer =
CountdownTimer(Duration(minutes: 90), Duration(seconds: 1)).listen(null)
..onDone(() {
callTimer.cancel();
})
..onData((data) {
var t = Helpers.timeFrom(duration: data.elapsed);
videoCallDurationStreamController.sink.add(t);
});
}
callDisconnected() {
@ -133,12 +138,12 @@ class _PatientProfileScreenState extends State<PatientProfileScreen> with Single
final screenSize = MediaQuery.of(context).size;
return BaseView<LiveCarePatientViewModel>(
onModelReady: (model) async {
if (isFromLiveCare && patient.patientStatus == 1) await model.addPatientToDoctorList(patient.vcId);
if (isFromLiveCare && patient.patientStatus == 1)
await model.addPatientToDoctorList(patient.vcId);
},
builder: (_, model, w) => AppScaffold(
baseViewModel: model,
isLoading: true,
appBarTitle: TranslationBase.of(context).patientProfile,
isShowAppBar: false,
body: Column(
@ -147,11 +152,13 @@ class _PatientProfileScreenState extends State<PatientProfileScreen> with Single
children: [
Column(
children: [
PatientProfileHeaderNewDesignAppBar(patient, arrivalType ?? '0', patientType,
PatientProfileHeaderNewDesignAppBar(
patient, arrivalType ?? '0', patientType,
videoCallDurationStream: videoCallDurationStream,
isInpatient: isInpatient,
isFromLiveCare: isFromLiveCare,
height: (patient.patientStatusType != null && patient.patientStatusType == 43)
height: (patient.patientStatusType != null &&
patient.patientStatusType == 43)
? 210
: isDischargedPatient
? 240
@ -183,7 +190,8 @@ class _PatientProfileScreenState extends State<PatientProfileScreen> with Single
isInpatient: isInpatient,
from: from,
to: to,
isDischargedPatient: isDischargedPatient,
isDischargedPatient:
isDischargedPatient,
isFromSearch: isFromSearch,
)
: ProfileGridForOther(
@ -204,25 +212,34 @@ class _PatientProfileScreenState extends State<PatientProfileScreen> with Single
),
],
),
if ( (isInpatient )? true:isFromLiveCare
? patient.episodeNo != null
: patient.patientStatusType != null && patient.patientStatusType == 43)
if ((isInpatient)
? true
: isFromLiveCare
? patient.episodeNo != null
: patient.patientStatusType != null &&
patient.patientStatusType == 43)
BaseView<SOAPViewModel>(
onModelReady: (model) async {
model.getDoctorProfile();
if (isInpatient) {
await model.getEpisodeForInpatient(patient);
}
},
builder: (_, model, w) => Positioned(
top: 180,
left: 20,
right: 20,
child: Row(
child: Row(
children: [
Expanded(child: Container()),
if (patient.episodeNo == 0)
AppButton(
loading: model.state== ViewState.BusyLocal,
disabled: model.state== ViewState.BusyLocal,
title:
"${TranslationBase.of(context).createNew}\n${TranslationBase.of(context).episode}",
color: isFromLiveCare ||isInpatient
color: isFromLiveCare || isInpatient
? Colors.red.shade700
: patient.patientStatusType == 43
? Colors.red.shade700
@ -239,29 +256,22 @@ class _PatientProfileScreenState extends State<PatientProfileScreen> with Single
height: 30,
),
onPressed: () async {
if ((isFromLiveCare && patient.appointmentNo != null) ||
patient.patientStatusType == 43) {
await locator<AnalyticsService>().logEvent(
eventCategory: "Patient Profile",
eventAction: "Create Episode",
);
PostEpisodeReqModel postEpisodeReqModel = PostEpisodeReqModel(
appointmentNo: int.parse(patient.appointmentNo.toString()),
patientMRN: patient.patientMRN);
GifLoaderDialogUtils.showMyDialog(context);
await model.postEpisode(postEpisodeReqModel);
GifLoaderDialogUtils.hideDialog(context);
patient.episodeNo = model.episodeID;
Navigator.of(context)
.pushNamed(CREATE_EPISODE, arguments: {'patient': patient});
if ((isFromLiveCare &&
patient.appointmentNo != null) ||
patient.patientStatusType == 43 || isInpatient ) {
createEpisode(
patient: patient, model: model);
}
},
),
if (patient.episodeNo != 0)
AppButton(
loading: model.state== ViewState.BusyLocal,
disabled: model.state== ViewState.BusyLocal,
title:
"${TranslationBase.of(context).update}\n${TranslationBase.of(context).episode}",
color: (isInpatient ) || isFromLiveCare
color: ((isInpatient) || isFromLiveCare) && model.state!= ViewState.BusyLocal
? Colors.red.shade700
: patient.patientStatusType == 43
? Colors.red.shade700
@ -278,16 +288,19 @@ class _PatientProfileScreenState extends State<PatientProfileScreen> with Single
height: 30,
),
onPressed: () async {
await locator<AnalyticsService>().logEvent(
await locator<AnalyticsService>()
.logEvent(
eventCategory: "Patient Profile ",
eventAction: "Update Episode",
);
if ((isFromLiveCare &&
patient.appointmentNo != null &&
patient.appointmentNo != 0) ||
patient.patientStatusType == 43 ||isInpatient ) {
Navigator.of(context)
.pushNamed(UPDATE_EPISODE, arguments: {'patient': patient});
patient.patientStatusType == 43 ||
isInpatient) {
Navigator.of(context).pushNamed(
UPDATE_EPISODE,
arguments: {'patient': patient});
}
}),
],
@ -319,11 +332,14 @@ class _PatientProfileScreenState extends State<PatientProfileScreen> with Single
child: Center(
child: AppButton(
fontWeight: FontWeight.w700,
color: isCallFinished ? Colors.red[600] : Colors.green[600],
color: isCallFinished
? Colors.red[600]
: Colors.green[600],
title: isCallFinished
? TranslationBase.of(context).endCall
: TranslationBase.of(context).initiateCall,
disabled: isCallStarted || model.state == ViewState.BusyLocal,
disabled: isCallStarted ||
model.state == ViewState.BusyLocal,
onPressed: () async {
// TODO MOSA TEST
// AppPermissionsUtils
@ -339,37 +355,52 @@ class _PatientProfileScreenState extends State<PatientProfileScreen> with Single
// });
if (isCallFinished) {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => EndCallScreen(patient: patient),settings: RouteSettings(name: 'EndCallScreen'),),);
context,
MaterialPageRoute(
builder: (BuildContext context) =>
EndCallScreen(patient: patient),
settings:
RouteSettings(name: 'EndCallScreen'),
),
);
} else {
GifLoaderDialogUtils.showMyDialog(context);
await model.startCall(isReCall: false, vCID: patient.vcId);
await model.startCall(
isReCall: false, vCID: patient.vcId);
if (model.state == ViewState.ErrorLocal) {
GifLoaderDialogUtils.hideDialog(context);
Helpers.showErrorToast(model.error);
} else {
await model.getDoctorProfile();
patient.appointmentNo = int.parse(model.startCallRes.appointmentNo.toString());
patient.appointmentNo = int.parse(model
.startCallRes.appointmentNo
.toString());
patient.episodeNo = 0;
model.updateInCallPatient(
patient: patient,
appointmentNo: int.parse(model.startCallRes.appointmentNo.toString()));
appointmentNo: int.parse(model
.startCallRes.appointmentNo
.toString()));
setState(() {
isCallStarted = true;
});
GifLoaderDialogUtils.hideDialog(context);
AppPermissionsUtils.requestVideoCallPermission(
context: context,
onTapGrant: () {
locator<VideoCallService>().openVideo(
model.startCallRes,
patient,
model.startCallRes != null ? model.startCallRes.isRecording : true,
callConnected,
callDisconnected);
});
AppPermissionsUtils
.requestVideoCallPermission(
context: context,
onTapGrant: () {
locator<VideoCallService>()
.openVideo(
model.startCallRes,
patient,
model.startCallRes != null
? model.startCallRes
.isRecording
: true,
callConnected,
callDisconnected);
});
}
}
},
@ -387,6 +418,36 @@ class _PatientProfileScreenState extends State<PatientProfileScreen> with Single
),
);
}
createEpisode({PatiantInformtion patient, SOAPViewModel model}) async {
await locator<AnalyticsService>().logEvent(
eventCategory: "Patient Profile",
eventAction: "Create Episode",
);
GifLoaderDialogUtils.showMyDialog(context);
if (patient.admissionNo != null && patient.admissionNo.isNotEmpty) {
PostEpisodeForInpatientRequestModel postEpisodeReqModel =
PostEpisodeForInpatientRequestModel(
admissionNo: int.parse(patient.admissionNo),
patientID: patient.patientId);
await model.postEpisodeForInPatient(postEpisodeReqModel);
} else {
PostEpisodeReqModel postEpisodeReqModel = PostEpisodeReqModel(
appointmentNo: int.parse(patient.appointmentNo.toString()),
patientMRN: patient.patientMRN);
await model.postEpisode(postEpisodeReqModel);
}
GifLoaderDialogUtils.hideDialog(context);
if (model.state == ViewState.ErrorLocal) {
Helpers.showErrorToast(model.error);
} else {
patient.episodeNo = model.episodeID;
Navigator.of(context)
.pushNamed(CREATE_EPISODE, arguments: {'patient': patient});
}
}
}
class AvatarWidget extends StatelessWidget {
@ -398,7 +459,12 @@ class AvatarWidget extends StatelessWidget {
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
boxShadow: [BoxShadow(color: Color.fromRGBO(0, 0, 0, 0.08), offset: Offset(0.0, 5.0), blurRadius: 16.0)],
boxShadow: [
BoxShadow(
color: Color.fromRGBO(0, 0, 0, 0.08),
offset: Offset(0.0, 5.0),
blurRadius: 16.0)
],
borderRadius: BorderRadius.all(Radius.circular(35.0)),
color: Color(0xffCCCCCC),
),

Loading…
Cancel
Save