Skip to content

Commit

Permalink
feat: review selected facilities page
Browse files Browse the repository at this point in the history
  • Loading branch information
acatchpole authored and ayeshmcg committed Jan 17, 2025
1 parent a287ae4 commit 0f9defa
Show file tree
Hide file tree
Showing 13 changed files with 605 additions and 10 deletions.
47 changes: 47 additions & 0 deletions bc_obps/reporting/api/report_selected_facilties.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from typing import Literal
from uuid import UUID
from bc_obps.reporting.service.report_facilities_service import ReportFacilitiesService
from reporting.constants import EMISSIONS_REPORT_TAGS
from common.api.utils.current_user_utils import get_current_user_guid
from common.permissions import authorize
from registration.decorators import handle_http_errors
from service.error_service.custom_codes_4xx import custom_codes_4xx
from django.http import HttpRequest
from reporting.schema.generic import Message
from .router import router

@router.get(
"report-version/{report_version_id}/selected-facilities",
response={200: list[UUID], custom_codes_4xx: Message},
tags=EMISSIONS_REPORT_TAGS,
description="""Retrieves the list of selected facilities for a report version""",
exclude_none=True,
auyh=authorize("approved_industry_user"),
)
@handle_http_errors()
def get_selected_facilities(
request: HttpRequest, report_version_id: int
) -> tuple[Literal[200], list[UUID]]:
response_data = ReportFacilitiesService.get_selected_facilities(report_version_id)
return 200, response_data

@router.post(
"report-version/{report_version_id}/selected-facilities",
response={200: int, custom_codes_4xx: Message},
tags=EMISSIONS_REPORT_TAGS,
description="""Saves the list of selected facilities for a report version""",
auth=authorize("approved_industry_user"),
)
@handle_http_errors()
def save_selected_facilities(
request: HttpRequest,
report_version_id: int,
payload: list[UUID],
) -> Literal[200]:
ReportFacilitiesService.save_selected_facilities(
report_version_id,
payload,
get_current_user_guid(request),
)

return 200
36 changes: 36 additions & 0 deletions bc_obps/reporting/models/report_selected_facility.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from django.db import models
from registration.models.facility import Facility
from registration.models.time_stamped_model import TimeStampedModel
from reporting.models import ReportVersion


class ReportSelectedFacility(TimeStampedModel):
'''
Model representing a the facilities selected for a report.
A report (each report version) may contain multiple facilities.
'''

facility = models.ForeignKey(
Facility,
on_delete=models.CASCADE,
db_comment="The facility selected to be included in the report",
related_name="report_selected_facilities",
)

report_version = models.ForeignKey(
ReportVersion,
on_delete=models.CASCADE,
db_comment="The report this facility is selected for",
related_name="reprot_selected_facilities",
)

class Meta:
db_table_comment = "A table to store the facilities selected for a report"
db_table = 'erc"."report_selected_facility'
app_label = 'reporting'
constraints = [
models.UniqueConstraint(
fields=['report_version', 'facility_id'],
name="unique_selected_facility_per_facility_and_report_version",
)
]
10 changes: 10 additions & 0 deletions bc_obps/reporting/schema/report_selected_facility.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from uuid import UUID


class ReportSelectedFacilitySchemaOut(Schema):
"""
Schema for the get selected facilities endpoint response
"""
facility_id: UUID
is_selected: bool
is_current: bool
50 changes: 50 additions & 0 deletions bc_obps/reporting/service/report_facilities_service.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from django.db import transaction
from reporting.models.report_selected_facility import ReportSelectedFacility
from reporting.models import ReportVersion
from registration.models import Facility
from typing import List, Dict
from uuid import UUID


