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
@@ -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",
),
),
],
),
);
}
}
@@ -3,14 +3,114 @@ import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:patient_manager/components/buildFilesList.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/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:patient_manager/objects/files.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
Future<List<PFile>> fetchNotes(String endpoint) async { import '../objects/patients.dart';
class PatientFiles extends StatefulWidget {
final int 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 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> generateMedCert() async {
var response1 = await http.post(
Uri.parse(endpointGenFiles),
headers: <String, String>{
"Content-Type": "application/json; charset=UTF-8"
},
body: jsonEncode(<String, dynamic>{
"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,
}),
);
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 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)); final response = await http.get(Uri.parse(endpoint));
print(response.statusCode);
//print(response.statusCode);
//print(response.body); //print(response.body);
if (response.statusCode == 200) { if (response.statusCode == 200) {
Iterable l = jsonDecode(response.body); Iterable l = jsonDecode(response.body);
@@ -20,46 +120,6 @@ Future<List<PFile>> fetchNotes(String endpoint) async {
} else { } else {
throw Exception('failed to load patients'); throw Exception('failed to load patients');
} }
}
class PatientFiles extends StatefulWidget {
final int patientIndex;
const PatientFiles({super.key, required this.patientIndex});
@override
State<PatientFiles> createState() => _PatientFilesState();
}
class _PatientFilesState extends State<PatientFiles> {
String endpoint = "http://localhost:80/files/patients/";
String apiUrlAddNote = "http://localhost:80/notes/insert/";
final startDateController = TextEditingController();
final endDateTextController = TextEditingController();
late Future<List<PFile>> futueFiles;
Future<void> addPatientNoteAPICall() async {
var response = await http.post(
Uri.parse(apiUrlAddNote),
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,
}),
);
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);
} else {
messagePopUp("error");
}
} }
void messagePopUp(error) { void messagePopUp(error) {
@@ -75,8 +135,9 @@ class _PatientFilesState extends State<PatientFiles> {
@override @override
void initState() { void initState() {
futueFiles = fetchNotes(endpoint + widget.patientIndex.toString()); futueFiles = fetchFiles(endpointFiles + widget.patientIndex.toString());
//patientDetails = getPatientDetails() as Patient;
getUserDetails();
super.initState(); super.initState();
} }
@@ -128,33 +189,18 @@ class _PatientFilesState extends State<PatientFiles> {
Text("Create Medical Certificate"), Text("Create Medical Certificate"),
], ],
), ),
content: SizedBox( content: Medcertinput(
height: 250, startDateController: startDateController,
child: Column( endDateTextController:
children: [ endDateTextController,
const SizedBox(height: 50.0), retDateTextController:
SizedBox( retDateTextController,
width: 700,
child: MyDateField(
controller: startDateController,
LableText: "From",
),
),
const SizedBox(height: 25.0),
SizedBox(
width: 700,
child: MyDateField(
controller: endDateTextController,
LableText: "Up to Including",
),
),
],
),
), ),
actions: [ actions: [
TextButton( TextButton(
onPressed: () { onPressed: () {
//addPatientNoteAPICall(); //getPatientDetails();
generateMedCert();
Navigator.pop(context); Navigator.pop(context);
//print(widget.patientIndex); //print(widget.patientIndex);
}, },
@@ -12,7 +12,7 @@ Future<List<Note>> fetchNotes(String endpoint) async {
if (response.statusCode == 200) { if (response.statusCode == 200) {
Iterable l = jsonDecode(response.body); Iterable l = jsonDecode(response.body);
List<Note> notes = List<Note>.from(l.map((model) => Note.fromJson(model))); List<Note> notes = List<Note>.from(l.map((model) => Note.fromJson(model)));
print("Here notes"); //print("Here notes");
return notes; return notes;
} else { } else {
throw Exception('failed to load patients'); throw Exception('failed to load patients');
@@ -1,15 +1,39 @@
class AppUser { class AppUser {
final int idusers; final int idUser;
final String email; final String UserName;
final int docOffice_id; final int docOffice_id;
final String fname;
final String lname;
final String title;
const AppUser( const AppUser({
this.idusers, required this.idUser,
this.email, required this.UserName,
this.docOffice_id, required this.docOffice_id,
); required this.fname,
required this.lname,
required this.title,
});
factory AppUser.fromJson(dynamic json) { factory AppUser.fromJson(Map<String, dynamic> json) {
return AppUser(json['idusers'], json['email'], json['docOffice_id']); 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.'),
};
} }
} }
@@ -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;
}
}
@@ -34,6 +34,7 @@ class _PatientViewState extends State<PatientView> {
), ),
PatientFiles( PatientFiles(
patientIndex: widget.selectedPatient.idpatients, 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.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+13 -13
View File
@@ -17,17 +17,17 @@ endobj
endobj endobj
4 0 obj 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 /Type /XObject /Width 100
>> >>
stream 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 endobj
5 0 obj 5 0 obj
<< <<
/Contents 9 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 8 0 R /Resources << /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 << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /XObject <<
/FormXob.09be740384c9e55854408d2289092f07 4 0 R /FormXob.dedcbf51b54970828e09ce961fd66ee7 4 0 R
>> >>
>> /Rotate 0 /Trans << >> /Rotate 0 /Trans <<
@@ -42,7 +42,7 @@ endobj
endobj endobj
7 0 obj 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 /Subject (unspecified) /Title (untitled) /Trapped /False
>> >>
endobj endobj
@@ -53,10 +53,10 @@ endobj
endobj endobj
9 0 obj 9 0 obj
<< <<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 440 /Filter [ /ASCII85Decode /FlateDecode ] /Length 445
>> >>
stream 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 endobj
xref xref
0 10 0 10
@@ -65,15 +65,15 @@ xref
0000000114 00000 n 0000000114 00000 n
0000000221 00000 n 0000000221 00000 n
0000000333 00000 n 0000000333 00000 n
0000001549 00000 n 0000001595 00000 n
0000001815 00000 n 0000001861 00000 n
0000001883 00000 n 0000001929 00000 n
0000002179 00000 n 0000002225 00000 n
0000002238 00000 n 0000002284 00000 n
trailer trailer
<< <<
/ID /ID
[<e1d4c65132325a1d566ff363713a4818><e1d4c65132325a1d566ff363713a4818>] [<6b30cc1ade908a7927c384b5f230df56><6b30cc1ade908a7927c384b5f230df56>]
% ReportLab generated PDF document -- digest (http://www.reportlab.com) % ReportLab generated PDF document -- digest (http://www.reportlab.com)
/Info 7 0 R /Info 7 0 R
@@ -81,5 +81,5 @@ trailer
/Size 10 /Size 10
>> >>
startxref startxref
2768 2819
%%EOF %%EOF