Merge pull request #18 from yaso-meth/Claim-Document-Generation

Claim-Document-Generation
This commit is contained in:
yaso-meth
2024-12-04 14:06:43 +02:00
committed by GitHub
22 changed files with 2110 additions and 245 deletions

View File

@@ -0,0 +1,256 @@
import 'dart:convert';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
import 'package:Mzansi_Innovation_Hub/mih_objects/arguments.dart';
import 'package:Mzansi_Innovation_Hub/mih_objects/claim_statement_file.dart';
import 'package:flutter/material.dart';
import 'package:supertokens_flutter/http.dart' as http;
import '../mih_components/mih_pop_up_messages/mih_error_message.dart';
import '../mih_components/mih_pop_up_messages/mih_success_message.dart';
import '../mih_env/env.dart';
class MIHClaimStatementGenerationApi {
final baseAPI = AppEnviroment.baseApiUrl;
/// This function is used to generate and store a claim/ statement.
///
/// Patameters: TBC .
///
/// Returns TBC.
Future<void> generateClaimStatement(
ClaimStatementGenerationArguments data,
PatientViewArguments args,
BuildContext context,
) async {
//start loading circle
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
var response1 = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/minio/generate/claim-statement/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"document_type": data.document_type,
"patient_app_id": data.patient_app_id,
"patient_full_name": data.patient_full_name,
"patient_id_no": data.patient_id_no,
"has_med_aid": data.has_med_aid,
"med_aid_no": data.med_aid_no,
"med_aid_code": data.med_aid_code,
"med_aid_name": data.med_aid_name,
"med_aid_scheme": data.med_aid_scheme,
"busName": data.busName,
"busAddr": data.busAddr,
"busNo": data.busNo,
"busEmail": data.busEmail,
"provider_name": data.provider_name,
"practice_no": data.practice_no,
"vat_no": data.vat_no,
"service_date": data.service_date,
"service_desc": data.service_desc,
"service_desc_option": data.service_desc_option,
"procedure_name": data.procedure_name,
"procedure_additional_info": data.procedure_additional_info,
"icd10_code": data.icd10_code,
"amount": data.amount,
"pre_auth_no": data.pre_auth_no,
"logo_path": data.logo_path,
"sig_path": data.sig_path,
}),
);
//print(response1.statusCode);
DateTime now = new DateTime.now();
DateTime date = new DateTime(now.year, now.month, now.day);
String fileName =
"${data.document_type}-${data.patient_full_name}-${date.toString().substring(0, 10)}.pdf";
if (response1.statusCode == 200) {
//Update this API
var response2 = await http.post(
Uri.parse("${AppEnviroment.baseApiUrl}/files/claim-statement/insert/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"app_id": data.patient_app_id,
"business_id": args.business!.business_id,
"file_path": "${data.patient_app_id}/claims-statements/$fileName",
"file_name": fileName
}),
);
if (response2.statusCode == 201) {
// end loading circle
Navigator.of(context).pop();
Navigator.of(context).pop();
Navigator.of(context).pop();
Navigator.of(context)
.pushNamed('/patient-manager/patient', arguments: args);
String message =
"The ${data.document_type}: $fileName has been successfully generated and added to ${data.patient_full_name}'s record. You can now access and download it for their use.";
successPopUp(message, context);
} else {
internetConnectionPopUp(context);
}
} else {
internetConnectionPopUp(context);
}
}
/// This function is used to fetch a list of claim/ statement files for a ptient.
///
/// Patameters: app_id .
///
/// Returns List<ClaimStatementFile>.
static Future<List<ClaimStatementFile>> getClaimStatementFilesByPatient(
String app_id,
) async {
//print("Patien manager page: $endpoint");
final response = await http.get(Uri.parse(
"${AppEnviroment.baseApiUrl}/files/claim-statement/patient/$app_id"));
// print("Here");
// print("Body: ${response.body}");
// print("Code: ${response.statusCode}");
// errorCode = response.statusCode.toString();
// errorBody = response.body;
if (response.statusCode == 200) {
//print("Here1");
Iterable l = jsonDecode(response.body);
//print("Here2");
List<ClaimStatementFile> docList = List<ClaimStatementFile>.from(
l.map((model) => ClaimStatementFile.fromJson(model)));
//print("Here3");
//print(patientQueue);
return docList;
} else {
throw Exception(
'failed to fatch patient claims statement files with api');
}
}
/// This function is used to fetch a list of claim/ statement files for a business.
///
/// Patameters: business_id .
///
/// Returns List<ClaimStatementFile>.
static Future<List<ClaimStatementFile>> getClaimStatementFilesByBusiness(
String business_id,
) async {
//print("Patien manager page: $endpoint");
final response = await http.get(Uri.parse(
"${AppEnviroment.baseApiUrl}/files/claim-statement/business/$business_id"));
// print("Here");
// print("Body: ${response.body}");
// print("Code: ${response.statusCode}");
// errorCode = response.statusCode.toString();
// errorBody = response.body;
if (response.statusCode == 200) {
//print("Here1");
Iterable l = jsonDecode(response.body);
//print("Here2");
List<ClaimStatementFile> docList = List<ClaimStatementFile>.from(
l.map((model) => ClaimStatementFile.fromJson(model)));
//print("Here3");
//print(patientQueue);
return docList;
} else {
throw Exception(
'failed to fatch business claims statement files with api');
}
}
/// This function is used to Delete loyalty card from users mzansi wallet.
///
/// Patameters:-
/// AppUser signedInUser,
/// int idloyalty_cards,
/// BuildContext context,
///
/// Returns VOID (TRIGGERS NOTIGICATIOPN ON SUCCESS)
static Future<void> deleteClaimStatementFilesByFileID(
PatientViewArguments args,
String filePath,
int fileID,
BuildContext context,
) async {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
// delete file from minio
var response = await http.delete(
Uri.parse("${AppEnviroment.baseApiUrl}/minio/delete/file/"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{"file_path": filePath}),
);
//print("Here4");
//print(response.statusCode);
if (response.statusCode == 200) {
//SQL delete
var response2 = await http.delete(
Uri.parse("${AppEnviroment.baseApiUrl}/files/claim-statement/delete"),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{"idclaim_statement_file": fileID}),
);
if (response2.statusCode == 200) {
Navigator.of(context).pop();
Navigator.of(context).pop();
Navigator.of(context).pop();
Navigator.of(context).pop();
//print(widget.business);
Navigator.of(context)
.pushNamed('/patient-manager/patient', arguments: args);
// Navigator.of(context)
// .pushNamed('/patient-profile', arguments: widget.signedInUser);
// setState(() {});
String message =
"The File has been deleted successfully. This means it will no longer be visible on your and cannot be used for future appointments.";
successPopUp(message, context);
} else {
internetConnectionPopUp(context);
}
} else {
internetConnectionPopUp(context);
}
}
//================== POP UPS ==========================================================================
static void internetConnectionPopUp(BuildContext context) {
showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(
errorType: "Internet Connection",
);
},
);
}
static void successPopUp(String message, BuildContext context) {
showDialog(
context: context,
builder: (context) {
return MIHSuccessMessage(
successType: "Success",
successMessage: message,
);
},
);
}
}