class ReportFacilitiesService:
Expand All @@ -27,3 +29,51 @@ def get_report_facility_list_by_version_id(version_id: int) -> Dict[str, List[st
)

return {"facilities": facilities_list}

@classmethod
@transaction.atomic
def save_selected_facilities(
cls,
version_id: int,
facility_list: List[UUID],
user_guid: UUID,
) -> None:
"""
Save selected facility to report version.
Args:
version_id: The report version ID
facility_list: The facility IDs of the selected facilities
user_guid: The user GUID of the user making the save request
"""

# Delete existing selected facilities that are no longer selected
ReportSelectedFacility.objects.filter(report_version_id=version_id).exclude(facility_id__in=facility_list).delete()

for facility_id in facility_list:
selected_facility_record, created = ReportSelectedFacility.objects.get_or_create(
report_version_id=version_id,
facility_id=facility_id,
)
if created:
selected_facility_record.set_create_or_update(user_guid)

@staticmethod
@transaction.atomic
def get_selected_facilities(
version_id: int,
) -> List[UUID]:
"""
Get selected facilities for a report version.
Args:
version_id: The report version ID
Returns:
List of facility IDs
"""
return list(ReportSelectedFacility.objects.filter(report_version_id=version_id).values_list('facility_id', flat=True))


Empty file.
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import ReviewFacilities from "@reporting/src/app/components/operations/reviewFacilities/ReviewFacilitiesPage";
import { Suspense } from "react";
import Loading from "@bciers/components/loading/SkeletonForm";

export default async function Page({
params,
}: {
params: { version_id: number };
}) {
console.log(params);
return <>Review Facilities List Page TBD</>;
return (
<Suspense fallback={<Loading />}>
<ReviewFacilities version_id={params.version_id} />
</Suspense>
);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
export default async function Page({
params,
}: {
params: { version_id: number };
}) {
console.log(params);
return <>Review Facilities List Page TBD</>;
}
import defaultPageFactory from "@bciers/components/nextPageFactory/defaultPageFactory";
import Page from "@reporting/src/app/components/operations/reviewFacilities/ReviewFacilitiesPage";

export default defaultPageFactory(Page);
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"use client";

import React, { useEffect, useState } from "react";
import MultiStepFormWithTaskList from "@bciers/components/form/MultiStepFormWithTaskList";
import SimpleModal from "@bciers/components/modal/SimpleModal";
import { RJSFSchema } from "@rjsf/utils";
import {
operationReviewSchema,
operationReviewUiSchema,
updateSchema,
} from "@reporting/src/data/jsonSchema/operations";
import { actionHandler } from "@bciers/actions";
import safeJsonParse from "@bciers/utils/src/safeJsonParse";
import {
ActivePage,
getOperationInformationTaskList,
} from "@reporting/src/app/components/taskList/1_operationInformation";
import { multiStepHeaderSteps } from "@reporting/src/app/components/taskList/multiStepHeaderConfig";
import { Task } from "@nx/devkit";
import { TaskListElement } from "@bciers/components/navigation/reportingTaskList/types";

interface Props {
Initialdata: any;
version_id: number;
taskListElements: TaskListElement[];
}

export default function ReviewFacilitiesForm({
Initialdata,
version_id,
taskListElements,
}: Props) {
const [formData, setFormData] = useState<any>(() => ({
...Initialdata,
}));
const [schema, setSchema] = useState<RJSFSchema>(operationReviewSchema);
const [uiSchema, setUiSchema] = useState(operationReviewUiSchema);
const [errors, setErrors] = useState<string[]>();
const [submitButtonDisabled, setSubmitButtonDisabled] = useState(false);
const [isModalOpen, setIsModalOpen] = useState(false);
//const [modalMessage, setModalMessage] = useState<string | null>(null);
//const [modalTitle, setModalTitle] = useState<string | null>(null);
//const [modalType, setModalType] = useState<"error" | "success">("success");

const saveAndContinueUrl = `/reports/${version_id}/compliance-summary`;

const handleChange = (e: any) => {
const updatedData = { ...e.formData };
setFormData(updatedData);
};

const handleSubmit = async (data: any) => {
const endpoint = `reporting/report-version/${version_id}/selected-facilities`;
const method = "POST";
const response = await actionHandler(endpoint, method, endpoint, {
body: JSON.stringify(data),
});
if (response?.error) {
setErrors([response.error]);
return false;
}

setErrors(undefined);
return true;
};

return (
<MultiStepFormWithTaskList
formData={formData}
schema={schema}
uiSchema={uiSchema}
taskListElements={taskListElements}
headerSteps={multiStepHeaderSteps}
saveAndContinueUrl={saveAndContinueUrl}
handleChange={handleChange}
handleSubmit={handleSubmit}
submitButtonDisabled={submitButtonDisabled}
errors={errors}
/>
);
}
Loading

0 comments on commit 0f9defa

Please sign in to comment.