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

LGA-3271 scope reports #1238

Merged
merged 9 commits into from
Oct 10, 2024
Merged
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
2 changes: 2 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ repos:
rev: v2.1.0
hooks:
- id: flake8
# Pre-commit fails to install on apple chips as install pyyaml 5.4
additional_dependencies: ['PyYAML==5.3.1']
language_version: python2.7
args: ['--config=setup.cfg', '--exclude=./cla_backend/settings/*,./docs/*']
- repo: https://github.com/jazzband/pip-tools
Expand Down
24 changes: 24 additions & 0 deletions cla_backend/apps/legalaid/migrations/0036_auto_20241002_1407.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [("legalaid", "0035_case_gtm_anon_id")]

operations = [
migrations.AlterModelOptions(
name="case",
options={
"ordering": ("-created",),
"permissions": (
("run_reports", "Can run reports"),
("run_obiee_reports", "Can run OBIEE reports"),
("run_complaints_report", "Can run complaints report"),
("run_internal_reports", "Can run internal reports"),
),
},
)
]
2 changes: 2 additions & 0 deletions cla_backend/apps/legalaid/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,8 @@ class Meta(object):
("run_reports", u"Can run reports"),
("run_obiee_reports", u"Can run OBIEE reports"),
("run_complaints_report", u"Can run complaints report"),
# Used to give internal users access to reports that should not be used without the appropriate context.
("run_internal_reports", u"Can run internal reports"),
)

def __unicode__(self):
Expand Down
109 changes: 109 additions & 0 deletions cla_backend/apps/reports/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -1008,6 +1008,115 @@ def get_headers(self):
]


class MIScopeReport(SQLFileDateRangeReport):
QUERY_FILE = "MIScopeReport.sql"
description = "Reports on the current status of cases and extracts how the user self diagnosed their category of law based on the answers provided on Check if you can get legal aid"
documentation_link = (
"https://dsdmoj.atlassian.net/wiki/spaces/laagetaccess/pages/5183537366/Reports#MI-Scope-Report"
)

def get_sql_params(self):
from_date, to_date = self.date_range
return {"from_date": from_date, "to_date": to_date}

def get_headers(self):
return [
"Person ID",
"Case ID",
"Created",
"Modified",
"Case source",
"CHS scope state",
"Web scope state",
"Means eligibility state",
"Workflow status",
"CHS case outcome code",
"Provider Notes",
"Operator Notes",
"Client notes",
"Category code",
"Category name",
"Matter Type 1 code",
"Matter Type 1 description",
"Matter Type 2 code",
"Matter Type 2 description",
"Web diagnosis category 1",
"Web diagnosis category 2",
"Web diagnosis category 3",
"Web diagnosis category 4",
"Web diagnosis category 5",
"Web diagnosis category 6",
]

def get_rows(self):
for row in self.get_queryset():

row = list(row)
notes_col = self._get_col_index("Client notes")
notes = row[notes_col]
data = self.notes_to_dict(notes)
row[notes_col] = data["user problem"]

category_1_col = self._get_col_index("Web diagnosis category 1")
category_2_col = self._get_col_index("Web diagnosis category 2")
category_3_col = self._get_col_index("Web diagnosis category 3")
category_4_col = self._get_col_index("Web diagnosis category 4")
category_5_col = self._get_col_index("Web diagnosis category 5")
category_6_col = self._get_col_index("Web diagnosis category 6")

row[notes_col] = data["user problem"]
row[category_1_col] = data["categories"].pop(0) if data["categories"] else ""
row[category_2_col] = data["categories"].pop(0) if data["categories"] else ""
row[category_3_col] = data["categories"].pop(0) if data["categories"] else ""
row[category_4_col] = data["categories"].pop(0) if data["categories"] else ""
row[category_5_col] = data["categories"].pop(0) if data["categories"] else ""
row[category_6_col] = data["categories"].pop(0) if data["categories"] else ""

web_scope_state_col = self._get_col_index("Web scope state")
row[web_scope_state_col] = data["scope"]

yield row

def _get_col_index(self, column_name):
return self.get_headers().index(column_name)

@staticmethod
def notes_to_dict(notes):
def get_categories_and_scope(user_selected_text):
items, scope = user_selected_text.split("Outcome: ")
scope = re.sub(r"\s+|\n", "", scope)
categories = []
for category in items.split("\n\n"):
if ": " in category:
category = category.split(": ")[1]
categories.append(category)
return filter(None, categories), scope

ret = {"user problem": "", "categories": [], "scope": ""}
if not notes:
return ret

