From 8985cf1922c2b54a86e0ae400567d018007e6a32 Mon Sep 17 00:00:00 2001 From: Yasien Mac Mini Date: Tue, 20 May 2025 14:31:22 +0200 Subject: [PATCH] med cert and perscription --- .../pat_profile/components/prescip_input.dart | 18 ++- .../list_builders/build_files_list.dart | 14 +- .../package_tools/patient_documents.dart | 136 ++++++++++-------- backend/routers/fileStorage.py | 11 +- 4 files changed, 102 insertions(+), 77 deletions(-) diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/components/prescip_input.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/prescip_input.dart index 38b90e8e..f4e65682 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/components/prescip_input.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/components/prescip_input.dart @@ -31,6 +31,7 @@ class PrescripInput extends StatefulWidget { final AppUser signedInUser; final Business? business; final BusinessUser? businessUser; + final String env; const PrescripInput({ super.key, required this.medicineController, @@ -44,6 +45,7 @@ class PrescripInput extends StatefulWidget { required this.signedInUser, required this.business, required this.businessUser, + required this.env, }); @override @@ -98,6 +100,11 @@ class _PrescripInputState extends State { return const Mihloadingcircle(); }, ); + DateTime now = new DateTime.now(); + // DateTime date = new DateTime(now.year, now.month, now.day); + String fileName = + "Perscription-${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}-${now.toString().substring(0, 19)}.pdf" + .replaceAll(RegExp(r' '), '-'); var response1 = await http.post( Uri.parse("${AppEnviroment.baseApiUrl}/minio/generate/perscription/"), @@ -106,8 +113,10 @@ class _PrescripInputState extends State { }, body: jsonEncode({ "app_id": widget.selectedPatient.app_id, - "fullName": + "env": widget.env, + "patient_full_name": "${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}", + "fileName": fileName, "id_no": widget.selectedPatient.id_no, "docfname": "DR. ${widget.signedInUser.fname} ${widget.signedInUser.lname}", @@ -121,13 +130,9 @@ class _PrescripInputState extends State { }), ); //print(response1.statusCode); - DateTime now = new DateTime.now(); - DateTime date = new DateTime(now.year, now.month, now.day); - String fileName = - "Perscription-${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}-${date.toString().substring(0, 10)}.pdf"; if (response1.statusCode == 200) { var response2 = await http.post( - Uri.parse("${AppEnviroment.baseApiUrl}/files/insert/"), + Uri.parse("${AppEnviroment.baseApiUrl}/patient_files/insert/"), headers: { "Content-Type": "application/json; charset=UTF-8" }, @@ -155,6 +160,7 @@ class _PrescripInputState extends State { // end loading circle Navigator.of(context).pop(); Navigator.of(context).pop(); + Navigator.of(context).pop(); Navigator.of(context).pushNamed('/patient-manager/patient', arguments: PatientViewArguments( widget.signedInUser, diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_files_list.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_files_list.dart index 09ad0acd..260bc178 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_files_list.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/list_builders/build_files_list.dart @@ -60,7 +60,7 @@ class _BuildFilesListState extends State { Future deleteFileApiCall(String filePath, int fileID) async { var response = await MihFileApi.deleteFile( - widget.signedInUser.app_id, + widget.selectedPatient.app_id, widget.env, "patient_files", filePath.split("/").last, @@ -70,7 +70,6 @@ class _BuildFilesListState extends State { // delete file from database await deletePatientFileLocationToDB(fileID); } else { - Navigator.of(context).pop(); String message = "The File has not been deleted successfully. Please try again."; successPopUp(message); @@ -89,11 +88,16 @@ class _BuildFilesListState extends State { headers: { "Content-Type": "application/json; charset=UTF-8" }, - body: jsonEncode({"idpatient_files": fileID}), + body: jsonEncode({ + "idpatient_files": fileID, + "env": widget.env, + }), ); if (response2.statusCode == 200) { - Navigator.of(context).pop(); - Navigator.of(context).pop(); + Navigator.of(context).pop(); //Remove Loading Dialog + Navigator.of(context).pop(); //Remove Delete Dialog + Navigator.of(context).pop(); //Remove File View Dialog + Navigator.of(context).pop(); //Remove File List Dialog //print(widget.business); if (widget.business == null) { Navigator.of(context).pushNamed('/patient-manager/patient', diff --git a/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_documents.dart b/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_documents.dart index 54d78326..b4966ebf 100644 --- a/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_documents.dart +++ b/Frontend/lib/mih_packages/patient_profile/pat_profile/package_tools/patient_documents.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:mzansi_innovation_hub/main.dart'; +import 'package:mzansi_innovation_hub/mih_apis/mih_file_api.dart'; import 'package:mzansi_innovation_hub/mih_components/med_cert_input.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_file_input.dart'; @@ -22,9 +23,7 @@ import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/c import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/list_builders/build_files_list.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; -import 'package:supertokens_flutter/supertokens.dart'; import 'package:supertokens_flutter/http.dart' as http; -import 'package:http/http.dart' as http2; class PatientDocuments extends StatefulWidget { final int patientIndex; @@ -61,10 +60,24 @@ class _PatientDocumentsState extends State { final noRepeatsController = TextEditingController(); final outputController = TextEditingController(); late PlatformFile? selected; + late String env; + + Future submitDocUploadForm() async { + if (isFileFieldsFilled()) { + await uploadSelectedFile(selected); + } else { + showDialog( + context: context, + builder: (context) { + return const MIHErrorMessage(errorType: "Input Error"); + }, + ); + } + } Future> fetchFiles() async { final response = await http.get(Uri.parse( - "${AppEnviroment.baseApiUrl}/files/patients/${widget.selectedPatient.app_id}")); + "${AppEnviroment.baseApiUrl}/patient_files/get/${widget.selectedPatient.app_id}")); //print(response.statusCode); //print(response.body); if (response.statusCode == 200) { @@ -78,63 +91,53 @@ class _PatientDocumentsState extends State { } } - Future uploadSelectedFile(PlatformFile? file) async { - print("File: $file"); - //var strem = new http.ByteStream.fromBytes(file.bytes.) - //start loading circle + Future addPatientFileLocationToDB(PlatformFile? file) async { showDialog( context: context, builder: (context) { return const Mihloadingcircle(); }, ); - var token = await SuperTokens.getAccessToken(); - //print(t); - print("here1"); - var request = http2.MultipartRequest( - 'POST', Uri.parse("${AppEnviroment.baseApiUrl}/minio/upload/file/")); - request.headers['accept'] = 'application/json'; - request.headers['Authorization'] = 'Bearer $token'; - request.headers['Content-Type'] = 'multipart/form-data'; - request.fields['app_id'] = widget.selectedPatient.app_id; - request.fields['folder'] = "patient_files"; - request.files.add(await http2.MultipartFile.fromBytes('file', file!.bytes!, - filename: file.name.replaceAll(RegExp(r' '), '-'))); - print("here2"); - var response1 = await request.send(); - print("here3"); - print(response1.statusCode); - print(response1.toString()); - if (response1.statusCode == 200) { - //print("here3"); - var fname = file.name.replaceAll(RegExp(r' '), '-'); - var filePath = "${widget.selectedPatient.app_id}/patient_files/$fname"; - var response2 = await http.post( - Uri.parse("${AppEnviroment.baseApiUrl}/files/insert/"), - headers: { - "Content-Type": "application/json; charset=UTF-8" - }, - body: jsonEncode({ - "file_path": filePath, - "file_name": fname, - "app_id": widget.selectedPatient.app_id - }), - ); - //print("here5"); - //print(response2.statusCode); - if (response2.statusCode == 201) { - setState(() { - selectedFileController.clear(); - futueFiles = fetchFiles(); - }); - // end loading circle - Navigator.of(context).pop(); - String message = - "The file ${file.name.replaceAll(RegExp(r' '), '-')} has been successfully generated and added to ${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}'s record. You can now access and download it for their use."; - successPopUp(message); - } else { - internetConnectionPopUp(); - } + var fname = file!.name.replaceAll(RegExp(r' '), '-'); + var filePath = "${widget.selectedPatient.app_id}/patient_files/$fname"; + var response2 = await http.post( + Uri.parse("${AppEnviroment.baseApiUrl}/patient_files/insert/"), + headers: { + "Content-Type": "application/json; charset=UTF-8" + }, + body: jsonEncode({ + "file_path": filePath, + "file_name": fname, + "app_id": widget.selectedPatient.app_id + }), + ); + //print("here5"); + //print(response2.statusCode); + if (response2.statusCode == 201) { + setState(() { + selectedFileController.clear(); + futueFiles = fetchFiles(); + }); + // end loading circle + Navigator.of(context).pop(); + String message = + "The file ${file.name.replaceAll(RegExp(r' '), '-')} has been successfully generated and added to ${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}'s record. You can now access and download it for their use."; + successPopUp(message); + } else { + internetConnectionPopUp(); + } + } + + Future uploadSelectedFile(PlatformFile? file) async { + var response = await MihFileApi.uploadFile( + widget.selectedPatient.app_id, + env, + "patient_files", + file, + context, + ); + if (response == 200) { + await addPatientFileLocationToDB(file); } else { internetConnectionPopUp(); } @@ -148,6 +151,11 @@ class _PatientDocumentsState extends State { return const Mihloadingcircle(); }, ); + DateTime now = DateTime.now(); + // DateTime date = new DateTime(now.year, now.month, now.day); + String fileName = + "Med-Cert-${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}-${now.toString().substring(0, 19)}.pdf" + .replaceAll(RegExp(r' '), '-'); var response1 = await http.post( Uri.parse("${AppEnviroment.baseApiUrl}/minio/generate/med-cert/"), headers: { @@ -155,8 +163,10 @@ class _PatientDocumentsState extends State { }, body: jsonEncode({ "app_id": widget.selectedPatient.app_id, - "fullName": + "env": env, + "patient_full_name": "${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}", + "fileName": fileName, "id_no": widget.selectedPatient.id_no, "docfname": "DR. ${widget.signedInUser.fname} ${widget.signedInUser.lname}", @@ -172,13 +182,9 @@ class _PatientDocumentsState extends State { }), ); print(response1.statusCode); - DateTime now = new DateTime.now(); - DateTime date = new DateTime(now.year, now.month, now.day); - String fileName = - "Med-Cert-${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}-${date.toString().substring(0, 10)}.pdf"; if (response1.statusCode == 200) { var response2 = await http.post( - Uri.parse("${AppEnviroment.baseApiUrl}/files/insert/"), + Uri.parse("${AppEnviroment.baseApiUrl}/patient_files/insert/"), headers: { "Content-Type": "application/json; charset=UTF-8" }, @@ -256,7 +262,8 @@ class _PatientDocumentsState extends State { textColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), onTap: () { if (isFileFieldsFilled()) { - uploadSelectedFile(selected); + submitDocUploadForm(); + // uploadSelectedFile(selected); Navigator.pop(context); } else { showDialog( @@ -350,6 +357,7 @@ class _PatientDocumentsState extends State { signedInUser: widget.signedInUser, business: widget.business, businessUser: widget.businessUser, + env: env, ), ], ), @@ -576,6 +584,11 @@ class _PatientDocumentsState extends State { @override void initState() { futueFiles = fetchFiles(); + if (AppEnviroment.getEnv() == "Prod") { + env = "Prod"; + } else { + env = "Dev"; + } super.initState(); } @@ -629,6 +642,7 @@ class _PatientDocumentsState extends State { business: widget.business, businessUser: widget.businessUser, type: widget.type, + env: env, ), ]); } else { diff --git a/backend/routers/fileStorage.py b/backend/routers/fileStorage.py index 37807884..a2d56e1b 100644 --- a/backend/routers/fileStorage.py +++ b/backend/routers/fileStorage.py @@ -64,7 +64,8 @@ class perscription(BaseModel): class perscriptionList(BaseModel): app_id: str env: str - fullName: str + patient_full_name: str + fileName: str id_no: str docfname: str busName: str @@ -288,7 +289,7 @@ def uploudPerscription(requestItem: perscriptionList): client.make_bucket("mih") else: print("Bucket already exists") - fileName = f"{requestItem.app_id}/patient_files/Perscription-{requestItem.fullName}-{today}.pdf" + fileName = f"{requestItem.app_id}/patient_files/{requestItem.fileName}" client.fput_object("mih", fileName, "temp-perscription.pdf") def generatePerscriptionPDF(requestItem: perscriptionList): @@ -302,7 +303,7 @@ def generatePerscriptionPDF(requestItem: perscriptionList): w,h = A4 - myCanvas = canvas.Canvas("temp-claim.pdf", pagesize=A4) + myCanvas = canvas.Canvas("temp-perscription.pdf", pagesize=A4) #Business Logo myCanvas.drawImage(imageLogo, 50, h - 125,100,100, mask='auto') @@ -326,7 +327,7 @@ def generatePerscriptionPDF(requestItem: perscriptionList): #Body myCanvas.setFont('Helvetica-Bold', 12) - myCanvas.drawString(50, h-250, f"Patient: {requestItem.fullName}") + myCanvas.drawString(50, h-250, f"Patient: {requestItem.patient_full_name}") myCanvas.drawString(50, h-270, f"Patient ID: {requestItem.id_no}") #boday headings @@ -367,7 +368,7 @@ def generatePerscriptionPDF(requestItem: perscriptionList): myCanvas.drawString(50, h-y-30, requestItem.docfname.upper()) #QR Verification - qrText = f"Perscription generated on {issueDate} by {requestItem.docfname} for {requestItem.fullName}.\nPowered by Mzansi Innovation Hub." + qrText = f"Perscription generated on {issueDate} by {requestItem.docfname} 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"