]> Softwares of Agnibho - librevax.git/blob - librevax.py
Database dump
[librevax.git] / librevax.py
1 # LibreVax
2 # Copyright (C) 2024 Dr. Agnibho Mondal
3 # This file is part of LibreVax.
4 # LibreVax is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
5 # LibreVax is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
6 # You should have received a copy of the GNU General Public License along with LibreVax. If not, see <https://www.gnu.org/licenses/>.
7
8 from flask import Flask, render_template, request, session, redirect, send_file, g
9 from urllib.parse import urlencode
10 from datetime import datetime
11 import json, sqlite3
12 import advice, auth, inventory, multicenter, patient, personnel, transaction, vaccination
13
14 app=Flask(__name__)
15 app.config.from_file("config/config.json", load=json.load)
16
17 @app.before_request
18 def preload():
19 g.user=session.get("user", None)
20 g.auth=session.get("auth", None)
21 g.mid=session.get("mid", None)
22 g.center=session.get("center", None)
23 g.enable_delete=app.config.get("ENABLE_DELETE", False) or g.user=="admin"
24
25 @app.route("/")
26 def index():
27 try:
28 cursor=get_db().cursor()
29 (ok, mc)=multicenter.read(cursor, session["mid"])
30 if(not ok):
31 raise exception(mc)
32 (ok, pat)=patient.list(cursor)
33 if(not ok):
34 raise exception(pat)
35 return render_template("index.html", center=mc, patient=pat)
36 except KeyError as e:
37 return redirect("/login")
38 except Exception as e:
39 raise(e)
40 return render_template("error.html", data=e)
41
42 @app.get("/login")
43 def login_get(error=False):
44 try:
45 cursor=get_db().cursor()
46 (ok, data)=multicenter.list(cursor)
47 if(not ok):
48 raise exception(data)
49 if(len(data)<=0):
50 data.append("")
51 return render_template("login.html", data=data, error=error)
52 except Exception as e:
53 return render_template("error.html", data=e)
54
55 @app.post("/login")
56 def login_post():
57 cursor=get_db().cursor()
58 if(auth.login(cursor, request.form["user"], request.form["password"], request.form["center"])):
59 return redirect("/")
60 else:
61 return login_get(True)
62
63 @app.route("/logout")
64 def logout():
65 auth.logout()
66 return redirect("/login")
67
68 @app.get("/admin")
69 def admin(msg=None):
70 if((ret:=problem())!="go"):
71 return ret
72 cursor=get_db().cursor()
73 (ok, mc)=multicenter.list(cursor)
74 if(not ok):
75 raise Exception(mc)
76 users=auth.list(cursor)
77 return render_template("admin.html", users=users, auth=auth.auth, center=mc, msg=msg)
78
79 @app.post("/newuser")
80 def newuser():
81 if((ret:=problem())!="go"):
82 return ret
83 try:
84 cursor=get_db().cursor()
85 if(auth.new(cursor, request.form["user"], request.form["pwd"], request.form["auth"])):
86 return admin(msg="New user added")
87 else:
88 return admin(msg="Failed to add")
89 except Exception as e:
90 raise(e)
91 return render_template("error.html", data=e)
92
93 @app.post("/changepass")
94 def changepass():
95 if((ret:=problem())!="go"):
96 return ret
97 try:
98 cursor=get_db().cursor()
99 if("user" in request.form.keys()):
100 if(auth.changePass(cursor, request.form["user"], request.form["new"])):
101 return admin(msg="Password changed")
102 else:
103 return admin(msg="Incorrect Password")
104 elif(request.form["new"]==request.form["check"]):
105 user=request.form.get("user", session["user"])
106 if(auth.changePass(cursor, user, request.form["new"], request.form["old"])):
107 return admin(msg="Password changed")
108 else:
109 return admin(msg="Incorrect Password")
110 else:
111 return admin(msg="Failed to change password")
112 except Exception as e:
113 raise(e)
114 return render_template("error.html", data=e)
115
116 @app.post("/changeauth")
117 def changeauth():
118 if((ret:=problem())!="go"):
119 return ret
120 try:
121 cursor=get_db().cursor()
122 if(g.auth==auth.auth.ALL and "user" in request.form.keys() and "auth" in request.form.keys()):
123 if(auth.changeAuth(cursor, request.form["user"], request.form["auth"])):
124 return admin(msg="Authorization changed")
125 else:
126 return admin(msg="Failed to change authorization")
127 else:
128 return admin(msg="Failed to change authorization")
129 except Exception as e:
130 raise(e)
131 return render_template("error.html", data=e)
132
133 @app.post("/deluser")
134 def deluser():
135 if((ret:=problem())!="go"):
136 return ret
137 try:
138 cursor=get_db().cursor()
139 if("user" in request.form.keys()):
140 if(auth.delete(cursor, request.form["user"])):
141 return admin(msg="User deleted")
142 else:
143 return admin(msg="Failed to delete")
144 else:
145 return admin(msg="Failed to delete")
146 except Exception as e:
147 raise(e)
148 return render_template("error.html", data=e)
149
150 @app.post("/switchcenter")
151 def switchcenter():
152 try:
153 cursor=get_db().cursor()
154 if(auth.switch(cursor, request.form)):
155 return admin(msg="Switched center to "+g.center)
156 else:
157 raise Exception("Failed to switch")
158 except Exception as e:
159 raise(e)
160 return render_template("error.html", data=e)
161
162 @app.get("/center/<action>")
163 @app.get("/center/<action>/<mid>")
164 def center_view(action, mid=None):
165 if((ret:=problem())!="go"):
166 return ret
167 try:
168 cursor=get_db().cursor()
169 if(action=="list"):
170 (ok, data)=multicenter.list(cursor)
171 if(not ok):
172 raise exception(data)
173 return render_template("multicenter-view.html", data=data, action=action)
174 elif(action=="view"):
175 if(mid is not None):
176 (ok, data)=multicenter.read(cursor, mid)
177 if(not ok):
178 raise Exception(data)
179 (ok, invt)=inventory.list(cursor, mid)
180 if(not ok):
181 raise Exception(invt)
182 (ok, pers)=personnel.list(cursor, mid)
183 if(not ok):
184 raise Exception(pers)
185 return render_template("multicenter-view.html", data=data, inventory=invt, personnel=pers, action=action)
186 else:
187 raise Exception("Invalid parameter")
188 elif(action=="edit"):
189 if(mid is not None):
190 (ok, data)=multicenter.read(cursor, mid)
191 if(not ok):
192 raise Exception(data)
193 return render_template("multicenter-edit.html", data=data, action=action)
194 else:
195 raise Exception("Invalid parameter")
196 elif(action=="new"):
197 return render_template("multicenter-edit.html", data=[], action=action)
198 except Exception as e:
199 raise(e)
200 return render_template("error.html", data=e)
201
202 @app.get("/personnel/<action>")
203 @app.get("/personnel/<action>/<sid>")
204 def personnel_view(action, sid=None):
205 if((ret:=problem())!="go"):
206 return ret
207 try:
208 cursor=get_db().cursor()
209 if(action=="list"):
210 (ok, data)=personnel.list(cursor, g.mid)
211 if(not ok):
212 raise exception(data)
213 return render_template("personnel-view.html", data=data, action=action)
214 elif(action=="view"):
215 if(sid is not None):
216 (ok, data)=personnel.read(cursor, sid)
217 if(not ok):
218 raise Exception(data)
219 return render_template("personnel-view.html", data=data, action=action)
220 else:
221 raise Exception("Invalid parameter")
222 elif(action=="edit"):
223 if(sid is not None):
224 (ok, data)=personnel.read(cursor, sid)
225 if(not ok):
226 raise Exception(data)
227 (ok, center)=multicenter.list(cursor)
228 if(not ok):
229 raise Exception(center)
230 return render_template("personnel-edit.html", data=data, center=center, action=action)
231 else:
232 raise Exception("Invalid parameter")
233 elif(action=="new"):
234 (ok, center)=multicenter.list(cursor)
235 if(not ok):
236 raise Exception(center)
237 return render_template("personnel-edit.html", data=[], center=center, action=action)
238 except Exception as e:
239 raise(e)
240 return render_template("error.html", data=e)
241
242 @app.post("/personnel/new")
243 @app.post("/personnel/edit/<sid>")
244 def personnel_edit(sid=None):
245 if((ret:=problem())!="go"):
246 return ret
247 try:
248 cursor=get_db().cursor()
249 if(sid is None):
250 active="active" in request.form.keys()
251 (ok, data)=personnel.create(cursor, request.form, active)
252 if(not ok):
253 raise Exception(data)
254 sid=data
255 else:
256 active="active" in request.form.keys()
257 (ok, data)=personnel.update(cursor, sid, request.form, active)
258 if(not ok):
259 raise Exception(data)
260 return redirect("/personnel/view/"+str(sid))
261 except Exception as e:
262 return render_template("error.html", data=e)
263
264 @app.post("/center/new")
265 @app.post("/center/edit/<mid>")
266 def center_edit(mid=None):
267 if((ret:=problem())!="go"):
268 return ret
269 try:
270 cursor=get_db().cursor()
271 if(mid is None):
272 (ok, data)=multicenter.create(cursor, request.form)
273 if(not ok):
274 raise Exception(data)
275 mid=data
276 else:
277 (ok, data)=multicenter.update(cursor, mid, request.form)
278 if(not ok):
279 raise Exception(data)
280 return redirect("/center/view/"+str(mid))
281 except Exception as e:
282 return render_template("error.html", data=e)
283
284 @app.get("/inventory/<action>")
285 @app.get("/inventory/<action>/<id>")
286 def inventory_view(action, id=None):
287 if((ret:=problem())!="go"):
288 return ret
289 try:
290 cursor=get_db().cursor()
291 if(action=="list"):
292 if(id is not None):
293 (ok, data)=inventory.list(cursor, id, all=True)
294 if(not ok):
295 raise exception(data)
296 (ok, center)=multicenter.read(cursor, id)
297 if(not ok):
298 raise exception(center)
299 return render_template("inventory-view.html", data=data, center=center, action=action)
300 else:
301 raise Exception("Invalid parameter")
302 elif(action=="view"):
303 if(id is not None):
304 (ok, data)=inventory.read(cursor, id)
305 if(not ok):
306 raise Exception(data)
307 return render_template("inventory-view.html", data=data, action=action)
308 else:
309 raise Exception("Invalid parameter")
310 elif(action=="edit"):
311 if(id is not None):
312 (ok, data)=inventory.read(cursor, id)
313 if(not ok):
314 raise Exception(data)
315 return render_template("inventory-edit.html", data=data, mid=data["mid"], action=action)
316 else:
317 raise Exception("Invalid parameter")
318 elif(action=="new"):
319 if(id is not None):
320 (ok, center)=multicenter.list(cursor)
321 if(not ok):
322 raise Exception(center)
323 return render_template("inventory-edit.html", data=[], mid=id, action=action, center=center)
324 else:
325 raise Exception("Invalid parameter")
326 except Exception as e:
327 raise(e)
328 return render_template("error.html", data=e)
329
330 @app.post("/inventory/new/<mid>")
331 @app.post("/inventory/edit/<iid>")
332 def inventory_edit(mid=None, iid=None):
333 if((ret:=problem())!="go"):
334 return ret
335 try:
336 cursor=get_db().cursor()
337 if(iid is None):
338 available="available" in request.form.keys()
339 (ok, data)=inventory.create(cursor, request.form, available)
340 if(not ok):
341 raise Exception(data)
342 iid=data
343 else:
344 available="available" in request.form.keys()
345 (ok, data)=inventory.update(cursor, iid, request.form, available)
346 if(not ok):
347 raise Exception(data)
348 return redirect("/inventory/view/"+str(iid))
349 except Exception as e:
350 raise(e)
351 return render_template("error.html", data=e)
352
353 @app.get("/transaction/<action>")
354 @app.get("/transaction/<action>/<id>")
355 def transaction_view(action, id=None):
356 if((ret:=problem())!="go"):
357 return ret
358 try:
359 cursor=get_db().cursor()
360 if(action=="list"):
361 if(id is not None):
362 (ok, data)=transaction.list(cursor, id)
363 if(not ok):
364 raise Exception(data)
365 (ok, item)=inventory.read(cursor, id)
366 if(not ok):
367 raise Exception(item)
368 (ok, administered)=vaccination.list_by_inventory(cursor, id)
369 if(not ok):
370 raise Exception(administered)
371 usedDosage=0
372 for used in administered:
373 usedDosage=usedDosage+int(float(used["dosage"]))
374 stockVial=0
375 for entry in data:
376 if(entry["action"]=="IN"):
377 stockVial=stockVial+int(float(entry["target"]))
378 elif(entry["action"]=="OUT"):
379 stockVial=stockVial-int(float(entry["target"]))
380 return render_template("transaction-view.html", data=data, item=item, administered=administered, usage=usedDosage, stock=stockVial, action=action)
381 else:
382 raise Exception("Invalid parameter")
383 elif(action=="view"):
384 if(id is not None):
385 (ok, data)=transaction.read(cursor, id)
386 if(not ok):
387 raise Exception(data)
388 (ok, item)=inventory.read(cursor, data["iid"])
389 if(not ok):
390 raise Exception(item)
391 return render_template("transaction-view.html", data=data, action=action, item=item)
392 else:
393 raise Exception("Invalid parameter")
394 elif(action=="edit"):
395 if(id is not None):
396 (ok, data)=transaction.read(cursor, id)
397 if(not ok):
398 raise Exception(data)
399 (ok, item)=inventory.read(cursor, data["iid"])
400 if(not ok):
401 raise Exception(item)
402 return render_template("transaction-edit.html", data=data, iid=data["iid"], action=action, item=item)
403 else:
404 raise Exception("Invalid parameter")
405 elif(action=="new"):
406 if(id is not None):
407 (ok, item)=inventory.read(cursor, id)
408 if(not ok):
409 raise Exception(item)
410 data={"date":datetime.now().strftime("%Y-%m-%dT%H:%M:%S")}
411 return render_template("transaction-edit.html", data=data, iid=id, action=action, item=item)
412 else:
413 raise Exception("Invalid parameter")
414 except Exception as e:
415 raise(e)
416 return render_template("error.html", data=e)
417
418 @app.post("/transaction/new/<iid>")
419 @app.post("/transaction/edit/<tid>")
420 def transaction_edit(iid=None, tid=None):
421 if((ret:=problem())!="go"):
422 return ret
423 try:
424 cursor=get_db().cursor()
425 if(tid is None):
426 (ok, data)=transaction.create(cursor, request.form)
427 if(not ok):
428 raise Exception(data)
429 tid=data
430 else:
431 (ok, data)=transaction.update(cursor, tid, request.form)
432 if(not ok):
433 raise Exception(data)
434 return redirect("/transaction/view/"+str(tid))
435 except Exception as e:
436 raise(e)
437 return render_template("error.html", data=e)
438
439 @app.get("/patient/<action>")
440 @app.get("/patient/<action>/<pid>")
441 def patient_view(action, pid=None):
442 if((ret:=problem())!="go"):
443 return ret
444 try:
445 cursor=get_db().cursor()
446 if(action=="list"):
447 try:
448 page=int(request.args["page"])
449 except Exception:
450 page=1
451 if(request.args.get("all", False)):
452 (ok, data)=patient.list(cursor, request.args, g.mid)
453 else:
454 (ok, data)=patient.list(cursor, request.args)
455 if(ok):
456 param=dict(request.args)
457 param.pop("page", None)
458 return render_template("patient-list.html", num=app.config["LIST_LENGTH"], data=data, page=page, args=request.args, param=urlencode(param))
459 else:
460 raise Exception(data)
461 elif(action=="view"):
462 if(pid is not None):
463 (ok, data)=patient.read(cursor, pid)
464 if(not ok):
465 raise Exception(data)
466 (ok, vac)=vaccination.list_by_patient(cursor, pid)
467 if(not ok):
468 raise Exception(vac)
469 (ok, adv)=advice.list(cursor, pid)
470 if(not ok):
471 raise Exception(adv)
472
473 return render_template("patient-view.html", data=data, vaccination=vac, advice=adv, action=action)
474 else:
475 raise Exception("Invalid parameter")
476 elif(action=="edit"):
477 if(pid is not None):
478 (ok, data)=patient.read(cursor, pid)
479 if(not ok):
480 raise Exception(data)
481 (ok, center)=multicenter.list(cursor)
482 if(not ok):
483 raise exception(center)
484 return render_template("patient-edit.html", data=data, center=center, action=action)
485 else:
486 raise Exception("Invalid parameter")
487 elif(action=="new"):
488 (ok, last)=patient.last(cursor)
489 if(not ok):
490 raise Exception(last)
491 data={"lastCid": last["cid"]}
492 (ok, center)=multicenter.list(cursor)
493 if(not ok):
494 raise exception(center)
495 return render_template("patient-edit.html", data=data, center=center, action=action)
496 except Exception as e:
497 raise (e)
498 return render_template("error.html", data=e)
499
500 @app.post("/patient/new")
501 @app.post("/patient/edit/<pid>")
502 def patient_edit(pid=None):
503 if((ret:=problem())!="go"):
504 return ret
505 try:
506 cursor=get_db().cursor()
507 if(pid is None):
508 (ok, data)=patient.create(cursor, request.form)
509 if(not ok):
510 if(isinstance(data, sqlite3.IntegrityError)):
511 data=request.form
512 (ok, center)=multicenter.list(cursor)
513 if(not ok):
514 raise exception(center)
515 (ok, last)=patient.last(cursor)
516 if(not ok):
517 raise Exception(last)
518 data.lastCid=last["cid"]
519 return render_template("patient-edit.html", data=data, center=center, action="uniq")
520 else:
521 raise Exception(data)
522 pid=data
523 else:
524 (ok, data)=patient.update(cursor, pid, request.form)
525 if(not ok):
526 raise Exception(data)
527 return redirect("/patient/view/"+str(pid))
528 except Exception as e:
529 return render_template("error.html", data=e)
530
531 @app.get("/note/<pid>")
532 def note_get(pid):
533 if((ret:=problem())!="go"):
534 return ret
535 try:
536 cursor=get_db().cursor()
537 (ok, data)=patient.read(cursor, pid)
538 if(ok):
539 return render_template("note.html", data=data)
540 else:
541 return render_template("error.html", data=data)
542 except Exception as e:
543 raise(e)
544 return render_template("error.html", data=e)
545
546 @app.post("/note/<pid>")
547 def note_post(pid):
548 if((ret:=problem())!="go"):
549 return ret
550 try:
551 cursor=get_db().cursor()
552 (ok, data)=patient.note(cursor, pid, request.form)
553 if(not ok):
554 return render_template("error.html", data=data)
555 return redirect("/patient/view/"+str(pid))
556 except Exception as e:
557 raise(e)
558 return render_template("error.html", data=e)
559
560 @app.get("/vaccination/<action>")
561 @app.get("/vaccination/<action>/<id>")
562 def vaccination_view(action, id=None):
563 if((ret:=problem())!="go"):
564 return ret
565 try:
566 cursor=get_db().cursor()
567 if(action=="list"):
568 if(id is not None):
569 (ok, data)=vaccination.list_by_patient(cursor, id)
570 if(not ok):
571 raise exception(data)
572 (ok, pat)=patient.read(cursor, data["pid"])
573 if(not ok):
574 raise exception(patient)
575 (ok, inv)=inventory.list(cursor, data["iid"])
576 if(not ok):
577 raise exception(inventory)
578 return render_template("vaccination-view.html", data=data, patient=pat, inventory=inv, action=action)
579 else:
580 raise Exception("Invalid parameter")
581 elif(action=="view"):
582 if(id is not None):
583 (ok, data)=vaccination.read(cursor, id)
584 if(not ok):
585 raise Exception(data)
586 (ok, inv)=inventory.read(cursor, data["iid"])
587 if(not ok):
588 raise Exception(inv)
589 (ok, pat)=patient.read(cursor, data["pid"])
590 if(not ok):
591 raise Exception(pat)
592 (ok, consultant)=personnel.read(cursor, data["consultant"])
593 if(not ok):
594 raise Exception(consultant)
595 (ok, vaccinator)=personnel.read(cursor, data["vaccinator"])
596 if(not ok):
597 raise Exception(vaccinator)
598 return render_template("vaccination-view.html", data=data, inventory=inv, patient=pat, consultant=consultant, vaccinator=vaccinator, action=action)
599 else:
600 raise Exception("Invalid parameter")
601 elif(action=="edit"):
602 if(id is not None):
603 (ok, data)=vaccination.read(cursor, id)
604 if(not ok):
605 raise Exception(data)
606 (ok, inv)=inventory.list(cursor, g.mid)
607 if(not ok):
608 raise Exception(inv)
609 (ok, consultant)=personnel.list(cursor, g.mid, "consultant")
610 if(not ok):
611 raise Exception(consultant)
612 (ok, vaccinator)=personnel.list(cursor, g.mid, "vaccinator")
613 if(not ok):
614 raise Exception(vaccinator)
615 (ok, pat)=patient.read(cursor, data["pid"])
616 if(not ok):
617 raise Exception(pat)
618 return render_template("vaccination-edit.html", data=data, inventory=inv, consultant=consultant, vaccinator=vaccinator, patient=pat, action=action)
619 else:
620 raise Exception("Invalid parameter")
621 elif(action=="new"):
622 if(id is not None):
623 (ok, inv)=inventory.list(cursor, g.mid)
624 if(not ok):
625 raise Exception(inv)
626 (ok, consultant)=personnel.list(cursor, g.mid, "consultant")
627 if(not ok):
628 raise Exception(consultant)
629 (ok, vaccinator)=personnel.list(cursor, g.mid, "vaccinator")
630 if(not ok):
631 raise Exception(vaccinator)
632 (ok, pat)=patient.read(cursor, id)
633 if(not ok):
634 raise Exception(pat)
635 data={"pid": id, "date":datetime.now().strftime("%Y-%m-%dT%H:%M:%S")}
636 if(len(inv)<=0):
637 raise Exception("Please add a vaccine to inventory before vaccination.")
638 return render_template("vaccination-edit.html", data=data, inventory=inv, consultant=consultant, vaccinator=vaccinator, patient=pat, action=action)
639 else:
640 raise Exception("Invalid parameter")
641 except Exception as e:
642 return render_template("error.html", data=e)
643
644 @app.post("/vaccination/new/<pid>")
645 @app.post("/vaccination/edit/<vid>")
646 def vaccination_edit(vid=None, pid=None):
647 if((ret:=problem())!="go"):
648 return ret
649 try:
650 cursor=get_db().cursor()
651 if(vid is None):
652 given="given" in request.form.keys()
653 (ok, data)=vaccination.create(cursor, request.form, given)
654 if(not ok):
655 raise Exception(data)
656 vid=data
657 else:
658 given="given" in request.form.keys()
659 (ok, data)=vaccination.update(cursor, vid, request.form, given)
660 if(not ok):
661 raise Exception(data)
662 return redirect("/vaccination/view/"+str(vid))
663 except Exception as e:
664 raise(e)
665 return render_template("error.html", data=e)
666
667 @app.post("/mark")
668 def mark():
669 if((ret:=problem())!="go"):
670 return ret
671 try:
672 cursor=get_db().cursor()
673 (ok, data)=vaccination.mark(cursor, request.form["vid"], True)
674 if(not ok):
675 raise Exception(data)
676 return redirect("/vaccination/view/"+str(request.form["vid"]))
677 except Exception as e:
678 raise(e)
679 return render_template("error.html", data=e)
680
681 @app.get("/advice/<action>")
682 @app.get("/advice/<action>/<id>")
683 def advice_view(action, id=None):
684 if((ret:=problem())!="go"):
685 return ret
686 try:
687 cursor=get_db().cursor()
688 if(action=="list"):
689 if(id is not None):
690 (ok, data)=advice.list(cursor, id)
691 if(not ok):
692 raise exception(data)
693 (ok, pat)=patient.read(cursor, id)
694 if(not ok):
695 raise exception(patient)
696 return render_template("advice-view.html", data=data, patient=pat, action=action)
697 else:
698 raise Exception("Invalid parameter")
699 elif(action=="view"):
700 if(id is not None):
701 (ok, data)=advice.read(cursor, id)
702 if(not ok):
703 raise Exception(data)
704 (ok, pat)=patient.read(cursor, data["pid"])
705 if(not ok):
706 raise Exception(pat)
707 (ok, consultant)=personnel.read(cursor, data["consultant"])
708 if(not ok):
709 raise Exception(consultant)
710 return render_template("advice-view.html", data=data, patient=pat, consultant=consultant, action=action)
711 else:
712 raise Exception("Invalid parameter")
713 elif(action=="edit"):
714 if(id is not None):
715 (ok, data)=advice.read(cursor, g.mid)
716 if(not ok):
717 raise Exception(data)
718 (ok, consultant)=personnel.list(cursor, g.mid, "consultant")
719 if(not ok):
720 raise Exception(consultant)
721 return render_template("advice-edit.html", data=data, consultant=consultant, action=action)
722 else:
723 raise Exception("Invalid parameter")
724 elif(action=="new"):
725 if(id is not None):
726 (ok, consultant)=personnel.list(cursor, g.mid, "consultant")
727 if(not ok):
728 raise Exception(consultant)
729 data={"pid": id, "date":datetime.now().strftime("%Y-%m-%dT%H:%M:%S")}
730 return render_template("advice-edit.html", data=data, consultant=consultant, action=action)
731 else:
732 raise Exception("Invalid parameter")
733 except Exception as e:
734 raise(e)
735 return render_template("error.html", data=e)
736
737 @app.post("/advice/new/<pid>")
738 @app.post("/advice/edit/<aid>")
739 def advice_edit(aid=None, pid=None):
740 if((ret:=problem())!="go"):
741 return ret
742 try:
743 cursor=get_db().cursor()
744 if(aid is None):
745 (ok, data)=advice.create(cursor, request.form, pid)
746 if(not ok):
747 raise Exception(data)
748 aid=data
749 else:
750 (ok, data)=advice.update(cursor, aid, request.form)
751 if(not ok):
752 raise Exception(data)
753 return redirect("/advice/view/"+str(aid))
754 except Exception as e:
755 raise(e)
756 return render_template("error.html", data=e)
757
758 @app.get("/delete/<cat>/<id>")
759 def delete(cat, id):
760 if((ret:=problem())!="go"):
761 return ret
762 try:
763 if(not g.enable_delete):
764 raise Exception("Deleting record is not allowed.")
765 cursor=get_db().cursor()
766 if(cat=="advice"):
767 (ok, data)=advice.delete(cursor, id)
768 if(not ok):
769 return render_template("error.html", data=data)
770 elif(cat=="inventory"):
771 (ok, data)=inventory.delete(cursor, id)
772 if(not ok):
773 return render_template("error.html", data=data)
774 elif(cat=="center"):
775 (ok, data)=multicenter.delete(cursor, id)
776 if(not ok):
777 return render_template("error.html", data=data)
778 elif(cat=="patient"):
779 (ok, data)=patient.delete(cursor, id)
780 if(not ok):
781 return render_template("error.html", data=data)
782 elif(cat=="personnel"):
783 (ok, data)=personnel.delete(cursor, id)
784 if(not ok):
785 return render_template("error.html", data=data)
786 elif(cat=="transaction"):
787 (ok, data)=transaction.delete(cursor, id)
788 if(not ok):
789 return render_template("error.html", data=data)
790 elif(cat=="vaccination"):
791 (ok, data)=vaccination.delete(cursor, id)
792 if(not ok):
793 return render_template("error.html", data=data)
794 return redirect("/")
795 except Exception as e:
796 raise(e)
797 return render_template("error.html", data=e)
798
799 @app.route("/card/<pid>")
800 def card(pid):
801 if((ret:=problem())!="go"):
802 return ret
803 try:
804 cursor=get_db().cursor()
805 (ok, data)=patient.read(cursor, pid)
806 if(not ok):
807 raise Exception(data)
808 (ok, vac)=vaccination.list_by_patient(cursor, pid)
809 if(not ok):
810 raise Exception(vac)
811 (ok, adv)=advice.list(cursor, pid)
812 if(not ok):
813 raise Exception(adv)
814 (ok, center)=multicenter.read(cursor, g.mid)
815 if(not ok):
816 raise Exception(center)
817 return render_template("card.html", data=data, vaccination=vac, advice=adv, center=center)
818 except Exception as e:
819 raise(e)
820 return render_template("error.html", data=e)
821
822 @app.route("/report/<mid>")
823 def report(mid):
824 if((ret:=problem())!="go"):
825 return ret
826 try:
827 date=request.args.get("date", datetime.now().strftime("%Y-%m-%d"))
828 cursor=get_db().cursor()
829 (ok, data)=vaccination.list_by_date(cursor, date)
830 if(not ok):
831 raise Exception(data)
832 (ok, center)=multicenter.read(cursor, g.mid)
833 if(not ok):
834 raise Exception(center)
835 count={}
836 for i in data:
837 try:
838 count[i["vaccine"]]=count[i["vaccine"]]+i["dosage"]
839 except KeyError:
840 count[i["vaccine"]]=i["dosage"]
841 return render_template("report.html", data=data, count=count, center=center, date=date)
842 except Exception as e:
843 raise(e)
844 return render_template("error.html", data=e)
845
846 @app.get("/dump")
847 def dump(msg=None):
848 if((ret:=problem())!="go"):
849 return ret
850 try:
851 if(g.user!="admin"):
852 raise PermissionError
853 return send_file("data/database.db", as_attachment=True, download_name="backup-"+str(datetime.now())+".db")
854 except PermissionError as e:
855 return render_template("error.html", data="Access Denied")
856 except Exception as e:
857 raise(e)
858 return render_template("error.html", data=e)
859
860 def get_db():
861 db=getattr(g, "_database", None)
862 if db is None:
863 db=g._database=sqlite3.connect("data/database.db", isolation_level=None)
864 db.row_factory=sqlite3.Row
865 return db
866
867 @app.teardown_appcontext
868 def close_connection(exception):
869 db=getattr(g, "_database", None)
870 if db is not None:
871 db.close()
872
873 def problem(access=""):
874 if(auth.access()==auth.auth.ALL):
875 return "go"
876 else:
877 return render_template("error.html", data="Access denied")
878
879 @app.template_filter("format_date")
880 def format_date(date):
881 try:
882 if("T" in date):
883 dt=datetime.strptime(date, "%Y-%m-%dT%H:%M:%S")
884 return dt.strftime("%b %d, %Y, %I:%M %p")
885 else:
886 dt=datetime.strptime(date, "%Y-%m-%d")
887 return dt.strftime("%b %d, %Y")
888 except Exception as e:
889 return date
890
891 @app.template_filter("calculate_age")
892 def calculate_age(dob):
893 try:
894 today=datetime.today()
895 try:
896 born=datetime.strptime(dob, "%Y-%m-%d")
897 except ValueError:
898 born=datetime.strptime(dob, "%Y")
899 return today.year-born.year-((today.month, today.day)<(born.month, born.day))
900 except Exception as e:
901 return ""
902
903 def init_db():
904 with app.app_context():
905 db=get_db()
906 with app.open_resource("etc/schema.sql", mode="r") as f:
907 db.cursor().executescript(f.read())
908 db.commit()