from textwrap import wrap import io from datetime import datetime, date from typing import List import requests from fastapi import APIRouter, HTTPException, File, UploadFile, Form from fastapi.responses import FileResponse, JSONResponse from pydantic import BaseModel from minio import Minio import Minio_Storage from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import A4 from reportlab.lib.utils import ImageReader from reportlab.platypus import SimpleDocTemplate from supertokens_python.recipe.session.framework.fastapi import verify_session from supertokens_python.recipe.session import SessionContainer from fastapi import Depends import Minio_Storage.minioConnection router = APIRouter() class minioPullRequest(BaseModel): file_path: str class minioDeleteRequest(BaseModel): file_path: str class medCertUploud(BaseModel): app_id: str fullName: str id_no: str docfname: str busName: str busAddr: str busNo: str busEmail: str startDate: str endDate: str returnDate: str logo_path: str sig_path: str class perscription(BaseModel): name: str unit: str form: str fullForm: str quantity: str dosage: str times: str days: str repeats: str class perscriptionList(BaseModel): app_id: str fullName: str id_no: str docfname: str busName: str busAddr: str busNo: str busEmail: str logo_path: str 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 try: # print(f"env: {env}") # uploudFile(app_id, file.filename, extension[1], content) client = Minio_Storage.minioConnection.minioConnect(env) miniourl = client.presigned_get_object("mih", path) # if(env == "Dev"): # miniourl.replace("minio", "localhost") # temp = minioResponse.data#.encode('utf-8').strip() # print(temp) # print("=======================================================================") # temp = temp.decode('utf-8') #print(miniourl) except Exception as error: raise HTTPException(status_code=404, detail=miniourl) # return {"message": error} if(env == "Dev"): return { # 10.0.2.2 "minioURL": f"http://10.0.2.2:9000/mih/{app_id}/{folder}/{file_name}",#"http://localhost:9000/mih/{app_id}/{folder}/{file_name}", } else: return { "minioURL": miniourl, } @router.post("/minio/upload/file/", tags=["Minio"]) async def upload_File_to_user(file: UploadFile = File(...), app_id: str= Form(...), folder: str= Form(...), session: SessionContainer = Depends(verify_session())): extension = file.filename.split(".") content = file.file try: uploudFile(app_id, folder, file.filename, extension[1], content) except Exception as error: raise HTTPException(status_code=404, detail="Failed to Uploud Record") return {"message": f"Successfully Uploaded {file.filename}"} # return { # "app_id": app_id, # "file name": file.filename, # "extension": extension[0], # "file contents": file.file.read(), # } @router.delete("/minio/delete/file/", tags=["Minio"]) async def delete_File_of_user(requestItem: minioDeleteRequest, session: SessionContainer = Depends(verify_session())): #, session: SessionContainer = Depends(verify_session()) path = requestItem.file_path try: # uploudFile(app_id, file.filename, extension[1], content) client = Minio_Storage.minioConnection.minioConnect("Prod") minioError = client.remove_object("mih", path) except Exception as error: raise HTTPException(status_code=404, detail=minioError) # return {"message": error} return {"message": "Successfully deleted File"} # return { # "app_id": app_id, # "file name": file.filename, # "extension": extension[0], # "file contents": file.file.read(), # } # Get List of all files by patient @router.post("/minio/generate/med-cert/", tags=["Minio"]) async def upload_med_cert_to_user(requestItem: medCertUploud, session: SessionContainer = Depends(verify_session())): uploudMedCert(requestItem) return {"message": "Successfully Generated File"} @router.post("/minio/generate/perscription/", tags=["Minio"]) async def upload_perscription_to_user(requestItem: perscriptionList, session: SessionContainer = Depends(verify_session())): #, session: SessionContainer = Depends(verify_session()) 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("Prod") found = client.bucket_exists("mih") if not found: client.make_bucket("mih") else: print("Bucket already exists") fname = app_id + "/" + folder + "/" + fileName client.put_object("mih", fname, content, length=-1, part_size=10*1024*1024, content_type=f"application/{extension}") def uploudMedCert(requestItem: medCertUploud): client = Minio_Storage.minioConnection.minioConnect("Prod") generateMedCertPDF(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.app_id}/patient_files/Med-Cert-{requestItem.fullName}-{today}.pdf" client.fput_object("mih", fileName, "temp-med-cert.pdf") def generateMedCertPDF(requestItem: medCertUploud): 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() imageLogo = ImageReader(io.BytesIO(minioLogo)) minioSig = client.get_object("mih", new_sig_path).read() imageSig = ImageReader(io.BytesIO(minioSig)) w,h = A4 today = datetime.today().strftime('%d-%m-%Y') myCanvas = canvas.Canvas("temp-med-cert.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"Contact No.: {requestItem.busNo}") myCanvas.drawRightString(w - 50,h - 85, f"Email: {requestItem.busEmail}") myCanvas.line(50,h-150,w-50,h-150) #Todays Date myCanvas.setFont('Helvetica', 12) issueDate = str(today) myCanvas.drawRightString(w - 50,h - 180,issueDate) #Title myCanvas.setFont('Helvetica-Bold', 20) myCanvas.drawString(w-375, h - 200, "Medical Certificate") #Body myCanvas.setFont('Helvetica', 12) body = "" body += "This is to certify that " + requestItem.fullName.upper() + " (" + requestItem.id_no+ ") was seen by " + requestItem.docfname.upper() + " on " + requestItem.startDate + "." body += "\nHe/She is unfit to attend work/school from " + requestItem.startDate + " up to and including " + requestItem.endDate + "." body += "\nHe/She will return on " + requestItem.returnDate + "." y = 250 for line in wrap(body, 90): myCanvas.drawString(50, h-y, line) y += 30 # myCanvas.drawString(50, h-250,line1) # myCanvas.drawString(50, h-280,line2) # myCanvas.drawString(50, h-310,line3) #Signature myCanvas.drawImage(imageSig, 50, h - 690,100,100) myCanvas.line(50,h-700,200,h-700) myCanvas.drawString(50, h-720, requestItem.docfname.upper()) #QR Verification qrText = requestItem.fullName.upper() + " booked off from " + requestItem.startDate + " to " + requestItem.endDate + " by " + requestItem.docfname.upper() + ".\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-700,100,100) myCanvas.setFont('Helvetica-Bold', 15) myCanvas.drawString(w-150,h-720,"Scan to verify") myCanvas.save() def uploudPerscription(requestItem: perscriptionList): client = Minio_Storage.minioConnection.minioConnect("Prod") generatePerscriptionPDF(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.app_id}/patient_files/Perscription-{requestItem.fullName}-{today}.pdf" client.fput_object("mih", fileName, "temp-perscription.pdf") def generatePerscriptionPDF(requestItem: perscriptionList): 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() 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.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"Contact No.: {requestItem.busNo}") myCanvas.drawRightString(w - 50,h - 85, f"Email: {requestItem.busEmail}") myCanvas.line(50,h-150,w-50,h-150) #Todays Date myCanvas.setFont('Helvetica', 12) today = datetime.today() issueDate = today.strftime('%d-%m-%Y') myCanvas.drawRightString(w - 50,h - 180,issueDate) #Title myCanvas.setFont('Helvetica-Bold', 20) myCanvas.drawString(w-375, h - 200, "Perscription") #Body myCanvas.setFont('Helvetica-Bold', 12) myCanvas.drawString(50, h-250, f"Patient: {requestItem.fullName}") myCanvas.drawString(50, h-270, f"Patient ID: {requestItem.id_no}") #boday headings myCanvas.drawString(50, h-300, "Description") myCanvas.drawRightString(w - 50, h-300, "Repeat(s)") myCanvas.drawRightString(w - 150, h-300, "Quantity") myCanvas.line(50,h-310,w-50,h-310) myCanvas.setStrokeColorRGB(0.749, 0.749, 0.749) myCanvas.setFont('Helvetica', 12) y = 330 i = 0 for persc in requestItem.data: description1 = f"{persc.name} - {persc.form}" description2 = f"{persc.dosage} {persc.fullForm}, {persc.times} time(s) daily, for {persc.days} day(s)" quant = f"{persc.quantity}" reps = f"{persc.repeats}" myCanvas.drawString(50, h-y, f"{i+1}.") myCanvas.drawString(60, h-y, description1) myCanvas.drawRightString(w-75, h-y, reps) myCanvas.drawRightString(w-175, h-y, quant) y+=15 myCanvas.drawString(60, h-y, description2) if(i