View File

@@ -0,0 +1,55 @@
import 'dart:convert';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
import 'package:Mzansi_Innovation_Hub/mih_objects/icd10_code.dart.dart';
import 'package:flutter/material.dart';
import 'package:supertokens_flutter/http.dart' as http;
import '../mih_env/env.dart';
class MIHIcd10CodeApis {
final baseAPI = AppEnviroment.baseApiUrl;
/// This function is used to fetch a list of icd 10 codes based on a search .
///
/// Patameters: String search, BuildContext context
///
/// Returns List<ICD10Code>.
static Future<List<ICD10Code>> getIcd10Codes(
String search, BuildContext context) async {
//print("Patien manager page: $endpoint");
mihLoadingPopUp(context);
final response = await http
.get(Uri.parse("${AppEnviroment.baseApiUrl}/icd10-codes/$search"));
// print("Here");
// print("Body: ${response.body}");
// print("Code: ${response.statusCode}");
// errorCode = response.statusCode.toString();
// errorBody = response.body;
if (response.statusCode == 200) {
//print("Here1");
Iterable l = jsonDecode(response.body);
//print("Here2");
List<ICD10Code> icd10Codes =
List<ICD10Code>.from(l.map((model) => ICD10Code.fromJson(model)));
//print("Here3");
//print(patientQueue);
Navigator.of(context).pop();
return icd10Codes;
} else {
Navigator.of(context).pop();
throw Exception('failed to fetch icd-10 codes with api');
}
}
static void mihLoadingPopUp(BuildContext context) {
showDialog(
context: context,
builder: (context) {
return const Mihloadingcircle();
},
);
}
}

View File

