Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/dinesh-aot/EPIC.compliance
Browse files Browse the repository at this point in the history
… into test_cases
  • Loading branch information
dinesh-aot committed Dec 4, 2024
2 parents a8acdf5 + 7d43bbd commit 03d4098
Show file tree
Hide file tree
Showing 20 changed files with 441 additions and 123 deletions.
Binary file modified compliance-api/requirements.txt
Binary file not shown.
3 changes: 2 additions & 1 deletion compliance-api/requirements/prod.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ requests
flask_cors
pyhumps
importlib-resources
pycryptodome==3.20.0
pycryptodome==3.20.0
tenacity==9.0.0
29 changes: 16 additions & 13 deletions compliance-api/src/compliance_api/services/case_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ def update(cls, case_file_id: int, case_file_data: dict, ho_session=None):
case_file_obj = {
"primary_officer_id": case_file_data.get("primary_officer_id", None),
"project_description": case_file_data.get("project_description", None),
"is_deleted": case_file_data.get("is_deleted", False),
"is_active": case_file_data.get("is_active", True)
}
with session_scope() as session:
updated_case_file = CaseFileModel.update_case_file(
Expand Down Expand Up @@ -163,19 +165,20 @@ def change_case_file_status(cls, case_file_id, status_data):

def _set_project_parameters(case_file):
"""Set project parameters."""
project_id = case_file.project_id
if project_id:
project = TrackService.get_project_by_id(project_id)
setattr(case_file, "authorization", project.get("ea_certificate", None))
setattr(case_file, "type", project.get("type").get("name"))
setattr(case_file, "sub_type", project.get("sub_type").get("name"))
setattr(case_file, "regulated_party", project.get("proponent").get("name"))
if not project_id:
project = UnapprovedProjectModel.get_by_case_file_id(case_file.id)
setattr(case_file, "authorization", project.authorization)
setattr(case_file, "type", project.type)
setattr(case_file, "sub_type", project.sub_type)
setattr(case_file, "regulated_party", project.regulated_party)
if case_file:
project_id = case_file.project_id
if project_id:
project = TrackService.get_project_by_id(project_id)
setattr(case_file, "authorization", project.get("ea_certificate", None))
setattr(case_file, "type", project.get("type").get("name"))
setattr(case_file, "sub_type", project.get("sub_type").get("name"))
setattr(case_file, "regulated_party", project.get("proponent").get("name"))
if not project_id:
project = UnapprovedProjectModel.get_by_case_file_id(case_file.id)
setattr(case_file, "authorization", project.authorization)
setattr(case_file, "type", project.type)
setattr(case_file, "sub_type", project.sub_type)
setattr(case_file, "regulated_party", project.regulated_party)
return case_file


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import requests
from flask import current_app, g
from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_fixed

from compliance_api.exceptions import BusinessError
from compliance_api.utils.enum import HttpMethod
Expand Down Expand Up @@ -45,6 +46,11 @@ def get_first_nation_by_id(first_nation_id: int):
return first_nation_response.json()


@retry(
retry=retry_if_exception_type(requests.exceptions.RequestException),
stop=stop_after_attempt(3), # Retry up to 3 times
wait=wait_fixed(2), # Wait 2 seconds between retries
)
def _request_track_service(
relative_url, http_method: HttpMethod = HttpMethod.GET, data=None
):
Expand Down
66 changes: 36 additions & 30 deletions compliance-api/tests/integration/api/test_case_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,15 +157,9 @@ def test_get_case_file_by_id(client, auth_header, mocker):
)
mock_get_user_by_guid.return_value = {
"ea_certificate": fake.word(),
"type": {
"name": fake.word()
},
"sub_type": {
"name": fake.word()
},
"proponent": {
"name": fake.word()
}
"type": {"name": fake.word()},
"sub_type": {"name": fake.word()},
"proponent": {"name": fake.word()},
}
case_file_data = copy.copy(CasefileScenario.default_value.value)
case_file_data["project_id"] = 2
Expand Down Expand Up @@ -210,15 +204,9 @@ def test_get_case_file_by_number(client, auth_header_super_user, mocker):
)
mock_get_user_by_guid.return_value = {
"ea_certificate": fake.word(),
"type": {
"name": fake.word()
},
"sub_type": {
"name": fake.word()
},
"proponent": {
"name": fake.word()
}
"type": {"name": fake.word()},
"sub_type": {"name": fake.word()},
"proponent": {"name": fake.word()},
}
case_file_data = copy.copy(CasefileScenario.default_value.value)
case_file_data["case_file_number"] = fake.word()
Expand All @@ -245,15 +233,9 @@ def test_case_file_update(client, auth_header_super_user, created_staff, mocker)
)
mock_get_user_by_guid.return_value = {
"ea_certificate": fake.word(),
"type": {
"name": fake.word()
},
"sub_type": {
"name": fake.word()
},
"proponent": {
"name": fake.word()
}
"type": {"name": fake.word()},
"sub_type": {"name": fake.word()},
"proponent": {"name": fake.word()},
}
# creating case file without officers or primary officer
case_file_data = copy.copy(CasefileScenario.default_value.value)
Expand Down Expand Up @@ -308,7 +290,9 @@ def test_case_file_update(client, auth_header_super_user, created_staff, mocker)
assert len(officers) == 0


