Skip to content

Commit

Permalink
Caregiver CaseOverview component
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenny Vong authored and Jenny Vong committed Dec 4, 2023
1 parent e82777c commit 2985845
Show file tree
Hide file tree
Showing 20 changed files with 862 additions and 102 deletions.
17 changes: 13 additions & 4 deletions backend/python/app/models/caregiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,18 @@
from .base_mixin import BaseMixin

relationship_to_child_enum = db.Enum(
"FOSTER_CAREGIVER",
"KINSHIP_CAREGIVER",
"BIOLOGICAL_FAMILY",
"ADOPTIVE_PARENT",
"FOSTER_PARENT",
"BIOLOGICAL_PARENT",
"STEP_PARENT",
"MATERNAL_GRANDPARENT",
"PATERNAL_GRANDPARENT",
"SIBLING",
"STEP_SIBLING",
"HALF_SIBLING",
"UNCLE/AUNT",
"OTHER_RELATIVE",
"OTHER",
name="caregivers_relationship_to_child",
)

Expand All @@ -18,7 +27,7 @@ class Caregiver(db.Model, BaseMixin):
individual_considerations = db.Column(db.String, nullable=True)
primary_phone_number = db.Column(db.String, nullable=False)
secondary_phone_number = db.Column(db.String, nullable=True)
email = db.Column(db.String, nullable=False)
email = db.Column(db.String, nullable=True)
address = db.Column(db.String, nullable=False)
relationship_to_child = db.Column(relationship_to_child_enum, nullable=False)
additional_contact_notes = db.Column(db.String, nullable=True)
Expand Down
58 changes: 58 additions & 0 deletions backend/python/app/rest/caregiver_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,20 @@ def get_all_caregivers():
return jsonify(error), 400


# get all caregivers by intake_id
@blueprint.route("/<int:intake_id>", methods=["GET"], strict_slashes=False)
# @require_authorization_by_role({"Admin"})
def get_caregivers_by_intake_id(intake_id):
if intake_id:
if type(intake_id) is not int:
return jsonify({"error:" "intake_id query parameter must be an int"})
try:
caregivers = caregiver_service.get_caregivers_by_intake_id(intake_id)
return jsonify(list(map(lambda user: user.__dict__, caregivers))), 200
except Exception as error:
return jsonify(error), 400

Check warning

Code scanning / CodeQL

Information exposure through an exception Medium

Stack trace information
flows to this location and may be exposed to an external user.


# create a caregiver
@blueprint.route("/", methods=["POST"], strict_slashes=False)
# @require_authorization_by_role({"Admin"})
Expand All @@ -32,3 +46,47 @@ def create_caregiver():
return jsonify(new_caregiver.__dict__), 201
except Exception as error:
return jsonify(str(error)), 400


# update a caregiver
@blueprint.route("/<int:caregiver_id>", methods=["PUT"], strict_slashes=False)
def update_caregiver(caregiver_id):
try:
new_caregiver = request.json
updated_caregiver = caregiver_service.update_caregiver(
caregiver_id, new_caregiver
)
return jsonify(updated_caregiver.__dict__), 200

except Exception as error:
return jsonify(str(error)), 400

Check warning

Code scanning / CodeQL

Information exposure through an exception Medium

Stack trace information
flows to this location and may be exposed to an external user.


@blueprint.route("/", methods=["DELETE"], strict_slashes=False)
def delete_intake():
"""
Delete intake by caretgiver_id specified through a query parameter
"""
caregiver_id = int(request.args.get("caregiver_id"))

if caregiver_id:
if type(caregiver_id) is not int:
return (
jsonify({"error": "caregiver_id query parameter must be an int"}),
400,
)
else:
try:
caregiver_service.delete_caregiver(caregiver_id)
return "caregiver deleted", 200
except Exception as e:
error_message = getattr(e, "message", None)
return (
jsonify({"error": (error_message if error_message else str(e))}),

Check warning

Code scanning / CodeQL

Information exposure through an exception Medium

Stack trace information
flows to this location and may be exposed to an external user.
500,
)

return (
jsonify({"error": "Must supply intake id as query parameter."}),
400,
)
47 changes: 47 additions & 0 deletions backend/python/app/services/implementations/caregiver_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,50 @@ def get_caregivers_by_intake_id(self, intake_id):
except Exception as error:
self.logger.error(str(error))
raise error