@@ -85,7 +85,7 @@ class MIHMzansiWalletApis {
arguments: signedInUser,
);
String message =
"The note has been deleted successfully. This means it will no longer be visible on your and cannot be used for future appointments.";
"The loyalty card has been deleted successfully. This means it will no longer be visible in your Mzansi Wallet.";
successPopUp(message, context);
} else {
internetConnectionPopUp(context);
@@ -125,7 +125,7 @@ class MIHMzansiWalletApis {
// Navigator.pushNamed(context, '/patient-manager/patient',
// arguments: widget.signedInUser);
String message =
"Your $shop_name Loyalty Card was successfully added to you Mzansi Wallet.";
"Your $shop_name Loyalty Card was successfully added to your Mzansi Wallet.";
Navigator.pop(context);
Navigator.pop(context);
Navigator.of(context).pushNamed(

View File

@@ -99,3 +99,61 @@ class PatientEditArguments {
this.selectedPatient,
);
}
class ClaimStatementGenerationArguments {
final String document_type;
final String patient_app_id;
final String patient_full_name;
final String patient_id_no;
final String has_med_aid;
final String med_aid_no;
final String med_aid_code;
final String med_aid_name;
final String med_aid_scheme;
final String busName;
final String busAddr;
final String busNo;
final String busEmail;
final String provider_name;
final String practice_no;
final String vat_no;
final String service_date;
final String service_desc;
final String service_desc_option;
final String procedure_name;
final String procedure_additional_info;
final String icd10_code;
final String amount;
final String pre_auth_no;
final String logo_path;
final String sig_path;
ClaimStatementGenerationArguments(
this.document_type,
this.patient_app_id,
this.patient_full_name,
this.patient_id_no,
this.has_med_aid,
this.med_aid_no,
this.med_aid_code,
this.med_aid_name,
this.med_aid_scheme,
this.busName,
this.busAddr,
this.busNo,
this.busEmail,
this.provider_name,
this.practice_no,
this.vat_no,
this.service_date,
this.service_desc,
this.service_desc_option,
this.procedure_name,
this.procedure_additional_info,
this.icd10_code,
this.amount,
this.pre_auth_no,
this.logo_path,
this.sig_path,
);
}

View File

@@ -10,6 +10,8 @@ class Business {
final String bus_email;
final String app_id;
final String gps_location;
final String practice_no;
final String vat_no;
const Business(
this.business_id,
@@ -22,6 +24,8 @@ class Business {
this.bus_email,
this.app_id,
this.gps_location,
this.practice_no,
this.vat_no,
);
factory Business.fromJson(dynamic json) {
@@ -36,6 +40,8 @@ class Business {
json['bus_email'],
json['app_id'],
json['gps_location'],
json['practice_no'],
json['vat_no'],
);
}
}

View File

@@ -0,0 +1,40 @@
class ClaimStatementFile {
final int idclaim_statement_file;
final String app_id;
final String business_id;
final String insert_date;
final String file_path;
final String file_name;
const ClaimStatementFile({
required this.idclaim_statement_file,
required this.app_id,
required this.business_id,
required this.insert_date,
required this.file_path,
required this.file_name,
});
factory ClaimStatementFile.fromJson(Map<String, dynamic> json) {
return switch (json) {
{
"idclaim_statement_file": int idclaim_statement_file,
'app_id': String app_id,
'business_id': String business_id,
'insert_date': String insert_date,
'file_path': String file_path,
'file_name': String file_name,
} =>
ClaimStatementFile(
idclaim_statement_file: idclaim_statement_file,
app_id: app_id,
business_id: business_id,
insert_date: insert_date,
file_path: file_path,
file_name: file_name,
),
_ =>
throw const FormatException('Failed to load Claim Statement Object.'),
};
}
}

View File

@@ -0,0 +1,23 @@
class ICD10Code {
final String icd10;
final String description;
const ICD10Code({
required this.icd10,
required this.description,
});
factory ICD10Code.fromJson(Map<String, dynamic> json) {
return switch (json) {
{
"icd10": String icd10,
'description': String description,
} =>
ICD10Code(
icd10: icd10,
description: description,
),
_ => throw const FormatException('Failed to load icd10 code object.'),
};
}
}

View File

@@ -48,14 +48,13 @@ class _BusinessDetailsState extends State<BusinessDetails> {
final contactController = TextEditingController();
final emailController = TextEditingController();
final locationController = TextEditingController();
final practiceNoController = TextEditingController();
final vatNoController = TextEditingController();
late PlatformFile? selectedLogo = null;
late PlatformFile? selectedSignature = null;
// late Future<BusinessUser?> futureBusinessUser;
// BusinessUser? businessUser;
// late Future<Business?> futureBusiness;
// Business? business;
final ValueNotifier<String> busType = ValueNotifier("");
late String business_id;
late String oldLogoPath;
@@ -79,32 +78,6 @@ class _BusinessDetailsState extends State<BusinessDetails> {
}
}
// Future<BusinessUser?> getBusinessUserDetails() async {
// var response = await http
// .get(Uri.parse("$baseAPI/business-user/${widget.signedInUser.app_id}"));
// if (response.statusCode == 200) {
// String body = response.body;
// var decodedData = jsonDecode(body);
// BusinessUser business_User = BusinessUser.fromJson(decodedData);
// return business_User;
// } else {
// return null;
// }
// }
// Future<Business?> getBusinessDetails() async {
// var response = await http.get(
// Uri.parse("$baseAPI/business/app_id/${widget.signedInUser.app_id}"));
// if (response.statusCode == 200) {
// String body = response.body;
// var decodedData = jsonDecode(body);
// Business business = Business.fromJson(decodedData);
// return business;
// } else {
// return null;
// }
// }
Future<void> uploadSelectedFile(
PlatformFile? file, TextEditingController controller) async {
//to-do delete file when changed
@@ -183,6 +156,8 @@ class _BusinessDetailsState extends State<BusinessDetails> {
"contact_no": contactController.text,
"bus_email": emailController.text,
"gps_location": locationController.text,
"practice_no": practiceNoController.text,
"vat_no": vatNoController.text,
}),
);
if (response.statusCode == 200) {
@@ -275,6 +250,14 @@ class _BusinessDetailsState extends State<BusinessDetails> {
}
}
void typeSelected() {
if (typeController.text.isNotEmpty) {
busType.value = typeController.text;
} else {
busType.value = "";
}
}
@override
void dispose() {
nameController.dispose();
@@ -289,12 +272,15 @@ class _BusinessDetailsState extends State<BusinessDetails> {
contactController.dispose();
emailController.dispose();
locationController.dispose();
practiceNoController.dispose();
vatNoController.dispose();
_focusNode.dispose();
super.dispose();
}
@override
void initState() {
typeController.addListener(typeSelected);
setState(() {
//businessUser = results;
titleController.text = widget.arguments.businessUser!.title;
@@ -316,6 +302,8 @@ class _BusinessDetailsState extends State<BusinessDetails> {
contactController.text = widget.arguments.business!.contact_no;
emailController.text = widget.arguments.business!.bus_email;
locationController.text = widget.arguments.business!.gps_location;
practiceNoController.text = widget.arguments.business!.practice_no;
vatNoController.text = widget.arguments.business!.vat_no;
});
super.initState();
@@ -374,6 +362,29 @@ class _BusinessDetailsState extends State<BusinessDetails> {
editable: true,
),
const SizedBox(height: 10.0),
ValueListenableBuilder(
valueListenable: busType,
builder:
(BuildContext context, String value, Widget? child) {
return Visibility(
visible: value == "Doctors Office",
child: MIHTextField(
controller: practiceNoController,
hintText: "Practice Number",
editable: true,
required: true,
),
);
},
),
const SizedBox(height: 10.0),
MIHTextField(
controller: vatNoController,
hintText: "VAT Number",
editable: true,
required: true,
),
const SizedBox(height: 10.0),
MIHTextField(
controller: contactController,
hintText: "Contact Number",

View File

@@ -52,10 +52,14 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
final contactController = TextEditingController();
final emailController = TextEditingController();
final locationController = TextEditingController();
final practiceNoController = TextEditingController();
final vatNoController = TextEditingController();
late PlatformFile selectedLogo;
late PlatformFile selectedSignature;
final ValueNotifier<String> busType = ValueNotifier("");
Future<void> uploadSelectedFile(
PlatformFile file, TextEditingController controller) async {
var token = await SuperTokens.getAccessToken();
@@ -125,6 +129,8 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
"contact_no": contactController.text,
"bus_email": emailController.text,
"gps_location": locationController.text,
"practice_no": practiceNoController.text,
"vat_no": vatNoController.text,
}),
);
if (response.statusCode == 201) {
@@ -205,6 +211,14 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
return regex.hasMatch(text);
}
void typeSelected() {
if (typeController.text.isNotEmpty) {
busType.value = typeController.text;
} else {
busType.value = "";
}
}
MIHAction getActionButton() {
return MIHAction(
icon: const Icon(Icons.arrow_back),
@@ -281,6 +295,28 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
editable: true,
),
const SizedBox(height: 10.0),
ValueListenableBuilder(
valueListenable: busType,
builder: (BuildContext context, String value, Widget? child) {
return Visibility(
visible: value == "Doctors Office",
child: MIHTextField(
controller: practiceNoController,
hintText: "Practice Number",
editable: true,
required: true,
),
);
},
),
const SizedBox(height: 10.0),
MIHTextField(
controller: vatNoController,
hintText: "VAT Number",
editable: true,
required: true,
),
const SizedBox(height: 10.0),
MIHTextField(
controller: contactController,
hintText: "Contact Number",
@@ -462,12 +498,15 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
contactController.dispose();
emailController.dispose();
locationController.dispose();
practiceNoController.dispose();
vatNoController.dispose();
_focusNode.dispose();
super.dispose();
}
@override
void initState() {
typeController.addListener(typeSelected);
setState(() {
fnameController.text = widget.signedInUser.fname;
lnameController.text = widget.signedInUser.lname;
@@ -489,197 +528,5 @@ class _ProfileBusinessAddState extends State<ProfileBusinessAdd> {
pullDownToRefresh: false,
onPullDown: () async {},
);
// return Scaffold(
// // appBar: const MIHAppBar(
// // barTitle: "Add Business",
// // propicFile: null,
// // ),
// //drawer: MIHAppDrawer(signedInUser: widget.signedInUser),
// body: SafeArea(
// child: Stack(
// children: [
// KeyboardListener(
// focusNode: _focusNode,
// autofocus: true,
// onKeyEvent: (event) async {
// if (event is KeyDownEvent &&
// event.logicalKey == LogicalKeyboardKey.enter) {
// submitForm();
// }
// },
// child: SingleChildScrollView(
// padding: const EdgeInsets.all(15),
// child: Column(
// children: [
// //const SizedBox(height: 15),
// const Text(
// "Add Business Profile",
// style: TextStyle(
// fontWeight: FontWeight.bold,
// fontSize: 25,
// ),
// ),
// const SizedBox(height: 25.0),
// MIHTextField(
// controller: regController,
// hintText: "Registration No.",
// editable: true,
// required: true,
// ),
// const SizedBox(height: 10.0),
// MIHTextField(
// controller: nameController,
// hintText: "Business Name",
// editable: true,
// required: true,
// ),
// const SizedBox(height: 10.0),
// MIHDropdownField(
// controller: typeController,
// hintText: "Business Type",
// dropdownOptions: const ["Doctors Office", "Other"],
// required: true,
// editable: true,
// ),
// const SizedBox(height: 10.0),
// MIHTextField(
// controller: contactController,
// hintText: "Contact Number",
// editable: true,
// required: true,
// ),
// const SizedBox(height: 10.0),
// MIHTextField(
// controller: emailController,
// hintText: "Email",
// editable: true,
// required: true,
// ),
// const SizedBox(height: 10.0),
// MIHFileField(
// controller: logonameController,
// hintText: "Logo",
// editable: false,
// required: true,
// onPressed: () async {
// FilePickerResult? result =
// await FilePicker.platform.pickFiles(
// type: FileType.custom,
// allowedExtensions: ['jpg', 'png', 'pdf'],
// );
// if (result == null) return;
// final selectedFile = result.files.first;
// setState(() {
// selectedLogo = selectedFile;
// });
// setState(() {
// logonameController.text = selectedFile.name;
// });
// },
// ),
// const SizedBox(height: 15.0),
// Divider(
// color: MzanziInnovationHub.of(context)
// ?.theme
// .secondaryColor(),
// ),
// //const SizedBox(height: 15.0),
// const Text(
// "My Business User",
// style: TextStyle(
// fontWeight: FontWeight.bold,
// fontSize: 25,
// ),
// ),
// const SizedBox(height: 25.0),
// MIHDropdownField(
// controller: titleController,
// hintText: "Title",
// dropdownOptions: const ["Doctor", "Assistant"],
// required: true,
// editable: true,
// ),
// const SizedBox(height: 10.0),
// MIHTextField(
// controller: fnameController,
// hintText: "Name",
// editable: false,
// required: true,
// ),
// const SizedBox(height: 10.0),
// MIHTextField(
// controller: lnameController,
// hintText: "Surname",
// editable: false,
// required: true,
// ),
// const SizedBox(height: 10.0),
// MIHFileField(
// controller: signtureController,
// hintText: "Signature",
// editable: false,
// required: true,
// onPressed: () async {
// FilePickerResult? result =
// await FilePicker.platform.pickFiles(
// type: FileType.custom,
// allowedExtensions: ['jpg', 'png', 'pdf'],
// );
// if (result == null) return;
// final selectedFile = result.files.first;
// setState(() {
// selectedSignature = selectedFile;
// });
// setState(() {
// signtureController.text = selectedFile.name;
// });
// },
// ),
// const SizedBox(height: 15.0),
// MIHDropdownField(
// controller: accessController,
// hintText: "Access",
// dropdownOptions: const ["Full", "Partial"],
// required: true,
// editable: false,
// ),
// const SizedBox(height: 30.0),
// SizedBox(
// width: 500.0,
// height: 50.0,
// child: MIHButton(
// buttonText: "Add",
// buttonColor: MzanziInnovationHub.of(context)!
// .theme
// .secondaryColor(),
// textColor: MzanziInnovationHub.of(context)!
// .theme
// .primaryColor(),
// onTap: () {
// submitForm();
// },
// ),
// ),
// ],
// ),
// ),
// ),
// Positioned(
// top: 10,
// left: 5,
// width: 50,
// height: 50,
// child: IconButton(
// onPressed: () {
// Navigator.of(context).pop();
// },
// icon: const Icon(Icons.arrow_back),
// ),
// )
// ],
// ),
// ),
// );
}
}

View File

@@ -0,0 +1,508 @@
import 'package:Mzansi_Innovation_Hub/main.dart';
import 'package:Mzansi_Innovation_Hub/mih_apis/mih_claim_statement_generation_api.dart';
import 'package:Mzansi_Innovation_Hub/mih_apis/mih_icd10_code_api.dart';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_button.dart';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_date_input.dart';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_search_input.dart';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_window.dart';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_pop_up_messages/mih_error_message.dart';
import 'package:Mzansi_Innovation_Hub/mih_objects/app_user.dart';
import 'package:Mzansi_Innovation_Hub/mih_objects/arguments.dart';
import 'package:Mzansi_Innovation_Hub/mih_objects/business.dart';
import 'package:Mzansi_Innovation_Hub/mih_objects/business_user.dart';
import 'package:Mzansi_Innovation_Hub/mih_objects/icd10_code.dart.dart';
import 'package:Mzansi_Innovation_Hub/mih_objects/patients.dart';
import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/icd10_search_window.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class ClaimStatementWindow extends StatefulWidget {
final Patient selectedPatient;
final AppUser signedInUser;
final Business? business;
final BusinessUser? businessUser;
const ClaimStatementWindow({
super.key,
required this.selectedPatient,
required this.signedInUser,
required this.business,
required this.businessUser,
});
@override
State<ClaimStatementWindow> createState() => _ClaimStatementWindowState();
}
class _ClaimStatementWindowState extends State<ClaimStatementWindow> {
final TextEditingController _docTypeController = TextEditingController();
final TextEditingController _fullNameController = TextEditingController();
final TextEditingController _idController = TextEditingController();
final TextEditingController _medAidController = TextEditingController();
final TextEditingController _medAidNoController = TextEditingController();
final TextEditingController _medAidCodeController = TextEditingController();
final TextEditingController _medAidNameController = TextEditingController();
final TextEditingController _medAidSchemeController = TextEditingController();
final TextEditingController _providerNameController = TextEditingController();
final TextEditingController _practiceNoController = TextEditingController();
final TextEditingController _vatNoController = TextEditingController();
final TextEditingController _serviceDateController = TextEditingController();
final TextEditingController _serviceDescController = TextEditingController();
final TextEditingController _serviceDescOptionsController =
TextEditingController();
final TextEditingController _prcedureNameController = TextEditingController();
// final TextEditingController _procedureDateController =
// TextEditingController();
final TextEditingController _proceedureAdditionalInfoController =
TextEditingController();
final TextEditingController _icd10CodeController = TextEditingController();
final TextEditingController _amountController = TextEditingController();
final TextEditingController _preauthNoController = TextEditingController();
final ValueNotifier<String> serviceDesc = ValueNotifier("");
final ValueNotifier<String> medAid = ValueNotifier("");
List<ICD10Code> icd10codeList = [];
void icd10SearchWindow(List<ICD10Code> codeList) {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => ICD10SearchWindow(
icd10CodeController: _icd10CodeController,
icd10codeList: codeList,
),
);
}
Widget getWindowBody() {
return Column(
children: [
MIHDropdownField(
controller: _docTypeController,
hintText: "Document Type",
dropdownOptions: const ["Claim", "Statement"],
required: true,
editable: true,
),
const SizedBox(height: 10),
// Text(
// "Patient Details",
// textAlign: TextAlign.center,
// style: TextStyle(
// fontSize: 20,
// fontWeight: FontWeight.bold,
// color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
// ),
// ),
// Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
// const SizedBox(height: 10),
// MIHTextField(
// controller: _fullNameController,
// hintText: "Full Name",
// editable: false,
// required: true,
// ),
// const SizedBox(height: 10),
// MIHTextField(
// controller: _idController,
// hintText: "ID No.",
// editable: false,
// required: true,
// ),
// const SizedBox(height: 10),
// MIHTextField(
// controller: _medAidController,
// hintText: "Has Medical Aid",
// editable: false,
// required: true,
// ),
// const SizedBox(height: 10),
// ValueListenableBuilder(
// valueListenable: serviceDesc,
// builder: (BuildContext context, String value, Widget? child) {
// return Visibility(
// visible: value == "Yes",
// child: Column(
// children: [
// MIHTextField(
// controller: _medAidNoController,
// hintText: "Medical Aid No.",
// editable: false,
// required: true,
// ),
// const SizedBox(height: 10),
// MIHTextField(
// controller: _medAidCodeController,
// hintText: "Medical Aid Code",
// editable: false,
// required: true,
// ),
// const SizedBox(height: 10),
// MIHTextField(
// controller: _medAidNameController,
// hintText: "Medical Aid Name",
// editable: false,
// required: true,
// ),
// const SizedBox(height: 10),
// MIHTextField(
// controller: _medAidSchemeController,
// hintText: "Medical Aid Scheme",
// editable: false,
// required: true,
// ),
// const SizedBox(height: 10),
// ],
// ),
// );
// },
// ),
// Text(
// "Provider Details",
// textAlign: TextAlign.center,
// style: TextStyle(
// fontSize: 20,
// fontWeight: FontWeight.bold,
// color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
// ),
// ),
// Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
// const SizedBox(height: 10),
// MIHTextField(
// controller: _providerNameController,
// hintText: "Provider Name",
// editable: false,
// required: true,
// ),
// const SizedBox(height: 10),
// MIHTextField(
// controller: _practiceNoController,
// hintText: "Practice No.",
// editable: false,
// required: true,
// ),
// const SizedBox(height: 10),
// MIHTextField(
// controller: _vatNoController,
// hintText: "VAT No.",
// editable: false,
// required: true,
// ),
// const SizedBox(height: 10),
Text(
"Service Details",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
),
),
Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
const SizedBox(height: 10),
MIHDateField(
controller: _serviceDateController,
lableText: "Date of Service",
required: true,
),
const SizedBox(height: 10),
MIHDropdownField(
controller: _serviceDescController,
hintText: "Service Decription",
dropdownOptions: const [
"Consultation",
"Procedure",
"Other",
],
required: true,
editable: true,
),
const SizedBox(height: 10),
ValueListenableBuilder(
valueListenable: serviceDesc,
builder: (BuildContext context, String value, Widget? child) {
Widget returnWidget;
switch (value) {
case 'Consultation':
returnWidget = Column(
children: [
MIHDropdownField(
controller: _serviceDescOptionsController,
hintText: "Service Decription Options",
dropdownOptions: const [
"General Consultation",
"Follow-Up Consultation",
"Specialist Consultation",
"Emergency Consultation",
],
required: true,
editable: true,
),
const SizedBox(height: 10),
],
);
case 'Procedure':
returnWidget = Column(
children: [
MIHTextField(
controller: _prcedureNameController,
hintText: "Procedure Name",
editable: true,
required: true,
),
const SizedBox(height: 10),
// MIHDateField(
// controller: _procedureDateController,
// lableText: "Procedure Date",
// required: true,
// ),
// const SizedBox(height: 10),
MIHTextField(
controller: _proceedureAdditionalInfoController,
hintText: "Additional Information",
editable: true,
required: true,
),
const SizedBox(height: 10),
],
);
case 'Other':
returnWidget = Column(
children: [
MIHTextField(
controller: _serviceDescOptionsController,
hintText: "Service Decription text",
editable: false,
required: true,
),
const SizedBox(height: 10),
],
);
default:
returnWidget = const SizedBox();
}
return returnWidget;
},
),
//const SizedBox(height: 10),
MIHSearchField(
controller: _icd10CodeController,
hintText: "ICD-10 Code & Description",
required: true,
editable: true,
onTap: () {
//api
MIHIcd10CodeApis.getIcd10Codes(_icd10CodeController.text, context)
.then((result) {
icd10SearchWindow(result);
});
},
),
const SizedBox(height: 10),
MIHTextField(
controller: _amountController,
hintText: "Amount",
editable: true,
required: true,
),
Text(
"Additional Infomation",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
),
),
Divider(color: MzanziInnovationHub.of(context)!.theme.secondaryColor()),
const SizedBox(height: 10),
MIHTextField(
controller: _preauthNoController,
hintText: "Pre-authorisation No.",
editable: true,
required: false,
),
const SizedBox(height: 15),
SizedBox(
width: 500,
height: 50,
child: MIHButton(
onTap: () {
//generate document and uploud it
if (isInputValid()) {
MIHClaimStatementGenerationApi().generateClaimStatement(
ClaimStatementGenerationArguments(
_docTypeController.text,
widget.selectedPatient.app_id,
_fullNameController.text,
_idController.text,
_medAidController.text,
_medAidNoController.text,
_medAidCodeController.text,
_medAidNameController.text,
_medAidSchemeController.text,
widget.business!.Name,
"*To-Be Added*",
widget.business!.contact_no,
widget.business!.bus_email,
_providerNameController.text,
_practiceNoController.text,
_vatNoController.text,
_serviceDateController.text,
_serviceDescController.text,
_serviceDescOptionsController.text,
_prcedureNameController.text,
_proceedureAdditionalInfoController.text,
_icd10CodeController.text,
_amountController.text,
_preauthNoController.text,
widget.business!.logo_path,
widget.businessUser!.sig_path,
),
PatientViewArguments(
widget.signedInUser,
widget.selectedPatient,
widget.businessUser,
widget.business,
"business",
),
context);
} else {
showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(errorType: "Input Error");
},
);
}
},
buttonText: "Generate",
buttonColor:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(),
),
)
],
);
}
void serviceDescriptionSelected() {
if (_serviceDescController.text.isNotEmpty) {
serviceDesc.value = _serviceDescController.text;
} else {
serviceDesc.value = "";
}
}
void hasMedAid() {
if (_medAidController.text.isNotEmpty) {
medAid.value = _medAidController.text;
} else {
medAid.value = "";
}
}
bool isInputValid() {
switch (_serviceDescController.text) {
case 'Procedure':
if (_docTypeController.text.isEmpty ||
_serviceDateController.text.isEmpty ||
_icd10CodeController.text.isEmpty ||
_amountController.text.isEmpty ||
_prcedureNameController.text.isEmpty ||
_proceedureAdditionalInfoController.text.isEmpty) {
return false;
} else {
return true;
}
default:
if (_docTypeController.text.isEmpty ||
_serviceDateController.text.isEmpty ||
_icd10CodeController.text.isEmpty ||
_amountController.text.isEmpty ||
_serviceDescOptionsController.text.isEmpty) {
return false;
} else {
return true;
}
}
}
String getUserTitle() {
if (widget.businessUser!.title == "Doctor") {
return "Dr.";
} else {
return widget.businessUser!.title;
}
}
String getTodayDate() {
DateTime today = DateTime.now();
return DateFormat('yyyy-MM-dd').format(today);
}
@override
void dispose() {
_docTypeController.dispose();
_fullNameController.dispose();
_idController.dispose();
_medAidController.dispose();
_medAidNoController.dispose();
_medAidCodeController.dispose();
_medAidNameController.dispose();
_medAidSchemeController.dispose();
_providerNameController.dispose();
_practiceNoController.dispose();
_vatNoController.dispose();
_serviceDateController.dispose();
_serviceDescController.dispose();
_serviceDescOptionsController.dispose();
_prcedureNameController.dispose();
// _procedureDateController.dispose();
_proceedureAdditionalInfoController.dispose();
_icd10CodeController.dispose();
_preauthNoController.dispose();
super.dispose();
}
@override
void initState() {
_serviceDescController.addListener(serviceDescriptionSelected);
_medAidController.addListener(hasMedAid);
_fullNameController.text =
"${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}";
_idController.text = widget.selectedPatient.id_no;
_medAidController.text = widget.selectedPatient.medical_aid;
_medAidNameController.text = widget.selectedPatient.medical_aid_name;
_medAidCodeController.text = widget.selectedPatient.medical_aid_code;
_medAidNoController.text = widget.selectedPatient.medical_aid_no;
_medAidSchemeController.text = widget.selectedPatient.medical_aid_scheme;
_serviceDateController.text = getTodayDate();
_providerNameController.text =
"${getUserTitle()} ${widget.signedInUser.fname} ${widget.signedInUser.lname}";
_practiceNoController.text = widget.business!.practice_no;
_vatNoController.text = widget.business!.vat_no;
super.initState();
}
@override
Widget build(BuildContext context) {
return MIHWindow(
fullscreen: false,
windowTitle: "Generate Claim/ Statement Document",
windowTools: const [],
onWindowTapClose: () {
// medicineController.clear();
// quantityController.clear();
// dosageController.clear();
// timesDailyController.clear();
// noDaysController.clear();
// noRepeatsController.clear();
Navigator.pop(context);
},
windowBody: [
getWindowBody(),
],
);
}
}

View File

@@ -0,0 +1,228 @@
import 'dart:convert';
import 'package:Mzansi_Innovation_Hub/mih_apis/mih_claim_statement_generation_api.dart';
import 'package:Mzansi_Innovation_Hub/mih_objects/arguments.dart';
import 'package:Mzansi_Innovation_Hub/mih_objects/claim_statement_file.dart';
import 'package:flutter/material.dart';
import 'package:supertokens_flutter/http.dart' as http;
import '../../../main.dart';
import '../../../mih_components/mih_layout/mih_window.dart';
import '../../../mih_components/mih_pop_up_messages/mih_delete_message.dart';
import '../../../mih_components/mih_pop_up_messages/mih_error_message.dart';
import '../../../mih_components/mih_pop_up_messages/mih_success_message.dart';
import '../../../mih_env/env.dart';
import '../../../mih_objects/app_user.dart';
import '../../../mih_objects/business.dart';
import '../../../mih_objects/business_user.dart';
import '../../../mih_objects/patients.dart';
import 'build_file_view.dart';
class BuildClaimStatementFileList extends StatefulWidget {
final AppUser signedInUser;
final List<ClaimStatementFile> files;
final Patient selectedPatient;
final Business? business;
final BusinessUser? businessUser;
final String type;
const BuildClaimStatementFileList({
super.key,
required this.files,
required this.signedInUser,
required this.selectedPatient,
required this.business,
required this.businessUser,
required this.type,
});
@override
State<BuildClaimStatementFileList> createState() =>
_BuildClaimStatementFileListState();
}
class _BuildClaimStatementFileListState
extends State<BuildClaimStatementFileList> {
int indexOn = 0;
final baseAPI = AppEnviroment.baseApiUrl;
final basefile = AppEnviroment.baseFileUrl;
String fileUrl = "";
Future<String> getFileUrlApiCall(String filePath) async {
var url = "$baseAPI/minio/pull/file/${AppEnviroment.getEnv()}/$filePath";
//print(url);
var response = await http.get(Uri.parse(url));
// print("here1");
//print(response.statusCode);
if (response.statusCode == 200) {
//print("here2");
String body = response.body;
//print(body);
//print("here3");
var decodedData = jsonDecode(body);
//print("Dedoced: ${decodedData['minioURL']}");
return decodedData['minioURL'];
//AppUser u = AppUser.fromJson(decodedData);
// print(u.email);
//return "AlometThere";
} else {
throw Exception("Error: GetUserData status code ${response.statusCode}");
}
}
void internetConnectionPopUp() {
showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(errorType: "Internet Connection");
},
);
}
void successPopUp(String message) {
showDialog(
context: context,
builder: (context) {
return MIHSuccessMessage(
successType: "Success",
successMessage: message,
);
},
);
}
void deleteFilePopUp(String filePath, int fileID) {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => MIHDeleteMessage(
deleteType: "File",
onTap: () async {
//API Call here
await MIHClaimStatementGenerationApi
.deleteClaimStatementFilesByFileID(
PatientViewArguments(
widget.signedInUser,
widget.selectedPatient,
widget.businessUser,
widget.business,
"business",
),
filePath,
fileID,
context,
);
},
),
);
}
void viewFilePopUp(String fileName, String filePath, int fileID, String url) {
bool hasAccessToDelete = false;
if (widget.type == "business") {
hasAccessToDelete = true;
}
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => MIHWindow(
fullscreen: true,
windowTitle: fileName,
windowBody: [
BuildFileView(
link: url,
path: filePath,
//pdfLink: '${AppEnviroment.baseFileUrl}/mih/$filePath',
),
const SizedBox(
height: 10,
)
],
windowTools: [
Visibility(
visible: hasAccessToDelete,
child: IconButton(
onPressed: () {
deleteFilePopUp(filePath, fileID);
},
icon: Icon(
size: 35,
Icons.delete,
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
),
),
),
],
onWindowTapClose: () {
Navigator.pop(context);
},
),
);
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
}
@override
Widget build(BuildContext context) {
if (widget.files.isNotEmpty) {
return ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
separatorBuilder: (BuildContext context, int index) {
return Divider(
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
);
},
itemCount: widget.files.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(
widget.files[index].file_name,
style: TextStyle(
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
),
),
subtitle: Text(
widget.files[index].insert_date,
style: TextStyle(
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
),
),
// trailing: Icon(
// Icons.arrow_forward,
// color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
// ),
onTap: () async {
await getFileUrlApiCall(widget.files[index].file_path)
.then((urlHere) {
//print(url);
setState(() {
fileUrl = urlHere;
});
});
viewFilePopUp(
widget.files[index].file_name,
widget.files[index].file_path,
widget.files[index].idclaim_statement_file,
fileUrl);
},
);
},
);
} else {
return const Center(
child: Text(
"No Documents Available",
style: TextStyle(fontSize: 25, color: Colors.grey),
textAlign: TextAlign.center,
),
);
}
}
}

