コード例 #1
0
    def post(self):
        import api.util as util
        import data.crud as crud
        import service.assoc as assoc
        from models import Patient

        try:
            request_body = _get_request_body()
        except:
            return {"HTTP 400": decoding_error}, 400
        if not request_body["patientId"]:
            return {"HTTP 400": "Patient Id is empty."}, 400

        # Emulate old API functionality with new systems, use of /api/associations is
        # preferred over this method now
        patient = crud.read(Patient, patientId=request_body["patientId"])
        if patient:
            user = util.current_user()
            facility = user.healthFacility
            if not assoc.has_association(patient, facility, user):
                assoc.associate(patient, facility, user)
            else:
                abort(409, message="Duplicate entry")
            return {
                "message": "patient has been added to facility successfully"
            }, 201
        else:
            abort(404, message="This patient does not exist.")
コード例 #2
0
    def post():
        json = request.get_json(force=True)

        # Populate the dateAssessed and healthCareWorkerId fields of the followup
        json["dateAssessed"] = get_current_time()
        user = util.current_user()
        json["healthcareWorkerId"] = user.id

        error_message = assessments.validate(json)
        if error_message is not None:
            abort(400, message=error_message)

        follow_up = marshal.unmarshal(FollowUp, json)

        # Check that reading id which doesn’t reference an existing reading in the database
        reading = crud.read(Reading, readingId=follow_up.readingId)
        if not reading:
            abort(404, message=f"No reading with id {follow_up.readingId}")

        crud.create(follow_up)

        # Creating an assessment also marks any referral attached to the associated
        # reading as "assessed"
        if follow_up.reading.referral:
            follow_up.reading.referral.isAssessed = True
            data.db_session.commit()

        return follow_up.id, 201
コード例 #3
0
    def post():
        json = request.get_json(force=True)

        # Populate the dateAssessed and healthCareWorkerId fields of the followup
        json["dateAssessed"] = get_current_time()
        user = util.current_user()
        json["healthcareWorkerId"] = user.id

        error_message = assessments.validate(json)
        if error_message is not None:
            abort(400, message=error_message)

        # TODO: validate that assessment's reading id references an actual reading and
        #   return 404 if it doesn't

        follow_up = marshal.unmarshal(FollowUp, json)

        crud.create(follow_up)

        # Creating an assessment also marks any referral attached to the associated
        # reading as "assessed"
        if follow_up.reading.referral:
            follow_up.reading.referral.isAssessed = True
            data.db_session.commit()

        return follow_up.id, 201
コード例 #4
0
    def post():
        json = request.get_json(force=True)
        error_message = patients.validate(json)
        if error_message is not None:
            abort(400, message=error_message)
        patient = marshal.unmarshal(Patient, json)

        if crud.read(Patient, patientId=patient.patientId):
            abort(409, message=f"A patient already exists with id: {patient.patientId}")

        # Resolve invariants and set the creation timestamp for the patient ensuring
        # that both the created and lastEdited fields have the exact same value.
        invariant.resolve_reading_invariants(patient)
        creation_time = get_current_time()
        patient.created = creation_time
        patient.lastEdited = creation_time

        crud.create(patient, refresh=True)

        # Associate the patient with the user who created them
        user = util.current_user()
        assoc.associate_by_user_role(patient, user)

        # If the patient has any readings, and those readings have referrals, we
        # associate the patient with the facilities they were referred to
        for reading in patient.readings:
            referral = reading.referral
            if referral and not assoc.has_association(patient, referral.healthFacility):
                assoc.associate(patient, facility=referral.healthFacility)
                # The associate function performs a database commit, since this will
                # wipe out the patient we want to return we must refresh it.
                data.db_session.refresh(patient)
        return marshal.marshal(patient), 201
コード例 #5
0
 def get():
     user = util.current_user()
     patients = view.patient_view_for_user(user)
     if util.query_param_bool(request, name="simplified"):
         # TODO: Compute simplified view for each patient
         return []
     else:
         return [marshal.marshal(p) for p in patients]
コード例 #6
0
    def get():
        user = util.current_user()
        referrals = view.referral_view_for_user(user)

        # If the request does not specifically specify "all=true", then only return the
        # referrals which have not been assessed.
        if not util.query_param_bool(request, "all"):
            referrals = [r for r in referrals if not r.isAssessed]

        return [marshal.marshal(r) for r in referrals]
