Update AppUser Objecct to cater for all fields.

enable file generation of med cert
This commit is contained in:
2024-06-25 17:21:39 +02:00
parent fce5380390
commit 2fa2191a5f
23 changed files with 251 additions and 79 deletions

View File

@@ -0,0 +1,54 @@
import 'package:flutter/material.dart';
import 'package:patient_manager/components/myDateInput.dart';
class Medcertinput extends StatefulWidget {
final startDateController;
final endDateTextController;
final retDateTextController;
const Medcertinput({
super.key,
required this.startDateController,
required this.endDateTextController,
required this.retDateTextController,
});
@override
State<Medcertinput> createState() => _MedcertinputState();
}
class _MedcertinputState extends State<Medcertinput> {
@override
Widget build(BuildContext context) {
return SizedBox(
height: 250,
child: Column(
children: [
const SizedBox(height: 50.0),
SizedBox(
width: 700,
child: MyDateField(
controller: widget.startDateController,
LableText: "From",
),
),
const SizedBox(height: 25.0),
SizedBox(
width: 700,
child: MyDateField(
controller: widget.endDateTextController,
LableText: "Up to Including",
),
),
const SizedBox(height: 25.0),
SizedBox(
width: 700,
child: MyDateField(
controller: widget.retDateTextController,
LableText: "Return",
),
),
],
),
);
}
}

View File