View File

@@ -0,0 +1,76 @@
import 'package:Mzansi_Innovation_Hub/mih_objects/icd10_code.dart.dart';
import 'package:flutter/material.dart';
import '../../../main.dart';
import '../../../mih_env/env.dart';
class BuildICD10CodeList extends StatefulWidget {
final TextEditingController icd10CodeController;
final List<ICD10Code> icd10codeList;
const BuildICD10CodeList({
super.key,
required this.icd10CodeController,
required this.icd10codeList,
});
@override
State<BuildICD10CodeList> createState() => _BuildPatientsListState();
}
class _BuildPatientsListState extends State<BuildICD10CodeList> {
String baseAPI = AppEnviroment.baseApiUrl;
int counter = 0;
Widget displayCode(int index) {
String title = "ICD-10 Code: ${widget.icd10codeList[index].icd10}";
String description =
"Description: ${widget.icd10codeList[index].description}";
return ListTile(
title: Text(
title,
style: TextStyle(
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
),
),
subtitle: RichText(
text: TextSpan(
text: description,
style: DefaultTextStyle.of(context).style,
),
),
onTap: () {
//select code
setState(() {
widget.icd10CodeController.text =
"${widget.icd10codeList[index].icd10} - ${widget.icd10codeList[index].description}";
});
Navigator.of(context).pop();
},
);
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return ListView.separated(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
separatorBuilder: (BuildContext context, index) {
return Divider(
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
);
},
itemCount: widget.icd10codeList.length,
itemBuilder: (context, index) {
//final patient = widget.patients[index].id_no.contains(widget.searchString);
//print(index);
return displayCode(index);
},
);
}
}