def test_case_file_update_viewer_fails(client, auth_header, auth_header_super_user, created_staff):
def test_case_file_update_viewer_fails(
client, auth_header, auth_header_super_user, created_staff
):
"""Update as Viewer."""
case_file_data = copy.copy(CasefileScenario.default_value.value)
case_file_data["case_file_number"] = fake.word()
Expand All @@ -323,7 +307,9 @@ def test_case_file_update_viewer_fails(client, auth_header, auth_header_super_us
assert result.status_code == HTTPStatus.FORBIDDEN


def test_case_file_update_with_primary(client, jwt, created_staff, auth_header_super_user):
def test_case_file_update_with_primary(
client, jwt, created_staff, auth_header_super_user
):
"""Update as primary."""
case_file_data = copy.copy(CasefileScenario.default_value.value)
case_file_data["case_file_number"] = fake.word()
Expand All @@ -342,6 +328,7 @@ def test_case_file_update_with_primary(client, jwt, created_staff, auth_header_s
result = client.patch(url, data=json.dumps(case_file_data), headers=headers)
assert result.status_code == HTTPStatus.OK


def test_case_file_close(client, jwt, created_staff, auth_header_super_user):
"""Update as primary."""
case_file_data = copy.copy(CasefileScenario.default_value.value)
Expand All @@ -363,4 +350,23 @@ def test_case_file_close(client, jwt, created_staff, auth_header_super_user):
result = client.patch(url, data=json.dumps({"status": "CLOSED"}), headers=headers)
assert result.status_code == HTTPStatus.NO_CONTENT
result = client.patch(url, data=json.dumps({"status": "CLOSED"}), headers=headers)
assert result.status_code == HTTPStatus.UNPROCESSABLE_ENTITY
assert result.status_code == HTTPStatus.UNPROCESSABLE_ENTITY


def test_case_file_delete(client, jwt, created_staff, auth_header_super_user):
"""Update as primary."""
case_file_data = copy.copy(CasefileScenario.default_value.value)
case_file_data["case_file_number"] = fake.word()
case_file_data["primary_officer_id"] = created_staff.id
created_result = client.post(
urljoin(API_BASE_URL, "case-files"),
data=json.dumps(case_file_data),
headers=auth_header_super_user,
)

url = urljoin(API_BASE_URL, f"case-files/{created_result.json.get('id')}")
result = client.delete(url, headers=auth_header_super_user)
assert result.status_code == HTTPStatus.NO_CONTENT
url = urljoin(API_BASE_URL, f"case-files/{created_result.json.get('id')}")
result = client.get(url, headers=auth_header_super_user)
assert result.status_code == HTTPStatus.NOT_FOUND
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import React, { useCallback } from "react";
import MenuActionDropdown from "@/components/Shared/MenuActionDropdown";
import {
useDeleteCaseFile,
useUpdateCaseFileStatus,
} from "@/hooks/useCaseFiles";
import { CaseFile } from "@/models/CaseFile";
import { useQueryClient } from "@tanstack/react-query";
import ConfirmationModal from "@/components/Shared/Popups/ConfirmationModal";
import { useModal } from "@/store/modalStore";
import { notify } from "@/store/snackbarStore";
import { useRouter } from "@tanstack/react-router";

interface CaseFileActionsProps {
status: string;
fileNumber: string;
}

const CaseFileActions: React.FC<CaseFileActionsProps> = ({
status,
fileNumber,
}) => {
const router = useRouter();
const queryClient = useQueryClient();
const { setOpen, setClose } = useModal();

const caseFileData = queryClient.getQueryData<CaseFile>([
"case-file",
fileNumber,
]);

const onUpdateStatusSuccess = useCallback(() => {
queryClient.invalidateQueries({
queryKey: ["case-file", fileNumber],
});
notify.success("Case File status updated!");
setClose();
}, [queryClient, fileNumber, setClose]);

const onDeleteSuccess = useCallback(() => {
notify.success("Case File deleted!");
setClose();
router.navigate({ to: "/ce-database/case-files" });
}, [setClose, router]);

const { mutate: updateCaseFileStatus } = useUpdateCaseFileStatus(
onUpdateStatusSuccess
);
const { mutate: deleteCaseFile } = useDeleteCaseFile(onDeleteSuccess);

const actionsList = [
{
text: "Link to Case File",
onClick: () => {
// Handle linking case file
},
hidden: true,
},
{
text: "Unlink from Case File",
onClick: () => {
// Handle unlinking case file
},
hidden: true,
},
{
text: "Close Case File",
onClick: () => {
// Handle closing case file
setOpen({
content: (
<ConfirmationModal
title="Close Case File?"
description="Are you sure you want to close this case file? This action cannot be undone without reopening the case file."
confirmButtonText="Close Case File"
onConfirm={() => {
updateCaseFileStatus({
id: caseFileData?.id ?? 0,
caseFileStatus: { status: "CLOSED" },
});
}}
/>
),
});
},
hidden: status?.toLowerCase() === "closed",
},
{
text: "Reopen Case File",
onClick: () => {
// Handle reopening case file
updateCaseFileStatus({
id: caseFileData?.id ?? 0,
caseFileStatus: { status: "OPEN" },
});
},
hidden: status?.toLowerCase() === "open",
},
{
text: "Delete Case File",
onClick: () => {
// Handle deleting case file
setOpen({
content: (
<ConfirmationModal
title="Delete Case File?"
description="Delete Case File? You are about to delete this case file. Are you sure?"
confirmButtonText="Delete"
onConfirm={() => deleteCaseFile(caseFileData?.id ?? 0)}
/>
),
});
},
hidden: false,
},
];

return <MenuActionDropdown actions={actionsList} />;
};

export default CaseFileActions;
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,20 @@ import { useQueryClient } from "@tanstack/react-query";
import ComplaintDrawer from "@/components/App/Complaints/ComplaintDrawer";
import { useDrawer } from "@/store/drawerStore";
import { CaseFile } from "@/models/CaseFile";
import { useParams } from "@tanstack/react-router";

const CaseFileCreateComplaint = () => {
const CaseFileCreateComplaint = ({
fileNumber,
disabled = false,
}: {
fileNumber: string;
disabled?: boolean;
}) => {
const queryClient = useQueryClient();
const { setOpen, setClose } = useDrawer();
const { caseFileNumber } = useParams({ strict: false });

const caseFileData = queryClient.getQueryData<CaseFile>([
"case-file",
caseFileNumber,
fileNumber,
]);

const handleOnSubmit = useCallback(
Expand Down Expand Up @@ -47,6 +51,7 @@ const CaseFileCreateComplaint = () => {
size="small"
onClick={handleOpenComplaintDrawer}
startIcon={<AddRounded />}
disabled={disabled}
>
Complaint
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,20 @@ import { useQueryClient } from "@tanstack/react-query";
import InspectionDrawer from "@/components/App/Inspections/InspectionDrawer";
import { useDrawer } from "@/store/drawerStore";
import { CaseFile } from "@/models/CaseFile";
import { useParams } from "@tanstack/react-router";

const CaseFileCreateInspection = () => {
const CaseFileCreateInspection = ({
fileNumber,
disabled = false,
}: {
fileNumber: string;
disabled?: boolean;
}) => {
const queryClient = useQueryClient();
const { setOpen, setClose } = useDrawer();
const { caseFileNumber } = useParams({ strict: false });

const caseFileData = queryClient.getQueryData<CaseFile>([
"case-file",
caseFileNumber,
fileNumber,
]);

const handleOnSubmit = useCallback(
Expand Down Expand Up @@ -47,6 +51,7 @@ const CaseFileCreateInspection = () => {
size="small"
onClick={handleOpenInspectionDrawer}
startIcon={<AddRounded />}
disabled={disabled}
>
Inspection
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ const CaseFileGeneralInformation: React.FC<CaseFileGeneralInformationProps> = ({
propertyName="Project Description"
propertyValue={caseFileData.project_description}
size="small"
expandable={true}
/>
<CaseFileComplaintsTable caseFileId={caseFileData.id} />
<CaseFileInspectionsTable caseFileId={caseFileData.id} />
Expand Down
Loading

0 comments on commit 03d4098

Please sign in to comment.