Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(summary-activities) Filter for inactivi activities without answers (M2-6921) #1380

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/apps/activity_flows/crud/flow_history.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,11 @@ async def get_versions_data(self, flow_id: uuid.UUID) -> list[Version]:
data = result.all()

return parse_obj_as(list[Version], data)

async def get_by_applet_id_version(self, applet_id_version: str) -> list[ActivityFlowHistoriesSchema]:
query: Query = select(ActivityFlowHistoriesSchema)
query = query.where(ActivityFlowHistoriesSchema.applet_id == applet_id_version)
query = query.join(AppletHistorySchema, AppletHistorySchema.id_version == ActivityFlowHistoriesSchema.applet_id)
query = query.order_by(AppletHistorySchema.created_at.desc())
result = await self._execute(query)
return result.scalars().all()
20 changes: 19 additions & 1 deletion src/apps/answers/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
)
from apps.answers.filters import AppletSubmitDateFilter, ReviewAppletItemFilter, SummaryActivityFilter
from apps.answers.tasks import create_report
from apps.applets.crud import AppletsCRUD
from apps.applets.crud import AppletHistoriesCRUD, AppletsCRUD
from apps.applets.domain.applet_history import Version
from apps.applets.domain.base import Encryption
from apps.applets.service import AppletHistoryService
Expand Down Expand Up @@ -1030,6 +1030,7 @@ async def get_summary_activities(
self, applet_id: uuid.UUID, filters: SummaryActivityFilter
) -> list[SummaryActivity]:
assert self.user_id
current_applet_version = await AppletHistoriesCRUD(self.session).get_current_versions_by_applet_id(applet_id)
act_hst_crud = ActivityHistoriesCRUD(self.session)
activities = await act_hst_crud.get_last_histories_by_applet(applet_id=applet_id)
activity_ver_ids = [activity.id_version for activity in activities]
Expand All @@ -1043,11 +1044,21 @@ async def get_summary_activities(
submitted_activities[activity_id] = max(submit_date, date) if date else submit_date
submitted_activities[activity_history_id] = submit_date

current_activity_histories = await act_hst_crud.retrieve_by_applet_version(current_applet_version)
current_activities_map = {str(ah.id): ah for ah in current_activity_histories}
results = []
for activity in activities:
activity_history_answer_date = submitted_activities.get(
activity.id_version, submitted_activities.get(str(activity.id))
)
has_answer = bool(activity_history_answer_date)
if not has_answer:
activity_curr = current_activities_map.get(str(activity.id))
if not activity_curr:
continue
elif activity_curr.is_reviewable:
continue

results.append(
SummaryActivity(
id=activity.id,
Expand All @@ -1063,6 +1074,7 @@ async def get_summary_activity_flows(
self, applet_id: uuid.UUID, target_subject_id: uuid.UUID | None
) -> list[SummaryActivityFlow]:
assert self.user_id
current_applet_version = await AppletHistoriesCRUD(self.session).get_current_versions_by_applet_id(applet_id)
flow_crud = FlowsHistoryCRUD(self.session)
answer_crud = AnswersCRUD(self.answer_session)
flow_history_ids_with_date = await answer_crud.get_submitted_flows_with_last_date(applet_id, target_subject_id)
Expand All @@ -1075,11 +1087,17 @@ async def get_summary_activity_flows(
submitted_activity_flows[flow_id] = max(submit_date, date) if date else submit_date
submitted_activity_flows[version_id] = submit_date

flow_histories = await flow_crud.get_by_applet_id_version(current_applet_version)
flow_histories_curr = [flow_h.id for flow_h in flow_histories]
results = []
for flow_history in activity_flow_histories:
flow_history_answer_date = submitted_activity_flows.get(
flow_history.id_version, submitted_activity_flows.get(str(flow_history.id))
)
has_answer = bool(flow_history_answer_date)
if not has_answer and flow_history.id not in flow_histories_curr:
continue

results.append(
SummaryActivityFlow(
id=flow_history.id,
Expand Down
64 changes: 64 additions & 0 deletions src/apps/answers/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,3 +474,67 @@ async def editor_user_reviewer_applet_one(user: UserSchema, session: AsyncSessio
applet_id = uuid.UUID("92917a56-d586-4613-b7aa-991f2c4b15b1")
srv = UserAppletAccessService(session, user.id, applet_id)
await srv.add_role(user.id, Role.EDITOR)


@pytest.fixture
async def applet__activity_turned_into_assessment(
session: AsyncSession, tom: User, applet_data: AppletCreate
) -> AppletFull:
"""
Applet with one Activity0 updated into applet with Activity0(is_reviewable=True) and Activity1
All activities has no answers
"""
srv = AppletService(session, tom.id)
applet = await srv.create(applet_data)
data = AppletUpdate(**applet.dict())

activity_new = data.activities[0].copy(deep=True)
activity_new.id = uuid.uuid4()
activity_new.key = uuid.uuid4()
for i in range(len(activity_new.items)):
activity_new.items[i].id = uuid.uuid4()
activity_new.name = "New activity"
data.activities.append(activity_new)

data.activities[0].is_reviewable = True
data.activities[0].name = "Reviewer assessment"
updated_applet = await srv.update(applet.id, data)
return updated_applet


@pytest.fixture
async def applet__deleted_activity_without_answers(
session: AsyncSession, tom: User, applet_data: AppletCreate
) -> AppletFull:
"""
Applet with one Activity0 updated into applet with Activity1 and deleted Activity1
All activities has no answers
"""
srv = AppletService(session, tom.id)
applet = await srv.create(applet_data)
data = AppletUpdate(**applet.dict())

activity_new = data.activities[0].copy(deep=True)
activity_new.id = uuid.uuid4()
activity_new.key = uuid.uuid4()
for i in range(len(activity_new.items)):
activity_new.items[i].id = uuid.uuid4()
activity_new.name = "New activity"
data.activities = [activity_new]
updated_applet = await srv.update(applet.id, data)
return updated_applet


@pytest.fixture
async def applet__deleted_flow_without_answers(
session: AsyncSession, tom: User, applet_with_flow: AppletFull
) -> AppletFull:
srv = AppletService(session, tom.id)
data = applet_with_flow.dict()
activity_flow = data["activity_flows"][0]
for i in range(len(activity_flow["items"])):
activity_flow["items"][i]["activity_key"] = data["activities"][0]["key"]
data["activity_flows"] = [activity_flow]
update_data = AppletUpdate(**data)
updated_applet = await srv.update(applet_with_flow.id, update_data)
return updated_applet
58 changes: 58 additions & 0 deletions src/apps/answers/tests/test_answers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1888,3 +1888,61 @@ async def test_access_to_activity_list(
client.login(user)
response = await client.get(url)
assert response.status_code == expected

async def test_get_summary_activities_no_answer_no_empty_deleted_history(
self, client: TestClient, tom: User, applet: AppletFull
):
client.login(tom)

response = await client.get(
self.summary_activities_url.format(
applet_id=str(applet.id),
)
)

assert response.status_code == http.HTTPStatus.OK
assert response.json()["count"] == 1
assert response.json()["result"][0]["name"] == applet.activities[0].name
assert response.json()["result"][0]["id"] == str(applet.activities[0].id)
assert not response.json()["result"][0]["isPerformanceTask"]
assert not response.json()["result"][0]["hasAnswer"]

async def test_activity_turned_into_assessment_not_included_in_list(
self, client: TestClient, tom: User, applet__activity_turned_into_assessment: AppletFull
):
client.login(tom)
response = await client.get(
self.summary_activities_url.format(
applet_id=str(applet__activity_turned_into_assessment.id),
)
)

assert response.status_code == http.HTTPStatus.OK
assert response.json()["count"] == 1
assert response.json()["result"][0]["id"] == str(applet__activity_turned_into_assessment.activities[1].id)

async def test_deleted_activity_without_answers_not_included_in_list(
self, client: TestClient, tom: User, applet__deleted_activity_without_answers: AppletFull
):
client.login(tom)
response = await client.get(
self.summary_activities_url.format(
applet_id=str(applet__deleted_activity_without_answers.id),
)
)

assert response.status_code == http.HTTPStatus.OK
assert response.json()["count"] == 1
assert response.json()["result"][0]["id"] == str(applet__deleted_activity_without_answers.activities[0].id)

async def test_deleted_flow_not_included_in_submission_list(
self, client: TestClient, tom: User, applet__deleted_flow_without_answers: AppletFull
):
client.login(tom)
url = self.summary_activity_flows_url.format(applet_id=applet__deleted_flow_without_answers.id)
response = await client.get(url)
assert response.status_code == 200
payload = response.json()
assert applet__deleted_flow_without_answers.activity_flows[0].id
assert payload["count"] == 1
assert payload["result"][0]["id"] == str(applet__deleted_flow_without_answers.activity_flows[0].id)
8 changes: 8 additions & 0 deletions src/apps/applets/crud/applets_history.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,11 @@ async def set_report_configuration(
query = query.values(**schema.dict(by_alias=False))

await self._execute(query)

async def get_current_versions_by_applet_id(self, applet_id: uuid.UUID) -> str:
query: Query = select(AppletHistorySchema.id_version)
query = query.where(AppletHistorySchema.id == applet_id)
query = query.order_by(AppletHistorySchema.created_at.desc())
query = query.limit(1)
result = await self._execute(query)
return result.scalars().first()
Loading