View File

@@ -0,0 +1,58 @@
import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_window.dart';
import 'package:Mzansi_Innovation_Hub/mih_objects/icd10_code.dart.dart';
import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/builder/build_icd10_code_list.dart';
import 'package:flutter/material.dart';
class ICD10SearchWindow extends StatefulWidget {
final TextEditingController icd10CodeController;
final List<ICD10Code> icd10codeList;
const ICD10SearchWindow({
super.key,
required this.icd10CodeController,
required this.icd10codeList,
});
@override
State<ICD10SearchWindow> createState() => _ICD10SearchWindowState();
}
class _ICD10SearchWindowState extends State<ICD10SearchWindow> {
Widget getWindowBody() {
return Column(
children: [
MIHTextField(
controller: widget.icd10CodeController,
hintText: "Search Text",
editable: false,
required: false,
),
BuildICD10CodeList(
icd10CodeController: widget.icd10CodeController,
icd10codeList: widget.icd10codeList,
),
],
);
}
@override
Widget build(BuildContext context) {
return MIHWindow(
fullscreen: false,
windowTitle: "ICD-10 Search",
windowTools: const [],
onWindowTapClose: () {
// medicineController.clear();
// quantityController.clear();
// dosageController.clear();
// timesDailyController.clear();
// noDaysController.clear();
// noRepeatsController.clear();
Navigator.pop(context);
},
windowBody: [
getWindowBody(),
],
);
}
}