def update_caregiver(self, caregiver_id: int, updated_caregiver):
try:
if not caregiver_id:
raise Exception(
"Empty caregiver id passed to update_caregiver function"
)
if not isinstance(caregiver_id, int):
raise Exception("Caregiver id passed is not of int type")

caregiver = Caregiver.query.filter_by(id=caregiver_id).first()
if not caregiver:
raise Exception("Caregiver with id {} not found".format(caregiver_id))

if "name" in updated_caregiver:
caregiver.name = updated_caregiver["name"]
if "date_of_birth" in updated_caregiver:
caregiver.date_of_birth = updated_caregiver["date_of_birth"]
if "individual_considerations" in updated_caregiver:
caregiver.individual_considerations = updated_caregiver[
"individual_considerations"
]
if "primary_phone_number" in updated_caregiver:
caregiver.primary_phone_number = updated_caregiver[
"primary_phone_number"
]
if "secondary_phone_number" in updated_caregiver:
caregiver.secondary_phone_number = updated_caregiver[
"secondary_phone_number"
]
if "email" in updated_caregiver:
caregiver.email = updated_caregiver["email"]
if "address" in updated_caregiver:
caregiver.address = updated_caregiver["address"]
if "relationship_to_child" in updated_caregiver:
caregiver.relationship_to_child = updated_caregiver[
"relationship_to_child"
]
if "additional_contact_notes" in updated_caregiver:
caregiver.additional_contact_notes = updated_caregiver[
"additional_contact_notes"
]
db.session.commit()
return CaregiverDTO(**caregiver.to_dict())
except Exception as error:
db.session.rollback()
raise error
15 changes: 15 additions & 0 deletions backend/python/app/services/interfaces/caregiver_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,18 @@ def get_caregivers_by_intake_id(self, intake_id):
:raises Exception: if an error occurs
in the database query
"""
pass

@abstractmethod
def update_caregiver(self, caregiver_id, updated_caregiver):
"""Updates the Caregiver with new name, date of birth, individual considerations,
primary and/or secondary phone number, email, address, relationship to child, additional contact notes
:param Caregiver_id: the caregiver_id of the caregiver to be updated
:type caregiver_id: int
:param updated_caregiver: the new updated CaregiverDTO object
:type updated_caregiver: CaregiverDTO
:return: CaregiverDTO
:rtype: CaregiverDTO
:raises Exception: if caregiver_id or updated_caregiver is not valid or if an error occurs during update
"""
pass
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"""add relationship_to_child enum values
Revision ID: db7c2f31d3ea
Revises: 2e3a95429cdf
Create Date: 2023-10-31 11:43:49.965500
"""
import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "db7c2f31d3ea"
down_revision = "2e3a95429cdf"
branch_labels = None
depends_on = None

# Enum 'type' for PostgreSQL
enum_name = "caregivers_relationship_to_child"
# Set temporary enum 'type' for PostgreSQL
tmp_enum_name = "tmp_" + enum_name

# Options for Enum
old_options = ("FOSTER_CAREGIVER", "KINSHIP_CAREGIVER", "BIOLOGICAL_FAMILY")
new_options = sorted(
old_options
+ (
"ADOPTIVE_PARENT",
"FOSTER_PARENT",
"BIOLOGICAL_PARENT",
"STEP_PARENT",
"MATERNAL_GRANDPARENT",
"PATERNAL_GRANDPARENT",
"SIBLING",
"STEP_SIBLING",
"HALF_SIBLING",
"UNCLE/AUNT",
"OTHER_RELATIVE",
"OTHER",
)
)

# Create enum fields
old_type = sa.Enum(*old_options, name=enum_name)
new_type = sa.Enum(*new_options, name=enum_name)


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
# Rename current enum type to tmp_
op.execute("ALTER TYPE " + enum_name + " RENAME TO " + tmp_enum_name)
# Create new enum type in db
new_type.create(op.get_bind())
# Update column to use new enum type
op.execute(
"ALTER TABLE caregivers ALTER COLUMN relationship_to_child TYPE "
+ enum_name
+ " USING relationship_to_child::text::"
+ enum_name
)
# Drop old enum type
op.execute("DROP TYPE " + tmp_enum_name)

op.alter_column("caregivers", "email", existing_type=sa.String(), nullable=True)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
# Rename enum type to tmp_
op.execute("ALTER TYPE " + enum_name + " RENAME TO " + tmp_enum_name)
# Create enum type using old values
old_type.create(op.get_bind())
# Set enum type as type for event_type column
op.execute(
"ALTER TABLE caregivers ALTER COLUMN relationship_to_child TYPE "
+ enum_name
+ " USING relationship_to_child::text::"
+ enum_name
)
# Drop temp enum type
op.execute("DROP TYPE " + tmp_enum_name)

op.alter_column("caregivers", "email", existing_type=sa.String(), nullable=False)
# ### end Alembic commands ###
16 changes: 11 additions & 5 deletions backend/python/tests/functional/test_caregiver_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def caregiver_service():
"secondary_phone_number": "2345678901",
"email": "[email protected]",
"address": "123 Fake Street",
"relationship_to_child": "FOSTER_CAREGIVER",
"relationship_to_child": "FOSTER_PARENT",
"intake_id": 1,
}

Expand Down Expand Up @@ -87,7 +87,7 @@ def test_normal_case(self, caregiver_service):
secondary_phone_number="2345678901",
email="[email protected]",
address="1234 Lester Street",
relationship_to_child="FOSTER_CAREGIVER",
relationship_to_child="FOSTER_PARENT",
intake_id=1,
)
caregiver_instance = caregiver_service.create_caregiver(param)
Expand All @@ -101,7 +101,7 @@ def test_nullable_false_case(self, caregiver_service):
primary_phone_number="1234567890",
email="[email protected]",
address="1234 Lester Street",
relationship_to_child="FOSTER_CAREGIVER",
relationship_to_child="FOSTER_PARENT",
intake_id=1,
)
caregiver_instance = caregiver_service.create_caregiver(param)
Expand All @@ -116,7 +116,7 @@ def test_missing_field(self, caregiver_service):
primary_phone_number="1234567890",
email="[email protected]",
address="1234 Lester Street",
relationship_to_child="FOSTER_CAREGIVER",
relationship_to_child="FOSTER_PARENT",
intake_id=1,
)
with pytest.raises(Exception):
Expand All @@ -131,7 +131,7 @@ def test_empty_input_string(self):
secondary_phone_number="2345678901",
email="[email protected]",
address="1234 Lester Street",
relationship_to_child="FOSTER_CAREGIVER",
relationship_to_child="FOSTER_PARENT",
intake_id=1,
)
with pytest.raises(Exception):
Expand All @@ -150,3 +150,9 @@ def test_delete_success(self, caregiver_service):
def test_delete_nonexistent_id_fail(self, caregiver_service):
with pytest.raises(Exception):
caregiver_service.delete_caregiver(999)


class GetCaregivers:
def tet_get_caregivers_by_intake_id(self, caregiver_service):
caregivers = caregiver_service.get_caregivers_by_intake_id(1)
assert len(caregivers) is 1
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"secondary_phone_number": "2345678901",
"email": "[email protected]",
"address": "123 Fake Street",
"relationship_to_child": "FOSTER_CAREGIVER",
"relationship_to_child": "FOSTER_PARENT",
"intake_id": 1,
}
DUMMY_CHILD_DATA = {
Expand Down
4 changes: 2 additions & 2 deletions backend/python/tools/db_seed.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ def insert_test_data():

# Caregivers
values = [
('Yor Forger', '1999-01-01', 'considerations', '555-555-5555', '777-777-7777', '[email protected]', 'address', 'FOSTER_CAREGIVER', 'NULL', 1),
('Loid Forger', '1999-01-01', 'considerations', '777-777-7777', '555-555-5555', '[email protected]', 'address', 'FOSTER_CAREGIVER', 'NULL', 1)
('Yor Forger', '1999-01-01', 'considerations', '555-555-5555', '777-777-7777', '[email protected]', 'address', 'FOSTER_PARENT', 'NULL', 1),
('Loid Forger', '1999-01-01', 'considerations', '777-777-7777', '555-555-5555', '[email protected]', 'address', 'MATERNAL_GRANDPARENT', 'NULL', 1)
]

for value in values:
Expand Down
Loading

0 comments on commit 2985845

Please sign in to comment.