contains_user_selected = "User selected:\n" in notes
contains_user_problem = "User problem:\n" in notes
contains_public_diagnosis_note = "Public Diagnosis note:\n" in notes

new_notes = notes
if contains_public_diagnosis_note:
new_notes = re.sub("Public Diagnosis note:\n.*\n\n", "", notes)

if contains_user_selected:
parts = filter(None, new_notes.split("User selected:\nWhat do you need help with?: "))
if contains_user_problem:
ret["categories"], ret["scope"] = get_categories_and_scope(parts[1])
ret["user problem"] = parts[0].split("User problem:\n")[1]
else:
ret["categories"], ret["scope"] = get_categories_and_scope(parts[0])
elif contains_user_problem:
ret["user problem"] = filter(None, new_notes.split("User problem:\n"))[0]

return ret


class CallbackTimeSlotReport(DateRangeReportForm):
def get_queryset(self):
from_date, to_date = self.date_range
Expand Down
59 changes: 59 additions & 0 deletions cla_backend/apps/reports/sql/MIScopeReport.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
WITH log_mi_oos_outcome_code as (
SELECT case_id, code
FROM cla_eventlog_log
WHERE code = 'MIS-OOS'
GROUP BY case_id, code
)

SELECT
DISTINCT c.personal_details_id as "Person ID"
,c.reference as "Case Id"
,to_char(c.created, 'YYYY-MM-DD') as "Created"
,to_char(c.modified, 'YYYY-MM-DD') as "Modified"
,c.source as "Case source"
,CASE diagnosis.state
when 'INSCOPE' then 'INSCOPE'
else NULL
END as "CHS scope state"
,'' as "Web scope state"
,CASE ec.state
when 'yes' then 'yes'
when 'no' then 'no'
else 'unknown'
END as "Means eligibility state"
,CASE
WHEN diagnosis.state IS NULL OR diagnosis.state = 'UNKNOWN' THEN 'Pending'
WHEN ec.state IS NOT NULL AND provider_assigned_at IS NULL THEN 'Operator'
-- All the provider outcome codes that are not MI-OOS
WHEN c.provider_viewed IS NOT NULL AND log_mi_oos_outcome_code.code IS NULL AND c.outcome_code IN ('MIS-MEANS', 'COI', 'MIS', 'SPOP', 'CLSP', 'DREFER', 'REOPEN', 'REF-EXT', 'REF-INT', 'REF-EXT_CREATED', 'REF-INT_CREATED') THEN 'Read and approved by SP'
WHEN c.provider_viewed IS NOT NULL AND log_mi_oos_outcome_code.code IS NOT NULL THEN 'Read and NOT approved by SP'
WHEN c.provider_viewed IS NOT NULL THEN 'Read by SP'
ELSE 'NOT read by SP'
END as "Workflow status"
,c.outcome_code as "CHS case outcome code"
,c.provider_notes as "Provider Notes"
,c.notes as "Operator Notes"
,ec.notes as "Client notes"
,category.code as "Category code"
,category.name as "Category name"
,mt1.code as "Matter Type 1 code"
,mt1.description as "Matter Type 1 description"
,mt2.code as "Matter Type 2 code"
,mt2.description as "Matter Type 2 description"
,'' as "Web diagnosis category 1"
,'' as "Web diagnosis category 2"
,'' as "Web diagnosis category 3"
,'' as "Web diagnosis category 4"
,'' as "Web diagnosis category 5"
,'' as "Web diagnosis category 6"
FROM legalaid_case as c
LEFT OUTER JOIN legalaid_eligibilitycheck as ec on c.eligibility_check_id = ec.id
LEFT OUTER JOIN legalaid_category as category on ec.category_id = category.id
LEFT OUTER JOIN legalaid_adaptationdetails as adapt on c.adaptation_details_id = adapt.id
LEFT OUTER JOIN legalaid_mattertype as mt1 on mt1.id = c.matter_type1_id
LEFT OUTER JOIN legalaid_mattertype as mt2 on mt2.id = c.matter_type2_id
LEFT OUTER JOIN diagnosis_diagnosistraversal as diagnosis on c.diagnosis_id = diagnosis.id
LEFT OUTER JOIN log_mi_oos_outcome_code ON log_mi_oos_outcome_code.case_id = c.id
WHERE source IN ('WEB')
AND c.modified >= %(from_date)s AND c.modified < %(to_date)s
ORDER BY to_char(c.modified, 'YYYY-MM-DD') DESC
Loading
Loading