View File

@@ -0,0 +1,272 @@
import 'dart:async';
import 'dart:convert';
import 'package:Mzansi_Innovation_Hub/mih_apis/mih_claim_statement_generation_api.dart';
import 'package:Mzansi_Innovation_Hub/mih_objects/claim_statement_file.dart';
import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/Claim_Statement_Window.dart';
import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/builder/build_claim_statement_files_list.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import '../../main.dart';
import 'package:supertokens_flutter/http.dart' as http;
import '../../mih_components/mih_pop_up_messages/mih_error_message.dart';
import '../../mih_components/mih_pop_up_messages/mih_loading_circle.dart';
import '../../mih_components/mih_pop_up_messages/mih_success_message.dart';
import '../../mih_env/env.dart';
import '../../mih_objects/app_user.dart';
import '../../mih_objects/business.dart';
import '../../mih_objects/business_user.dart';
import '../../mih_objects/files.dart';
import '../../mih_objects/patients.dart';
// import 'builder/build_files_list.dart';
class PatientClaimsOrStatements extends StatefulWidget {
final int patientIndex;
final Patient selectedPatient;
final AppUser signedInUser;
final Business? business;
final BusinessUser? businessUser;
final String type;
const PatientClaimsOrStatements({
super.key,
required this.patientIndex,
required this.selectedPatient,
required this.signedInUser,
required this.business,
required this.businessUser,
required this.type,
});
@override
State<PatientClaimsOrStatements> createState() =>
_PatientClaimsOrStatementsState();
}
class _PatientClaimsOrStatementsState extends State<PatientClaimsOrStatements> {
String endpointFiles = "${AppEnviroment.baseApiUrl}/files/patients/";
String endpointUser = "${AppEnviroment.baseApiUrl}/users/profile/";
String endpointGenFiles =
"${AppEnviroment.baseApiUrl}/files/generate/med-cert/";
String endpointFileUpload = "${AppEnviroment.baseApiUrl}/files/upload/file/";
String endpointInsertFiles = "${AppEnviroment.baseApiUrl}/files/insert/";
final startDateController = TextEditingController();
final endDateTextController = TextEditingController();
final retDateTextController = TextEditingController();
final selectedFileController = TextEditingController();
final medicineController = TextEditingController();
final quantityController = TextEditingController();
final dosageController = TextEditingController();
final timesDailyController = TextEditingController();
final noDaysController = TextEditingController();
final noRepeatsController = TextEditingController();
final outputController = TextEditingController();
late Future<List<ClaimStatementFile>> futueFiles;
late String userEmail = "";
late PlatformFile selected;
final baseAPI = AppEnviroment.baseApiUrl;
Future<List<PFile>> fetchFiles() async {
final response = await http.get(Uri.parse(
"${AppEnviroment.baseApiUrl}/files/patients/${widget.selectedPatient.app_id}"));
//print(response.statusCode);
//print(response.body);
if (response.statusCode == 200) {
Iterable l = jsonDecode(response.body);
List<PFile> files =
List<PFile>.from(l.map((model) => PFile.fromJson(model)));
return files;
} else {
internetConnectionPopUp();
throw Exception('failed to load patients');
}
}
void successPopUp(String message) {
showDialog(
context: context,
builder: (context) {
return MIHSuccessMessage(
successType: "Success",
successMessage: message,
);
},
);
}
void messagePopUp(error) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text(error),
);
},
);
}
void claimOrStatementWindow() {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => ClaimStatementWindow(
selectedPatient: widget.selectedPatient,
signedInUser: widget.signedInUser,
business: widget.business,
businessUser: widget.businessUser,
),
);
}
void internetConnectionPopUp() {
showDialog(
context: context,
builder: (context) {
return const MIHErrorMessage(errorType: "Internet Connection");
},
);
}
bool isMedCertFieldsFilled() {
if (startDateController.text.isEmpty ||
endDateTextController.text.isEmpty ||
retDateTextController.text.isEmpty) {
return false;
} else {
return true;
}
}
bool isFileFieldsFilled() {
if (selectedFileController.text.isEmpty) {
return false;
} else {
return true;
}
}
List<Widget> setIcons() {
if (widget.type == "personal") {
return [
Text(
"Claims/ Statements",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
),
),
// IconButton(
// onPressed: () {
// uploudFilePopUp();
// },
// icon: Icon(
// Icons.add,
// color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
// ),
// )
];
} else {
return [
Text(
"Claims/ Statements",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
),
),
IconButton(
onPressed: () {
// new window to input fields for claim/ statements
claimOrStatementWindow();
},
icon: Icon(
Icons.add,
color: MzanziInnovationHub.of(context)!.theme.secondaryColor(),
),
)
];
}
}
@override
void dispose() {
startDateController.dispose();
endDateTextController.dispose();
retDateTextController.dispose();
selectedFileController.dispose();
medicineController.dispose();
quantityController.dispose();
dosageController.dispose();
timesDailyController.dispose();
noDaysController.dispose();
noRepeatsController.dispose();
outputController.dispose();
super.dispose();
}
@override
void initState() {
if (widget.business == null) {
futueFiles =
MIHClaimStatementGenerationApi.getClaimStatementFilesByPatient(
widget.signedInUser.app_id);
} else {
futueFiles =
MIHClaimStatementGenerationApi.getClaimStatementFilesByBusiness(
widget.business!.business_id);
}
//patientDetails = getPatientDetails() as Patient;
//getUserDetails();
super.initState();
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: futueFiles,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: Mihloadingcircle(),
);
} else if (snapshot.hasData) {
final filesList = snapshot.data!;
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: setIcons(),
),
Divider(
color:
MzanziInnovationHub.of(context)!.theme.secondaryColor()),
const SizedBox(height: 10),
//const Placeholder(),
BuildClaimStatementFileList(
files: filesList,
signedInUser: widget.signedInUser,
selectedPatient: widget.selectedPatient,
business: widget.business,
businessUser: widget.businessUser,
type: widget.type,
),
],
);
} else {
return const Center(
child: Text("Error Loading Notes"),
);
}
},
);
}
}