コード例 #7
0
    def post():
        # Get all patients for this user
        timestamp: int = request.args.get("since", None, type=int)
        if not timestamp:
            abort(400, message="'since' query parameter is required")

        #  ~~~~~~~~~~~~~~~~~~~~~~ new Logic ~~~~~~~~~~~~~~~~~~~~~~~~~~
        json = request.get_json(force=True)
        patients_on_server_chache = set()
        for r in json:
            if r.get("patientId") not in patients_on_server_chache:
                patient_on_server = crud.read(Patient,
                                              patientId=r.get("patientId"))
                if patient_on_server is None:
                    continue
                else:
                    patients_on_server_chache.add(patient_on_server.patientId)

            if crud.read(Reading, readingId=r.get("readingId")):
                continue
            else:
                error_message = readings.validate(r)
                if error_message is not None:
                    abort(400, message=error_message)
                reading = marshal.unmarshal(Reading, r)
                invariant.resolve_reading_invariants(reading)
                crud.create(reading, refresh=True)

        user = util.current_user()
        #     TODO: create custome DB calls for referral and followup

        all_patients = view.patient_view_for_user(user)
        new_readings = []
        new_referral = []
        new_followup = []
        for p in all_patients:
            for r in p["readings"]:
                if r["dateTimeTaken"] > timestamp:
                    new_readings.append(r)
                if (r["referral"] and r["referral"]["dateReferred"] > timestamp
                        and r["dateTimeTaken"] < timestamp):
                    new_referral.append(r["referral"])
                if (r["followup"] and r["followup"]["dateAssessed"] > timestamp
                        and r["dateTimeTaken"] < timestamp):
                    new_followup.append(r["followup"])

        return {
            "total": len(new_readings) + len(new_referral) + len(new_followup),
            "readings": new_readings,
            "newReferralsForOldReadings": new_referral,
            "newFollowupsForOldReadings": new_followup,
        }
コード例 #8
0
    def get():
        timestamp: int = request.args.get("since", None, type=int)
        if not timestamp:
            abort(400, message="'since' query parameter is required")

        # Get all patients for this user
        user = util.current_user()
        all_patients = view.patient_view_for_user(user)

        # New patients are patients who are created after the timestamp
        new_patients = [
            p.patientId for p in all_patients if p.created > timestamp
        ]

        # Edited patients are patients who were created before the timestamp but
        # edited after it
        edited_patients = [
            p.patientId for p in all_patients if p.created < p.lastEdited
            and p.created <= timestamp < p.lastEdited
        ]

        # New readings created after the timestamp for patients who where created before
        # the timestamp
        readings = []

        # New followups which were created after the timestamp for readings which were
        # created before the timestamp
        followups = []

        for p in all_patients:
            for r in p.readings:
                r_time = int(r.dateTimeTaken)
                if p.created <= timestamp < r_time:
                    readings.append(r.readingId)

                if r.followup and r_time < timestamp < int(
                        r.followup.dateAssessed):
                    followups.append(r.followup.id)

        return {
            "newPatients": new_patients,
            "editedPatients": edited_patients,
            "readings": readings,
            "followups": followups,
        }
コード例 #9
0
    def get():
        user = util.current_user()
        limit = util.query_param_limit(request, name="limit")
        page = util.query_param_page(request, name="page")
        sort_by = util.query_param_sortBy(request, name="sortBy")
        sort_dir = util.query_param_sortDir(request, name="sortDir")
        search = util.query_param_search(request, name="search")

        referrals = view.referral_view_for_user(
            user,
            limit=limit,
            page=page,
            sortBy=sort_by,
            sortDir=sort_dir,
            search=search,
        )

        return [serialize.serialize_referral(r) for r in referrals]
コード例 #10
0
    def post():
        json: dict = request.get_json(force=True)
        error_message = associations.validate(json)
        if error_message is not None:
            abort(400, message=error_message)

        patient_id = json.get("patientId")
        facility_name = json.get("healthFacilityName")
        user_id = json.get("userId")

        patient = crud.read(Patient, patientId=patient_id)
        if not patient:
            abort(400, message=f"No patient exists with id: {patient_id}")

        if facility_name:
            facility = crud.read(HealthFacility,
                                 healthFacilityName=facility_name)
            if not facility:
                abort(400,
                      message=f"No health facility with name: {facility_name}")
        else:
            facility = None

        if user_id:
            user = crud.read(User, id=user_id)
            if not user:
                abort(400, message=f"No user with id: {user_id}")
            #     if user exists but no health facility then assign the patient to the user's health facility
            facility = user.healthFacility
        else:
            user = None

        if not facility_name and not user_id:
            # If neither facility_name or user_id are present in the request, create a
            # associate patient with the current user's health facility
            user = util.current_user()
            assoc.associate(patient, user.healthFacility, user)
        else:
            # Otherwise, simply associate the provided models together
            if not assoc.has_association(patient, facility, user):
                assoc.associate(patient, facility, user)

        return {}, 201