@@ -3,62 +3,122 @@ import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:patient_manager/components/buildFilesList.dart';
import 'package:patient_manager/components/medCertInput.dart';
import 'package:patient_manager/components/myDateInput.dart';
import 'package:patient_manager/main.dart';
import 'package:patient_manager/objects/AppUser.dart';
import 'package:patient_manager/objects/Patient2.dart';
import 'package:patient_manager/objects/files.dart';
import 'package:http/http.dart' as http;
Future<List<PFile>> fetchNotes(String endpoint) async {
final response = await http.get(Uri.parse(endpoint));
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 {
throw Exception('failed to load patients');
}
}
import '../objects/patients.dart';
class PatientFiles extends StatefulWidget {
final int patientIndex;
const PatientFiles({super.key, required this.patientIndex});
final Patient selectedPatient;
const PatientFiles({
super.key,
required this.patientIndex,
required this.selectedPatient,
});
@override
State<PatientFiles> createState() => _PatientFilesState();
}
class _PatientFilesState extends State<PatientFiles> {
String endpoint = "http://localhost:80/files/patients/";
String apiUrlAddNote = "http://localhost:80/notes/insert/";
String endpointFiles = "http://localhost:80/files/patients/";
String endpointUser = "http://localhost:80/docOffices/user/";
String endpointGenFiles = "http://localhost:80/files/generate/";
String endpointInsertFiles = "http://localhost:80/files/insert/";
final startDateController = TextEditingController();
final endDateTextController = TextEditingController();
final retDateTextController = TextEditingController();
late Future<List<PFile>> futueFiles;
late String userEmail = "";
late AppUser appUser;
Future<void> addPatientNoteAPICall() async {
var response = await http.post(
Uri.parse(apiUrlAddNote),
Future<void> generateMedCert() async {
var response1 = await http.post(
Uri.parse(endpointGenFiles),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"note_name": startDateController.text,
"note_text": endDateTextController.text,
"patient_id": widget.patientIndex,
"fullName":
"${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}",
"docfname": "${appUser.title} ${appUser.fname} ${appUser.lname}",
"startDate": startDateController.text,
"endDate": endDateTextController.text,
"returnDate": retDateTextController.text,
}),
);
if (response.statusCode == 201) {
setState(() {
futueFiles = fetchNotes(endpoint + widget.patientIndex.toString());
});
// Navigator.of(context)
// .pushNamed('/patient-manager', arguments: widget.userEmail);
String message = "Successfully added Files";
messagePopUp(message);
print(response1.statusCode);
String fileName =
"Med-Cert-${widget.selectedPatient.first_name} ${widget.selectedPatient.last_name}-${startDateController.text}";
if (response1.statusCode == 200) {
var response2 = await http.post(
Uri.parse(endpointInsertFiles),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"file_path": fileName,
"file_name": fileName,
"patient_id": widget.patientIndex
}),
);
print(response2.statusCode);
if (response2.statusCode == 201) {
setState(() {
futueFiles =
fetchFiles(endpointFiles + widget.patientIndex.toString());
});
String message = "Successfully added file";
messagePopUp(message);
} else {
messagePopUp("error response 2");
}
} else {
messagePopUp("error");
messagePopUp("error respose 1");
}
}
Future<void> getUserDetails() async {
await getUserEmail();
var response = await http.get(Uri.parse(endpointUser + userEmail));
//print(response.body);
if (response.statusCode == 200) {
appUser =
AppUser.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
} else {
throw Exception('Failed to load user');
}
}
Future<void> getUserEmail() async {
final res = await client.auth.getUser();
if (res.user!.email != null) {
//print("emai not null");
userEmail = res.user!.email!;
//print(userEmail);
}
}
Future<List<PFile>> fetchFiles(String endpoint) async {
final response = await http.get(Uri.parse(endpoint));
//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 {
throw Exception('failed to load patients');
}
}
@@ -75,8 +135,9 @@ class _PatientFilesState extends State<PatientFiles> {
@override
void initState() {
futueFiles = fetchNotes(endpoint + widget.patientIndex.toString());
futueFiles = fetchFiles(endpointFiles + widget.patientIndex.toString());
//patientDetails = getPatientDetails() as Patient;
getUserDetails();
super.initState();
}
@@ -128,33 +189,18 @@ class _PatientFilesState extends State<PatientFiles> {
Text("Create Medical Certificate"),
],
),
content: SizedBox(
height: 250,
child: Column(
children: [
const SizedBox(height: 50.0),
SizedBox(
width: 700,
child: MyDateField(
controller: startDateController,
LableText: "From",
),
),
const SizedBox(height: 25.0),
SizedBox(
width: 700,
child: MyDateField(
controller: endDateTextController,
LableText: "Up to Including",
),
),
],
),
content: Medcertinput(
startDateController: startDateController,
endDateTextController:
endDateTextController,
retDateTextController:
retDateTextController,
),
actions: [
TextButton(
onPressed: () {
//addPatientNoteAPICall();
//getPatientDetails();
generateMedCert();
Navigator.pop(context);
//print(widget.patientIndex);
},

View File

@@ -12,7 +12,7 @@ Future<List<Note>> fetchNotes(String endpoint) async {
if (response.statusCode == 200) {
Iterable l = jsonDecode(response.body);
List<Note> notes = List<Note>.from(l.map((model) => Note.fromJson(model)));
print("Here notes");
//print("Here notes");
return notes;
} else {
throw Exception('failed to load patients');

View File

@@ -1,15 +1,39 @@
class AppUser {
final int idusers;
final String email;
final int idUser;
final String UserName;
final int docOffice_id;
final String fname;
final String lname;
final String title;
const AppUser(
this.idusers,
this.email,
this.docOffice_id,
);
const AppUser({
required this.idUser,
required this.UserName,
required this.docOffice_id,
required this.fname,
required this.lname,
required this.title,
});
factory AppUser.fromJson(dynamic json) {
return AppUser(json['idusers'], json['email'], json['docOffice_id']);
factory AppUser.fromJson(Map<String, dynamic> json) {
return switch (json) {
{
'idUser': int idUser,
'UserName': String UserName,
'docOffice_id': int docOffice_id,
'fname': String fname,
'lname': String lname,
'title': String title,
} =>
AppUser(
idUser: idUser,
UserName: UserName,
docOffice_id: docOffice_id,
fname: fname,
lname: lname,
title: title,
),
_ => throw const FormatException('Failed to load album.'),
};
}
}

View File

@@ -0,0 +1,47 @@
class Patient2 {
final int idpatients;
final String id_no;
final String first_name;
final String last_name;
final String email;
final String cell_no;
final String medical_aid_name;
final String medical_aid_no;
final String medical_aid_scheme;
final String address;
final int doc_office_id;
const Patient2(
this.idpatients,
this.id_no,
this.first_name,
this.last_name,
this.email,
this.cell_no,
this.medical_aid_name,
this.medical_aid_no,
this.medical_aid_scheme,
this.address,
this.doc_office_id,
);
factory Patient2.fromJson(dynamic json) {
return Patient2(
json['idpatients'],
json['id_no'],
json['first_name'],
json['last_name'],
json['email'],
json['cell_no'],
json['medical_aid_name'],
json['medical_aid_no'],
json['medical_aid_scheme'],
json['address'],
json['docOffice_id'],
);
}
String getIDNum() {
return id_no;
}
}

View File

@@ -34,6 +34,7 @@ class _PatientViewState extends State<PatientView> {
),
PatientFiles(
patientIndex: widget.selectedPatient.idpatients,
selectedPatient: widget.selectedPatient,
)
],
)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -17,17 +17,17 @@ endobj
endobj
4 0 obj
<<
/BitsPerComponent 8 /ColorSpace /DeviceRGB /Filter [ /ASCII85Decode /FlateDecode ] /Height 100 /Length 1025 /Subtype /Image
/BitsPerComponent 8 /ColorSpace /DeviceRGB /Filter [ /ASCII85Decode /FlateDecode ] /Height 100 /Length 1071 /Subtype /Image
/Type /XObject /Width 100
>>
stream
Gb"/`bAuB'$j6,$5OI6(.;K2G.':\dJiCr;Gk?H4FFs=pRRncIR22B/nOV>_3d5K!P>rOCFsNsE?*A6lRm61B<kN?Rn\2Vq3jXgQf"[&Nd[=PdpWMh=qmaCQV-Tt*Bm:R!6A'Gm<E;>?eLldiR<HsubGqXm&1]o-g,e;tMeEpkVgZaGpZ6[\foD\+n_O31lumgGgm/\iI5b1[*M*:De#_p5GFl,"o?17h3rb\djm,)]]9\0<dMQQ'Ad,m?]+rrRYMlmLNORKD3NZmrEQtd5,*U_ZVQ&qCEa7Wc[XMAEeZ2j/'X;2G"mmfCNsemW.BqVm^?a!S-*A"?FEj?:KtpW$-I_c9W5ZsF\mJKaFElGAn+6;;g`hGd3Q&-PX"S)(>p=8390Pd,X+-(pVEKf@;]@1Q69[h#X8`I+@i0&K9&0duFEC^SRkd37Q'I=f\X/RU4.-G%H=,D5rLI4DCNGf,eLrGU5M>9TT743:4$/FRk=K02g5#-.-!3TMf,:GQ]+:\)\hB"5L>sZ-4<<.(=@"%+n%5"+e'-:7h1la;@J[-4,3oIq6398OUa%dYqILBV?\D[>Z%q%N8d/_WmP))P:fb4q=UDLrE)WKCfg;%Wc1/QYr`W@S!+dJ=a@\Z0B[aiGI6+jCe!_j-eLW4W1LcW0%5Y9;V,H3M,M1W%78m67hO0XJO%NPUPOD7r3oi>[[Ai32/nN#6r%_;O(G0*/K!8b%j69l4[V3Lp_"g^+Cc20/RAAY;-JG$B+o>iipWJH_>PBuPVfuA:\-=Gh3uALJ/h8!TXE\Q5,0_Z*:ASo]mC:>H<]pE#lK7:G;^r_!g?Hbgl*Df)PSKh"@\qmh.df'GK\[l>CV2)#m*#,lMmBXtn&`_<NA=l8FbZmFr>;M/=`L!g'j2=LlV`$Nl:g1(PSKgriq&G:Sgnjr!nSeCYB;$*CMI(?<EWU5XJlXhko:N+^5W@rg%Ve`a\#@o!bI&qlsa[bme1BsWiX>m@[0^B_R^iHiL8u5II4Ys-W=&nhNLqEc<iO0)*n~>endstream
Gb"/b8TFnf$j6,$:HR1X8-GC230ea(RqW4&]DQtd)Y5hT9#S<2R'&'gpTX!mlmK->]IX`N@_9*\>H*:Hbn"@jWPU-di4\Qg4g(ebYJ^G]W)Ju3h2,E>EP#FWBbu,nI1MsRQW5'l)cl[_p-,Rbmk(WP@C1q%YO/oJCU^tfX0(4O5-229g\WIZc(N&-I<Dafj6egTX)D,1^/ZXGOO`=gqs7pC:Ypg@J,;''Dk5&#mWGp;^[cf&`S2`@pj<pZ.M(kOmk8i<eJb_#%m*++CY.k.^&JLA?'gs=5A8_mJ"$&(enIDXX0DF(<r?grV*i,!?B+]@@4P>[nPg$3[I%F/lofW*)2a32$$!5+Zs$RGrL_u-_q:&4EXc("Z-LI$6_1Fo7U'5*mGY,V`O?jh*N3nKCHL@7#jUS]7H0"9O/F.7(Rq+Pe=(RJTT6.bA_7a^LAqZ_gRGJ17=joM!#tC4[lU`6l)pk-=h`JgCqRsJlG.S=]9_Gfq-F<1nLf0h"5=:!m@K:n_nD%<J"#Yo0Ft4g\pQVN<INV2dOj5@aF.\pi.Mi;/LqkH::F3S]fN39i'+7;5-4ONKX#mi<SbQuK*kXakdMC`'k%9bTr&i4(=I0kL9dqM[tp-$LS_B3=LM6$((p-,Y`r0-bNbPmUP2Y&6[*t`bBB;\@Y>JW&QU03eqBlEa&]0WAR;:_dJ$I"XNk<@dn4J#Dpsa6oKK?Im',KS[sOL9$@`G/bJ\S-@T[!#.]g^E'q\O[C2[fcV=\g]X5e>Ll.BE%@!*mSh:ki^bh]7cYPW'&G\[QQm67WHrW?9mnC;TL<ZAjl2I9Hcf*SMNT[F.Ioq9a\RW]4(gA>`F$E7UH5(o^&6RH5a4uZ*I^gA%T[eH+iGNIEi<dYt-9"S2LSSHMtQ;'TFnl.YthoZ-ZLXe1`l-,m6(?Z7%^=CoRiH<5TXu=?0FoF6Km9YY@]cO44e$3DTLK,Y$l\F$J@9)R-$?cqk0+TSS>!K+*8jE6CXL=7mIeA*4$;O^nJZSKCC(O8:Sp,`Hh)[U0T!/PP8>EK>A&WS8G]04lK5nOR:KUcuYWC1XD!)a;#?gT~>endstream
endobj
5 0 obj
<<
/Contents 9 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 8 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /XObject <<
/FormXob.09be740384c9e55854408d2289092f07 4 0 R
/FormXob.dedcbf51b54970828e09ce961fd66ee7 4 0 R
>>
>> /Rotate 0 /Trans <<
@@ -42,7 +42,7 @@ endobj
endobj
7 0 obj
<<
/Author (anonymous) /CreationDate (D:20240625114453+00'00') /Creator (ReportLab PDF Library - www.reportlab.com) /Keywords () /ModDate (D:20240625114453+00'00') /Producer (ReportLab PDF Library - www.reportlab.com)
/Author (anonymous) /CreationDate (D:20240625151653+00'00') /Creator (ReportLab PDF Library - www.reportlab.com) /Keywords () /ModDate (D:20240625151653+00'00') /Producer (ReportLab PDF Library - www.reportlab.com)
/Subject (unspecified) /Title (untitled) /Trapped /False
>>
endobj
@@ -53,10 +53,10 @@ endobj
endobj
9 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 440
/Filter [ /ASCII85Decode /FlateDecode ] /Length 445
>>
stream
GasbV?Vc;.'ZJu*'^&=f`nITnHW7Ic%k^?'#PZ;AE@A1$`Plb6_-uV6(/n,(\bC<n]se]o0&#bs"l'BBk7j.HjIk;k&9jKJn'!dT+F"Oo/.+^3$2*=<M'4?RY[Bl9&L36A6G,QgrQlAul"KDdM_T6[EJLrdgEK9`gre=b\c"AU(jb%J5S1Nh`3*c]+/=tkbYOU3C9YEYh.&GY$gc=HNKad>:J;l-ZSf+qVMDJTh\KIrd#hMQnS0F5Yu]t?kp02;UtT:]ldp-?mBeL.f=H"TB]&YO)c`i<Cq#+E"q1GS4o$VA0?Op81i9Ak$DLH9eR`fJaL5E2o35[HUbd#&3V:A.]mH!*mr804$$;PI<dE`9Y,`q`nO^$K&LWd0B8I%K38g=F>K5ZU,V1;TVV6A6/e&9dq8Oe[9:=gQQ)1KrhhS<#A0"b@^&UIF[j_~>endstream
Gas2F:K)m"&B4*cMK`$48s>LS8%%a6)69OW6'!i*MaF-Lm.B$?[+2O,3b0A;g#%.g$O(5tg>>=*gi*\"'U4/]TUtJ#hdaNo1Z.F,iPiOS69d^P;`BTn#e\(Zo*6NX0Z(Iqn9=B&?Q'"k*K?Ut0h-=;cXP.1RZ!uWXfP3f[9Fl:U$"$("G(EMYOWV!1)cm"DI?M%_<^dRDXr>RK[6ktC=H-2/2nD1GG3&o5V$qfp#Z#;Tb1K_YQSTZ\6-jJZ;FbB3oS!oWD]g?oeEPe9'ZO]V+Z`+k-I;)T$!<HRP\)aJ)TmUo]X'^3\Lh>dPR4MW$&B#Wlt,"0"^^a]bX]il&=u#g-)a'?OeAmS'jLT,eBVL.%T<r=65?H\uABB1@sbYpYq9&/<V7o1(Iu`#(`!^`nG^ls$"s$-QSbJ1M)lMKh,1p_J`Sb1U^Q)q#O0)]0u~>endstream
endobj
xref
0 10
@@ -65,15 +65,15 @@ xref
0000000114 00000 n
0000000221 00000 n
0000000333 00000 n
0000001549 00000 n
0000001815 00000 n
0000001883 00000 n
0000002179 00000 n
0000002238 00000 n
0000001595 00000 n
0000001861 00000 n
0000001929 00000 n
0000002225 00000 n
0000002284 00000 n
trailer
<<
/ID
[<e1d4c65132325a1d566ff363713a4818><e1d4c65132325a1d566ff363713a4818>]
[<6b30cc1ade908a7927c384b5f230df56><6b30cc1ade908a7927c384b5f230df56>]
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
/Info 7 0 R
@@ -81,5 +81,5 @@ trailer
/Size 10
>>
startxref
2768
2819
%%EOF