View File

@@ -1,5 +1,6 @@
import 'dart:convert';
import 'package:Mzansi_Innovation_Hub/mih_packages/patient_profile/patient_claims_statements.dart';
import 'package:flutter/material.dart';
import 'package:flutter_swipe_detector/flutter_swipe_detector.dart';
import '../../main.dart';
@@ -94,7 +95,7 @@ class _PatientViewState extends State<PatientView> {
businessUser: widget.arguments.businessUser,
type: widget.arguments.type,
);
} else {
} else if (index == 2) {
return PatientFiles(
patientIndex: widget.arguments.selectedPatient!.idpatients,
selectedPatient: widget.arguments.selectedPatient!,
@@ -103,6 +104,15 @@ class _PatientViewState extends State<PatientView> {
businessUser: widget.arguments.businessUser,
type: widget.arguments.type,
);
} else {
return PatientClaimsOrStatements(
patientIndex: widget.arguments.selectedPatient!.idpatients,
selectedPatient: widget.arguments.selectedPatient!,
signedInUser: widget.arguments.signedInUser,
business: widget.arguments.business,
businessUser: widget.arguments.businessUser,
type: widget.arguments.type,
);
}
}
@@ -221,6 +231,35 @@ class _PatientViewState extends State<PatientView> {
),
),
),
//============ Claims/ Statements ================
Visibility(
visible: _selectedIndex != 3,
child: IconButton(
onPressed: () {
setState(() {
_selectedIndex = 3;
});
},
icon: const Icon(
Icons.file_open_outlined,
size: 35,
),
),
),
Visibility(
visible: _selectedIndex == 3,
child: IconButton.filled(
onPressed: () {
setState(() {
_selectedIndex = 3;
});
},
icon: const Icon(
Icons.file_open_outlined,
size: 35,
),
),
),
],
);
}