コード例 #11
0
    def get():
        user = util.current_user()

        # query parameters for later SQL use
        limit = util.query_param_limit(request, name="limit")
        page = util.query_param_page(request, name="page")
        sort_by = util.query_param_sortBy(request, name="sortBy")
        sort_dir = util.query_param_sortDir(request, name="sortDir")
        search = util.query_param_search(request, name="search")

        patients = view.patient_view_for_user(
            user,
            limit=limit,
            page=page,
            sortBy=sort_by,
            sortDir=sort_dir,
            search=search,
        )

        # create JSON format
        return [serialize.serialize_patient(p) for p in patients]
コード例 #12
0
    def post(assessment_id: int):
        if not assessment_id:
            abort(404, message=f"Assessment id is required")
        json = request.get_json(force=True)

        json["dateAssessed"] = get_current_time()

        # get current UserID
        user = util.current_user()
        json["healthcareWorkerId"] = user.id

        assessment = crud.read(FollowUp, id=assessment_id)
        if not assessment:
            abort(404, message=f"No assessment with id {assessment_id}")

        json["readingId"] = assessment.readingId

        error_message = assessments.validate(json)
        if error_message is not None:
            abort(400, message=error_message)

        crud.update(FollowUp, json, id=assessment.id)

        return assessment.id, 201
コード例 #13
0
    def post():
        # Get all patients for this user
        user = util.current_user()
        timestamp: int = request.args.get("since", None, type=int)
        if not timestamp:
            abort(400, message="'since' query parameter is required")

        patients_to_be_added: [Patient] = []
        #  ~~~~~~~~~~~~~~~~~~~~~~ new Logic ~~~~~~~~~~~~~~~~~~~~~~~~~~
        json = request.get_json(force=True)
        for p in json:
            patient_on_server = crud.read(Patient,
                                          patientId=p.get("patientId"))
            if patient_on_server is None:
                error_message = patients.validate(p)
                if error_message is not None:
                    abort(400, message=error_message)

                patient = marshal.unmarshal(Patient, p)
                # # Resolve invariants and set the creation timestamp for the patient ensuring
                # # that both the created and lastEdited fields have the exact same value.
                invariant.resolve_reading_invariants_mobile(patient)
                creation_time = get_current_time()
                patient.created = creation_time
                patient.lastEdited = creation_time
                patients_to_be_added.append(patient)
            else:
                if (int(patient_on_server.lastEdited) < int(
                        p.get("lastEdited")) < timestamp):
                    if p.get("base"):
                        if p.get("base") != p.get("lastEdited"):
                            abort(
                                409,
                                message=
                                "Unable to merge changes, conflict detected",
                            )
                        del p["base"]

                    p["lastEdited"] = get_current_time()
                    crud.update(Patient, p, patientId=p["patientId"])
                #     TODO: revisit association logic
                if not assoc.has_association(patient_on_server, user=user):
                    assoc.associate(patient_on_server, user.healthFacility,
                                    user)

        # update association
        if patients_to_be_added:
            crud.create_all_patients(patients_to_be_added)
            for new_patient in patients_to_be_added:
                #     TODO: revisit association logic
                if not assoc.has_association(new_patient, user=user):
                    assoc.associate(new_patient, user.healthFacility, user)

        # read all the patients from the DB
        #     TODO: optimize to get only patients
        all_patients = view.patient_view_for_user(user)
        all_patients_edited_or_new = [
            p for p in all_patients if p["lastEdited"] > timestamp
        ]

        #  ~~~~~~~~~~~~~~~~~ old logic ~~~~~~~~~~~~~~~~~~~~
        # New patients are patients who are created after the timestamp
        # new_patients = [
        #     p["patientId"] for p in all_patients if p["created"] > timestamp
        # ]

        # Edited patients are patients who were created before the timestamp but
        # edited after it
        # edited_patients = [
        #     p["patientId"]
        #     for p in all_patients
        #     if p["created"] < p["lastEdited"]
        #     and p["created"] <= timestamp < p["lastEdited"]
        # ]

        # New readings created after the timestamp for patients who where created before
        # the timestamp
        # readings = []

        # New followups which were created after the timestamp for readings which were
        # created before the timestamp
        # followups = []
        #
        # for p in all_patients:
        #     for r in p["readings"]:
        #         r_time = int(r["dateTimeTaken"])
        #         if p["created"] <= timestamp < r_time:
        #             readings.append(r["readingId"])
        #
        #         if r["followup"] and r_time < timestamp < int(
        #             r["followup"]["dateAssessed"]
        #         ):
        #             followups.append(r["followup"]["id"])

        return {
            "total": len(all_patients_edited_or_new),
            "patients": all_patients_edited_or_new,
        }
コード例 #14
0
    def get():
        user = util.current_user()
        patients = view.patient_view_for_user(user)

        return patients, 200