forked from yaso_meth/mih-project
Merge pull request #18 from yaso-meth/Claim-Document-Generation
Claim-Document-Generation
This commit is contained in:
@@ -35,7 +35,8 @@ COPY . /app/
|
||||
|
||||
WORKDIR /app
|
||||
RUN flutter upgrade
|
||||
RUN flutter build web --release --web-renderer canvaskit -t ./lib/main_prod.dart
|
||||
RUN flutter build web --release -t ./lib/main_prod.dart
|
||||
# RUN flutter build web --release --web-renderer canvaskit -t ./lib/main_prod.dart
|
||||
|
||||
|
||||
# RUN cd ..
|
||||
|
||||
256
Frontend/lib/mih_apis/mih_claim_statement_generation_api.dart
Normal file
256
Frontend/lib/mih_apis/mih_claim_statement_generation_api.dart
Normal 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,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
55
Frontend/lib/mih_apis/mih_icd10_code_api.dart
Normal file
55
Frontend/lib/mih_apis/mih_icd10_code_api.dart
Normal 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();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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(
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
40
Frontend/lib/mih_objects/claim_statement_file.dart
Normal file
40
Frontend/lib/mih_objects/claim_statement_file.dart
Normal 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.'),
|
||||
};
|
||||
}
|
||||
}
|
||||
23
Frontend/lib/mih_objects/icd10_code.dart.dart
Normal file
23
Frontend/lib/mih_objects/icd10_code.dart.dart
Normal 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.'),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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",
|
||||
|
||||
@@ -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),
|
||||
// ),
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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(),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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"),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
BIN
backend/ICD10_Codes/ICD-10_MIT_2021_Excel_16-March_2021.xls
Normal file
BIN
backend/ICD10_Codes/ICD-10_MIT_2021_Excel_16-March_2021.xls
Normal file
Binary file not shown.
@@ -6,6 +6,7 @@ import routers.patients as patients
|
||||
import routers.patients_files as patients_files
|
||||
import routers.patients_notes as patients_notes
|
||||
import routers.patients_queue as patients_queue
|
||||
import routers.claim_statement_files as claim_statement_files
|
||||
import routers.users as users
|
||||
import routers.notifications as notifications
|
||||
import routers.fileStorage as fileStorage
|
||||
@@ -15,6 +16,7 @@ import routers.business as business
|
||||
import routers.access_request as access_request
|
||||
import routers.patient_access as patient_access
|
||||
import routers.mzansi_wallet as mzansi_wallet
|
||||
import routers.icd10_codes as icd10_codes
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.middleware import Middleware
|
||||
from supertokens_python import get_all_cors_headers
|
||||
@@ -83,11 +85,13 @@ app.include_router(access_request.router)
|
||||
app.include_router(patient_access.router)
|
||||
app.include_router(users.router)
|
||||
app.include_router(fileStorage.router)
|
||||
app.include_router(claim_statement_files.router)
|
||||
app.include_router(medicine.router)
|
||||
app.include_router(business_user.router)
|
||||
app.include_router(business.router)
|
||||
app.include_router(notifications.router)
|
||||
app.include_router(mzansi_wallet.router)
|
||||
app.include_router(icd10_codes.router)
|
||||
|
||||
# Check if server is up
|
||||
@app.get("/", tags=["Server Check"])
|
||||
|
||||
@@ -25,6 +25,8 @@ class businessInsertRequest(BaseModel):
|
||||
contact_no: str
|
||||
bus_email: str
|
||||
gps_location: str
|
||||
practice_no: str
|
||||
vat_no: str
|
||||
|
||||
class businessUpdateRequest(BaseModel):
|
||||
business_id: str
|
||||
@@ -36,6 +38,8 @@ class businessUpdateRequest(BaseModel):
|
||||
contact_no: str
|
||||
bus_email: str
|
||||
gps_location: str
|
||||
practice_no: str
|
||||
vat_no: str
|
||||
|
||||
|
||||
# Get List of all files
|
||||
@@ -43,7 +47,10 @@ class businessUpdateRequest(BaseModel):
|
||||
async def read_business_by_business_id(business_id: str, session: SessionContainer = Depends(verify_session())): #, session: SessionContainer = Depends(verify_session())
|
||||
db = database.dbConnection.dbAppDataConnect()
|
||||
cursor = db.cursor()
|
||||
query = "SELECT business.business_id, business.Name, business.type, business.registration_no, business.logo_name, business.logo_path, business.contact_no, business.bus_email, business_users.app_id, business.gps_location "
|
||||
query = "SELECT business.business_id, business.Name, business.type, business.registration_no, "
|
||||
query += "business.logo_name, business.logo_path, business.contact_no, business.bus_email, "
|
||||
query += "business_users.app_id, business.gps_location, "
|
||||
query += "practice_no, vat_no "
|
||||
query += "FROM business "
|
||||
query += "inner join business_users "
|
||||
query += "on business.business_id=business_users.business_id "
|
||||
@@ -64,6 +71,8 @@ async def read_business_by_business_id(business_id: str, session: SessionContain
|
||||
"bus_email": item[7],
|
||||
"app_id": item[8],
|
||||
"gps_location": item[9],
|
||||
"practice_no": item[10],
|
||||
"vat_no": item[11],
|
||||
}
|
||||
for item in cursor.fetchall()
|
||||
]
|
||||
@@ -81,7 +90,10 @@ async def read_business_by_business_id(business_id: str, session: SessionContain
|
||||
async def read_business_by_app_id(app_id: str, session: SessionContainer = Depends(verify_session())): #, session: SessionContainer = Depends(verify_session())
|
||||
db = database.dbConnection.dbAppDataConnect()
|
||||
cursor = db.cursor()
|
||||
query = "SELECT business.business_id, business.Name, business.type, business.registration_no, business.logo_name, business.logo_path, business.contact_no, business.bus_email, business_users.app_id, business.gps_location "
|
||||
query = "SELECT business.business_id, business.Name, business.type, business.registration_no, "
|
||||
query += "business.logo_name, business.logo_path, business.contact_no, business.bus_email, "
|
||||
query += "business_users.app_id, business.gps_location, "
|
||||
query += "practice_no, vat_no "
|
||||
query += "FROM business "
|
||||
query += "inner join business_users "
|
||||
query += "on business.business_id=business_users.business_id "
|
||||
@@ -102,6 +114,8 @@ async def read_business_by_app_id(app_id: str, session: SessionContainer = Depen
|
||||
"bus_email": item[7],
|
||||
"app_id": item[8],
|
||||
"gps_location": item[9],
|
||||
"practice_no": item[10],
|
||||
"vat_no": item[11],
|
||||
}
|
||||
for item in cursor.fetchall()
|
||||
]
|
||||
@@ -118,8 +132,8 @@ async def insert_business_details(itemRequest : businessInsertRequest, session:
|
||||
db = database.dbConnection.dbAppDataConnect()
|
||||
cursor = db.cursor()
|
||||
query = "insert into business "
|
||||
query += "(business_id, Name, type, registration_no, logo_name, logo_path, contact_no, bus_email, gps_location) "
|
||||
query += "values (%s, %s, %s, %s, %s, %s, %s, %s, %s)"
|
||||
query += "(business_id, Name, type, registration_no, logo_name, logo_path, contact_no, bus_email, gps_location, practice_no, vat_no), "
|
||||
query += "values (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
|
||||
uuidString = str(uuid.uuid1())
|
||||
userData = (uuidString,
|
||||
itemRequest.Name,
|
||||
@@ -129,7 +143,9 @@ async def insert_business_details(itemRequest : businessInsertRequest, session:
|
||||
itemRequest.logo_path,
|
||||
itemRequest.contact_no,
|
||||
itemRequest.bus_email,
|
||||
itemRequest.gps_location,)
|
||||
itemRequest.gps_location,
|
||||
itemRequest.practice_no,
|
||||
itemRequest.vat_no)
|
||||
try:
|
||||
cursor.execute(query, userData)
|
||||
except Exception as error:
|
||||
@@ -146,7 +162,7 @@ async def Update_Business_details(itemRequest : businessUpdateRequest, session:
|
||||
# print(itemRequest.gps_location)
|
||||
cursor = db.cursor()
|
||||
query = "update business "
|
||||
query += "set Name=%s, type=%s, registration_no=%s, logo_name=%s, logo_path=%s, contact_no=%s, bus_email=%s, gps_location=%s "
|
||||
query += "set Name=%s, type=%s, registration_no=%s, logo_name=%s, logo_path=%s, contact_no=%s, bus_email=%s, gps_location=%s, practice_no=%s, vat_no=%s "
|
||||
query += "where business_id=%s"
|
||||
userData = (itemRequest.Name,
|
||||
itemRequest.type,
|
||||
@@ -156,6 +172,8 @@ async def Update_Business_details(itemRequest : businessUpdateRequest, session:
|
||||
itemRequest.contact_no,
|
||||
itemRequest.bus_email,
|
||||
itemRequest.gps_location,
|
||||
itemRequest.practice_no,
|
||||
itemRequest.vat_no,
|
||||
itemRequest.business_id,
|
||||
)
|
||||
try:
|
||||
|
||||
112
backend/routers/claim_statement_files.py
Normal file
112
backend/routers/claim_statement_files.py
Normal file
@@ -0,0 +1,112 @@
|
||||
import mysql.connector
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from pydantic import BaseModel
|
||||
#from ..database import dbConnection
|
||||
import database
|
||||
from datetime import date
|
||||
#SuperToken Auth from front end
|
||||
from supertokens_python.recipe.session.framework.fastapi import verify_session
|
||||
from supertokens_python.recipe.session import SessionContainer
|
||||
from fastapi import Depends
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
class claimStatementDeleteRequest(BaseModel):
|
||||
idclaim_statement_file: int
|
||||
|
||||
class claimStatementInsertRequest(BaseModel):
|
||||
app_id: str
|
||||
business_id: str
|
||||
file_path: str
|
||||
file_name: str
|
||||
|
||||
|
||||
# Get List of all files by patient
|
||||
@router.get("/files/claim-statement/patient/{app_id}", tags=["Claim Statement Files"])
|
||||
async def read_all_claim_statement_files_by_app_id(app_id: str, session: SessionContainer = Depends(verify_session())):
|
||||
db = database.dbConnection.dbPatientManagerConnect()
|
||||
cursor = db.cursor()
|
||||
query = "SELECT * FROM claim_statement_file where app_id = %s ORDER BY insert_date DESC"
|
||||
cursor.execute(query, (app_id,))
|
||||
items = [
|
||||
{
|
||||
"idclaim_statement_file": item[0],
|
||||
"app_id": item[1],
|
||||
"business_id": item[2],
|
||||
"insert_date": item[3],
|
||||
"file_path": item[4],
|
||||
"file_name": item[5],
|
||||
}
|
||||
for item in cursor.fetchall()
|
||||
]
|
||||
cursor.close()
|
||||
db.close()
|
||||
return items
|
||||
|
||||
# Get List of all files by patient
|
||||
@router.get("/files/claim-statement/business/{business_id}", tags=["Claim Statement Files"])
|
||||
async def read_all_claim_statement_files_by_business_id(business_id: str, session: SessionContainer = Depends(verify_session())):
|
||||
db = database.dbConnection.dbPatientManagerConnect()
|
||||
cursor = db.cursor()
|
||||
query = "SELECT * FROM claim_statement_file where business_id = %s ORDER BY insert_date DESC"
|
||||
cursor.execute(query, (business_id,))
|
||||
items = [
|
||||
{
|
||||
"idclaim_statement_file": item[0],
|
||||
"app_id": item[1],
|
||||
"business_id": item[2],
|
||||
"insert_date": item[3],
|
||||
"file_path": item[4],
|
||||
"file_name": item[5],
|
||||
}
|
||||
for item in cursor.fetchall()
|
||||
]
|
||||
cursor.close()
|
||||
db.close()
|
||||
return items
|
||||
|
||||
# Delete Patient note on table
|
||||
@router.delete("/files/claim-statement/delete/", tags=["Claim Statement Files"])
|
||||
async def Delete_Patient_File(itemRequest : claimStatementDeleteRequest, session: SessionContainer = Depends(verify_session())): #session: SessionContainer = Depends(verify_session())
|
||||
# today = date.today()
|
||||
db = database.dbConnection.dbPatientManagerConnect()
|
||||
cursor = db.cursor()
|
||||
query = "delete from claim_statement_file "
|
||||
query += "where idclaim_statement_file=%s"
|
||||
# notetData = (itemRequest.idpatient_notes)
|
||||
try:
|
||||
cursor.execute(query, (str(itemRequest.idclaim_statement_file),))
|
||||
except Exception as error:
|
||||
raise HTTPException(status_code=404, detail="Failed to Delete Record")
|
||||
#return {"query": query, "message": error}
|
||||
db.commit()
|
||||
cursor.close()
|
||||
db.close()
|
||||
return {"message": "Successfully deleted Record"}
|
||||
|
||||
# Insert Patient note into table
|
||||
@router.post("/files/claim-statement/insert/", tags=["Claim Statement Files"], status_code=201)
|
||||
async def insert_Patient_Files(itemRequest : claimStatementInsertRequest, session: SessionContainer = Depends(verify_session())): #, session: SessionContainer = Depends(verify_session())
|
||||
today = date.today()
|
||||
db = database.dbConnection.dbPatientManagerConnect()
|
||||
cursor = db.cursor()
|
||||
query = "insert into claim_statement_file "
|
||||
query += "(app_id, business_id, file_path, file_name, insert_date) "
|
||||
query += "values (%s, %s, %s, %s, %s)"
|
||||
notetData = (
|
||||
itemRequest.app_id,
|
||||
itemRequest.business_id,
|
||||
itemRequest.file_path,
|
||||
itemRequest.file_name,
|
||||
today,
|
||||
)
|
||||
try:
|
||||
cursor.execute(query, notetData)
|
||||
except Exception as error:
|
||||
print(error)
|
||||
raise HTTPException(status_code=404, detail="Failed to Create Record")
|
||||
# return {"message": error}
|
||||
db.commit()
|
||||
cursor.close()
|
||||
db.close()
|
||||
return {"message": "Successfully Created file Record"}
|
||||
@@ -71,6 +71,35 @@ class perscriptionList(BaseModel):
|
||||
sig_path: str
|
||||
data: List[perscription]
|
||||
|
||||
class claimStatementUploud(BaseModel):
|
||||
document_type: str
|
||||
patient_app_id: str
|
||||
patient_full_name: str
|
||||
patient_id_no: str
|
||||
has_med_aid: str
|
||||
med_aid_no: str
|
||||
med_aid_code: str
|
||||
med_aid_name: str
|
||||
med_aid_scheme: str
|
||||
busName: str
|
||||
busAddr: str
|
||||
busNo: str
|
||||
busEmail: str
|
||||
provider_name: str
|
||||
practice_no: str
|
||||
vat_no: str
|
||||
service_date: str
|
||||
service_desc: str
|
||||
service_desc_option: str
|
||||
procedure_name: str
|
||||
# procedure_date: str
|
||||
procedure_additional_info: str
|
||||
icd10_code: str
|
||||
amount: str
|
||||
pre_auth_no: str
|
||||
logo_path: str
|
||||
sig_path: str
|
||||
|
||||
@router.get("/minio/pull/file/{env}/{app_id}/{folder}/{file_name}", tags=["Minio"])
|
||||
async def pull_File_from_user(app_id: str, folder: str, file_name: str, env: str, session: SessionContainer = Depends(verify_session())): #, session: SessionContainer = Depends(verify_session())
|
||||
path = app_id + "/" + folder + "/" + file_name
|
||||
@@ -93,7 +122,8 @@ async def pull_File_from_user(app_id: str, folder: str, file_name: str, env: str
|
||||
# return {"message": error}
|
||||
if(env == "Dev"):
|
||||
return {
|
||||
"minioURL": f"http://10.0.2.2:9000/mih/{app_id}/{folder}/{file_name}",
|
||||
# 10.0.2.2
|
||||
"minioURL": f"http://localhost:9000/mih/{app_id}/{folder}/{file_name}",
|
||||
}
|
||||
else:
|
||||
return {
|
||||
@@ -122,7 +152,7 @@ async def delete_File_of_user(requestItem: minioDeleteRequest, session: SessionC
|
||||
path = requestItem.file_path
|
||||
try:
|
||||
# uploudFile(app_id, file.filename, extension[1], content)
|
||||
client = Minio_Storage.minioConnection.minioConnect("dev")
|
||||
client = Minio_Storage.minioConnection.minioConnect("Prd")
|
||||
|
||||
minioError = client.remove_object("mih", path)
|
||||
except Exception as error:
|
||||
@@ -147,6 +177,11 @@ async def upload_perscription_to_user(requestItem: perscriptionList, session: Se
|
||||
uploudPerscription(requestItem)
|
||||
return {"message": "Successfully Generated File"}
|
||||
|
||||
@router.post("/minio/generate/claim-statement/", tags=["Minio"])
|
||||
async def upload_perscription_to_user(requestItem: claimStatementUploud, session: SessionContainer = Depends(verify_session())): #, session: SessionContainer = Depends(verify_session())
|
||||
uploudClaimStatement(requestItem)
|
||||
return {"message": "Successfully Generated File"}
|
||||
|
||||
def uploudFile(app_id, folder, fileName, extension, content):
|
||||
client = Minio_Storage.minioConnection.minioConnect("Dev")
|
||||
found = client.bucket_exists("mih")
|
||||
@@ -162,9 +197,8 @@ def uploudFile(app_id, folder, fileName, extension, content):
|
||||
part_size=10*1024*1024,
|
||||
content_type=f"application/{extension}")
|
||||
|
||||
|
||||
def uploudMedCert(requestItem: medCertUploud):
|
||||
client = Minio_Storage.minioConnection.minioConnect("dev")
|
||||
client = Minio_Storage.minioConnection.minioConnect("Prod")
|
||||
generateMedCertPDF(requestItem)
|
||||
today = datetime.today().strftime('%Y-%m-%d')
|
||||
found = client.bucket_exists("mih")
|
||||
@@ -176,7 +210,7 @@ def uploudMedCert(requestItem: medCertUploud):
|
||||
client.fput_object("mih", fileName, "temp-med-cert.pdf")
|
||||
|
||||
def generateMedCertPDF(requestItem: medCertUploud):
|
||||
client = Minio_Storage.minioConnection.minioConnect("dev")
|
||||
client = Minio_Storage.minioConnection.minioConnect("Prod")
|
||||
new_logo_path = requestItem.logo_path.replace(" ","-")
|
||||
new_sig_path = requestItem.sig_path.replace(" ","-")
|
||||
minioLogo = client.get_object("mih", new_logo_path).read()
|
||||
@@ -241,7 +275,7 @@ def generateMedCertPDF(requestItem: medCertUploud):
|
||||
myCanvas.save()
|
||||
|
||||
def uploudPerscription(requestItem: perscriptionList):
|
||||
client = Minio_Storage.minioConnection.minioConnect("dev")
|
||||
client = Minio_Storage.minioConnection.minioConnect("Prod")
|
||||
generatePerscriptionPDF(requestItem)
|
||||
today = datetime.today().strftime('%Y-%m-%d')
|
||||
found = client.bucket_exists("mih")
|
||||
@@ -253,7 +287,7 @@ def uploudPerscription(requestItem: perscriptionList):
|
||||
client.fput_object("mih", fileName, "temp-perscription.pdf")
|
||||
|
||||
def generatePerscriptionPDF(requestItem: perscriptionList):
|
||||
client = Minio_Storage.minioConnection.minioConnect("dev")
|
||||
client = Minio_Storage.minioConnection.minioConnect("Prod")
|
||||
new_logo_path = requestItem.logo_path.replace(" ","-")
|
||||
new_sig_path = requestItem.sig_path.replace(" ","-")
|
||||
minioLogo = client.get_object("mih", new_logo_path).read()
|
||||
@@ -263,7 +297,7 @@ def generatePerscriptionPDF(requestItem: perscriptionList):
|
||||
w,h = A4
|
||||
|
||||
|
||||
myCanvas = canvas.Canvas("temp-perscription.pdf", pagesize=A4)
|
||||
myCanvas = canvas.Canvas("temp-claim.pdf", pagesize=A4)
|
||||
|
||||
#Business Logo
|
||||
myCanvas.drawImage(imageLogo, 50, h - 125,100,100, mask='auto')
|
||||
@@ -341,9 +375,180 @@ def generatePerscriptionPDF(requestItem: perscriptionList):
|
||||
|
||||
myCanvas.save()
|
||||
|
||||
def byteToMb(size):
|
||||
sizekb = size /1000
|
||||
sizemb = sizekb / 1000
|
||||
return sizemb
|
||||
def uploudClaimStatement(requestItem: claimStatementUploud):
|
||||
try:
|
||||
client = Minio_Storage.minioConnection.minioConnect("Prod")
|
||||
print("connected")
|
||||
except Exception:
|
||||
print("error")
|
||||
|
||||
generateClaimStatementPDF(requestItem)
|
||||
today = datetime.today().strftime('%Y-%m-%d')
|
||||
found = client.bucket_exists("mih")
|
||||
if not found:
|
||||
client.make_bucket("mih")
|
||||
else:
|
||||
print("Bucket already exists")
|
||||
fileName = f"{requestItem.patient_app_id}/claims-statements/{requestItem.document_type}-{requestItem.patient_full_name}-{today}.pdf"
|
||||
client.fput_object("mih", fileName, "temp-claim-statement.pdf")
|
||||
|
||||
# print(byteToMb(229574))
|
||||
def generateClaimStatementPDF(requestItem: claimStatementUploud):
|
||||
client = Minio_Storage.minioConnection.minioConnect("Prod")
|
||||
# print("buckets: " + client.list_buckets)
|
||||
new_logo_path = requestItem.logo_path.replace(" ","-")
|
||||
new_sig_path = requestItem.sig_path.replace(" ","-")
|
||||
print("Path Logo: " + new_logo_path)
|
||||
minioLogo = client.get_object("mih", new_logo_path).read()
|
||||
imageLogo = ImageReader(io.BytesIO(minioLogo))
|
||||
minioSig = client.get_object("mih", new_sig_path).read()
|
||||
imageSig = ImageReader(io.BytesIO(minioSig))
|
||||
w,h = A4
|
||||
|
||||
|
||||
myCanvas = canvas.Canvas("temp-claim-statement.pdf", pagesize=A4)
|
||||
|
||||
#Business Logo
|
||||
myCanvas.drawImage(imageLogo, 50, h - 125,100,100, mask='auto')
|
||||
|
||||
#Business Details
|
||||
myCanvas.setFont('Helvetica-Bold', 10)
|
||||
myCanvas.drawRightString(w - 50,h - 40, f"Name: {requestItem.busName}")
|
||||
myCanvas.drawRightString(w - 50,h - 55, f"Address: {requestItem.busAddr}")
|
||||
myCanvas.drawRightString(w - 50,h - 70, f"Practice No.: {requestItem.practice_no}")
|
||||
myCanvas.drawRightString(w - 50,h - 85, f"Contact No.: {requestItem.busNo}")
|
||||
myCanvas.drawRightString(w - 50,h - 100, f"Email: {requestItem.busEmail}")
|
||||
myCanvas.line(50,h-150,w-50,h-150)
|
||||
#Todays Date
|
||||
myCanvas.setFont('Helvetica-Bold', 12)
|
||||
today = datetime.today()
|
||||
issueDate = today.strftime('%d-%m-%Y')
|
||||
myCanvas.drawRightString(w - 50,h - 180,f"{issueDate}")
|
||||
|
||||
#Title
|
||||
myCanvas.setFont('Helvetica-Bold', 20)
|
||||
myCanvas.drawString(w-340, h - 200, requestItem.document_type)
|
||||
|
||||
#Body
|
||||
# Patient Details
|
||||
myCanvas.setFont('Helvetica-Bold', 14)
|
||||
myCanvas.drawString(50, h-230, "Patient Details")
|
||||
myCanvas.line(50,h-235,w-50,h-235)
|
||||
|
||||
medAidNo = ""
|
||||
medAidCode = ""
|
||||
medAidNameAndScheme = ""
|
||||
if(requestItem.has_med_aid == "Yes"):
|
||||
medAidNo = requestItem.med_aid_no
|
||||
medAidCode = requestItem.med_aid_code
|
||||
medAidNameAndScheme = f"{requestItem.med_aid_name} - {requestItem.med_aid_scheme}"
|
||||
else:
|
||||
medAidNo = "n/a"
|
||||
medAidCode = "n/a"
|
||||
medAidNameAndScheme = "n/a"
|
||||
preAuthNo = requestItem.pre_auth_no
|
||||
if(preAuthNo == ""):
|
||||
preAuthNo = "n/a"
|
||||
# category
|
||||
myCanvas.setFont('Helvetica-Bold', 12)
|
||||
myCanvas.drawString(50, h-250, f"Patient Name:")
|
||||
myCanvas.drawString(50, h-265, f"Patient ID:")
|
||||
myCanvas.drawString(50, h-280, f"Medical Aid No.:")
|
||||
myCanvas.drawString(50, h-295, f"Medical Aid Code:")
|
||||
myCanvas.drawString(50, h-310, f"Medical Aid Scheme:")
|
||||
myCanvas.drawString(50, h-325, f"Pre-Authorisation No:")
|
||||
# content
|
||||
myCanvas.setFont('Helvetica', 12)
|
||||
myCanvas.drawString(225, h-250, f"{requestItem.patient_full_name}")
|
||||
myCanvas.drawString(225, h-265, f"{requestItem.patient_id_no}")
|
||||
myCanvas.drawString(225, h-280, f"{medAidNo}")
|
||||
myCanvas.drawString(225, h-295, f"{medAidCode}")
|
||||
myCanvas.drawString(225, h-310, f"{medAidNameAndScheme}")
|
||||
myCanvas.drawString(225, h-325, f"{preAuthNo}")
|
||||
#===============================================================================
|
||||
# Provide Details
|
||||
myCanvas.setFont('Helvetica-Bold', 14)
|
||||
myCanvas.drawString(50, h-355, "Provider Details")
|
||||
myCanvas.line(50,h-360,w-50,h-360)
|
||||
|
||||
myCanvas.setFont('Helvetica-Bold', 12)
|
||||
myCanvas.drawString(50, h-375, f"Practice Name:")
|
||||
myCanvas.drawString(50, h-390, f"Practice No.:")
|
||||
myCanvas.drawString(50, h-405, f"Vat No.:")
|
||||
myCanvas.drawString(50, h-420, f"Provider Name:")
|
||||
|
||||
myCanvas.setFont('Helvetica', 12)
|
||||
myCanvas.drawString(225, h-375, f"{requestItem.busName}")
|
||||
myCanvas.drawString(225, h-390, f"{requestItem.practice_no}")
|
||||
myCanvas.drawString(225, h-405, f"{requestItem.vat_no}")
|
||||
myCanvas.drawString(225, h-420, f"{requestItem.provider_name}")
|
||||
|
||||
#===============================================================================
|
||||
# Service Details
|
||||
myCanvas.setFont('Helvetica-Bold', 14)
|
||||
myCanvas.drawString(50, h-450, "Service Details")
|
||||
# myCanvas.drawRightString(w - 50, h-300, "Repeat(s)")
|
||||
myCanvas.drawRightString(w - 70, h-450, "Amount")
|
||||
myCanvas.line(50,h-455,w-50,h-455)
|
||||
|
||||
myCanvas.setFont('Helvetica-Bold', 12)
|
||||
myCanvas.drawString(50, h-470, f"Service Type:")
|
||||
myCanvas.drawString(50, h-485, f"Service Date:")
|
||||
|
||||
myCanvas.setFont('Helvetica', 12)
|
||||
myCanvas.drawString(225, h-470, f"{requestItem.service_desc}")
|
||||
displayAmount = ""
|
||||
if("." in requestItem.amount or "," in requestItem.amount):
|
||||
displayAmount = requestItem.amount.replace(",",".")
|
||||
else:
|
||||
displayAmount = requestItem.amount + ".00"
|
||||
myCanvas.drawRightString(w - 80, h-470, displayAmount)
|
||||
myCanvas.drawString(225, h-485, f"{requestItem.service_date}")
|
||||
y = 0
|
||||
if(requestItem.service_desc == "Precedure"):
|
||||
myCanvas.setFont('Helvetica-Bold', 12)
|
||||
myCanvas.drawString(50, h-500, f"Procedure Name:")
|
||||
myCanvas.drawString(50, h-515, f"Additional Info:")
|
||||
myCanvas.drawString(50, h-530, f"ICD-10 Code & Description:")
|
||||
|
||||
myCanvas.setFont('Helvetica', 12)
|
||||
myCanvas.drawString(225, h-500, f"{requestItem.procedure_name}")
|
||||
myCanvas.drawString(225, h-515, f"{requestItem.procedure_additional_info}")
|
||||
y = 530
|
||||
for line in wrap(requestItem.icd10_code, 45):
|
||||
myCanvas.drawString(225, h-y, f"{line}")
|
||||
y+=15
|
||||
myCanvas.line(50,h-y,w-50,h-y)
|
||||
else:
|
||||
myCanvas.setFont('Helvetica-Bold', 12)
|
||||
myCanvas.drawString(50, h-500, f"Service Description:")
|
||||
myCanvas.drawString(50, h-515, f"ICD-10 Code & Description:")
|
||||
|
||||
myCanvas.setFont('Helvetica', 12)
|
||||
myCanvas.drawString(225, h-500, f"{requestItem.service_desc_option}")
|
||||
y = 515
|
||||
for line in wrap(requestItem.icd10_code, 45):
|
||||
myCanvas.drawString(225, h-y, f"{line}")
|
||||
y+=15
|
||||
# myCanvas.drawString(225, h-515, f"{requestItem.icd10_code}")
|
||||
myCanvas.line(50,h-y,w-50,h-y)
|
||||
#===============================================================================
|
||||
|
||||
#Signature
|
||||
y=750
|
||||
myCanvas.drawImage(imageSig, 50, h-y,100,100)
|
||||
myCanvas.line(50,h-y-10,200,h-y-10)
|
||||
myCanvas.drawString(50, h-y-30, requestItem.provider_name.upper())
|
||||
|
||||
#QR Verification
|
||||
qrText = f"{requestItem.document_type} generated on {issueDate} by {requestItem.busName} for {requestItem.patient_full_name}.\nPowered by Mzansi Innovation Hub."
|
||||
qrText = qrText.replace(" ","+")
|
||||
|
||||
url = f"https://api.qrserver.com/v1/create-qr-code/?data={qrText}&size=100x100"
|
||||
response = requests.get(url)
|
||||
image = ImageReader(io.BytesIO(response.content))
|
||||
myCanvas.drawImage(image,w-150, h-y-10,100,100)
|
||||
|
||||
myCanvas.setFont('Helvetica-Bold', 15)
|
||||
myCanvas.drawString(w-150,h-y-30,"Scan to verify")
|
||||
|
||||
myCanvas.save()
|
||||
|
||||
48
backend/routers/icd10_codes.py
Normal file
48
backend/routers/icd10_codes.py
Normal file
@@ -0,0 +1,48 @@
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from pydantic import BaseModel
|
||||
import os
|
||||
import xlrd
|
||||
#SuperToken Auth from front end
|
||||
from supertokens_python.recipe.session.framework.fastapi import verify_session
|
||||
from supertokens_python.recipe.session import SessionContainer
|
||||
from fastapi import Depends
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
#get all medicines
|
||||
@router.get("/icd10-codes/all", tags=["ICD10 Code"])
|
||||
async def read_all_icd10_codes(session: SessionContainer = Depends(verify_session())):
|
||||
return getICD10CodesData("")
|
||||
|
||||
#get all medicines by search
|
||||
@router.get("/icd10-codes/{search}", tags=["ICD10 Code"])
|
||||
async def read_icd10_codes_search(search: str, session: SessionContainer = Depends(verify_session())): #, session: SessionContainer = Depends(verify_session())
|
||||
return getICD10CodesData(search)
|
||||
|
||||
def getICD10CodesData(search: str):
|
||||
path = os.getcwd()
|
||||
#print(path)
|
||||
#parentDir = os.path.abspath(os.path.join(path, os.pardir))
|
||||
filePath = os.path.join(path, "ICD10_Codes", "ICD-10_MIT_2021_Excel_16-March_2021.xls")
|
||||
print(f'========================= %s ===============================',filePath)
|
||||
book = xlrd.open_workbook_xls(filePath)
|
||||
sh = book.sheet_by_index(0)
|
||||
codeList = []
|
||||
for rx in range(1,sh.nrows):
|
||||
if(str(sh.cell_value(rx, 7)).strip() != ""
|
||||
and search.lower() in str(sh.cell_value(rx, 7)).strip().lower()
|
||||
or search.lower() in str(sh.cell_value(rx, 8)).strip().lower()):
|
||||
codeList.append({
|
||||
"icd10": str(sh.cell_value(rx, 7)).strip(),
|
||||
"description": str(sh.cell_value(rx, 8)).strip(),
|
||||
})
|
||||
seen = set()
|
||||
codeList_noDuplicates = []
|
||||
for d in codeList:
|
||||
t = tuple(d.items())
|
||||
#print(t[0][1])
|
||||
if t not in seen:
|
||||
seen.add(t)
|
||||
codeList_noDuplicates.append(d)
|
||||
return sorted(codeList_noDuplicates, key=lambda d: d['icd10']) #qsort(medlist)
|
||||
|
||||
Reference in New Issue
Block a user