Skip to content

Commit f85fcc9

Browse files
committed
chore:Added Api to get report Type and modified fields
1 parent 60b20dd commit f85fcc9

File tree

11 files changed

+174
-32
lines changed

11 files changed

+174
-32
lines changed

bc_obps/reporting/api/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
from .report_person_responsible import get_report_person_responsible_by_version_id
1111
from .report_person_responsible import save_report_contact
1212
from .report_activity import save_report_activity_data
13+
from .reports import get_report_type_by_version

bc_obps/reporting/api/reports.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
from reporting.schema.report_operation import ReportOperationOut, ReportOperationIn
1313
from reporting.schema.reporting_year import ReportingYearOut
1414
from .router import router
15-
from ..models import ReportingYear
15+
from ..models import ReportingYear, ReportVersion
16+
from ..schema.report_version import ReportingVersionOut
1617

1718

1819
@router.post(
@@ -71,3 +72,16 @@ def save_report(
7172
@handle_http_errors()
7273
def get_reporting_year(request: HttpRequest) -> Tuple[Literal[200], ReportingYear]:
7374
return 200, ReportingYearService.get_current_reporting_year()
75+
76+
77+
@router.get(
78+
"/report-version/{version_id}/report-type",
79+
response={200: ReportingVersionOut, custom_codes_4xx: Message},
80+
tags=EMISSIONS_REPORT_TAGS,
81+
description="Retrieve the report type for a specific reporting version, including the reporting year and due date.",
82+
# auth=authorize("all_roles"),
83+
)
84+
@handle_http_errors()
85+
def get_report_type_by_version(request: HttpRequest, version_id: int) -> tuple[Literal[200], ReportVersion]:
86+
report_type = ReportService.get_report_type_by_version_id(version_id)
87+
return 200, report_type
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 5.0.9 on 2024-10-17 21:59
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('reporting', '0020_report_person_responsible'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='reportversion',
15+
name='report_type',
16+
field=models.CharField(db_comment='Report type', default='Annual Report', max_length=1000),
17+
),
18+
]

bc_obps/reporting/models/report_version.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ class ReportVersion(TimeStampedModel):
1515
db_comment="True if this version is the latest submitted one",
1616
default=False,
1717
)
18+
report_type = models.CharField(
19+
max_length=1000,
20+
db_comment="Report type",
21+
default="Annual Report",
22+
)
1823

1924
class ReportVersionStatus(models.TextChoices):
2025
Draft = 'draft'
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from ninja import ModelSchema
2+
3+
from reporting.models import ReportVersion
4+
5+
6+
class ReportingVersionOut(ModelSchema):
7+
"""
8+
Schema for the get reporting year endpoint request output
9+
"""
10+
11+
class Meta:
12+
model = ReportVersion
13+
fields = ['report_type']

bc_obps/service/report_service.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,7 @@ def save_report_operation(cls, report_version_id: int, data: ReportOperationIn)
103103
report_operation.save()
104104

105105
return report_operation
106+
107+
@staticmethod
108+
def get_report_type_by_version_id(version_id: int) -> ReportVersion:
109+
return ReportVersion.objects.get(id=version_id)

bciers/apps/reporting/src/app/components/operations/OperationReview.tsx

Lines changed: 91 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ import { formatDate } from "@reporting/src/app/utils/formatDate";
1616
interface Props {
1717
formData: any;
1818
version_id: number;
19+
reportType: {
20+
report_type: string;
21+
};
1922
reportingYear: {
2023
reporting_year: number;
2124
report_due_date: string;
@@ -44,19 +47,22 @@ const taskListElements: TaskListElement[] = [
4447
export default function OperationReview({
4548
formData,
4649
version_id,
50+
reportType,
4751
reportingYear,
4852
allActivities,
4953
allRegulatedProducts,
5054
}: Props) {
5155
const router = useRouter();
5256
const [schema, setSchema] = useState<RJSFSchema>(operationReviewSchema);
57+
const [uiSchema, setUiSchema] = useState<RJSFSchema>(operationReviewUiSchema);
5358
const [formDataState, setFormDataState] = useState<any>(formData);
5459
const saveAndContinueUrl = `/reports/${version_id}/person-responsible`;
5560
const reportingWindowEnd = formatDate(
5661
reportingYear.reporting_window_end,
5762
"MMM DD YYYY",
5863
);
5964

65+
// Function to handle form data submission
6066
const submitHandler = async (
6167
data: { formData?: any },
6268
reportVersionId: number,
@@ -66,22 +72,30 @@ export default function OperationReview({
6672

6773
const formDataObject = safeJsonParse(JSON.stringify(data.formData));
6874

75+
// Prepare the data based on the operation report type
6976
const preparedData = {
7077
...formDataObject,
71-
activities: formDataObject.activities?.map((activityId: any) => {
72-
const activity = allActivities.find((a) => a.id === activityId);
73-
if (!activity)
74-
throw new Error(`Activity with ID ${activityId} not found`);
75-
return activity.name;
76-
}),
77-
regulated_products: formDataObject.regulated_products?.map(
78-
(productId: any) => {
79-
const product = allRegulatedProducts.find((p) => p.id === productId);
80-
if (!product)
81-
throw new Error(`Product with ID ${productId} not found`);
82-
return product.name;
83-
},
84-
),
78+
// Check the report type and set activities and regulated_products to empty arrays if it's a simple report
79+
activities:
80+
formDataState.operation_report_type === "Simple Report"
81+
? []
82+
: formDataObject.activities?.map((activityId: any) => {
83+
const activity = allActivities.find((a) => a.id === activityId);
84+
if (!activity)
85+
throw new Error(`Activity with ID ${activityId} not found`);
86+
return activity.name;
87+
}),
88+
regulated_products:
89+
formDataState.operation_report_type === "Simple Report"
90+
? []
91+
: formDataObject.regulated_products?.map((productId: any) => {
92+
const product = allRegulatedProducts.find(
93+
(p) => p.id === productId,
94+
);
95+
if (!product)
96+
throw new Error(`Product with ID ${productId} not found`);
97+
return product.name;
98+
}),
8599
};
86100

87101
const response = await actionHandler(endpoint, method, endpoint, {
@@ -93,18 +107,43 @@ export default function OperationReview({
93107
}
94108
};
95109

110+
// Function to handle changes in the form data
111+
const onChangeHandler = (data: { formData: any }) => {
112+
const updatedData = {
113+
...data.formData,
114+
// Modify the structure of form data here as needed
115+
};
116+
117+
setFormDataState(updatedData); // Update the state with modified data
118+
};
119+
96120
useEffect(() => {
97121
if (!formData || !allActivities || !allRegulatedProducts) {
98122
return;
99123
}
100124

101-
const activities = formData.activities || [];
102-
const products = formData.regulated_products || [];
125+
const updatedFormData = {
126+
...formData,
127+
operation_report_type: reportType?.report_type || "Annual Report",
128+
activities: formData.activities || [],
129+
regulated_products: formData.regulated_products || [],
130+
};
131+
132+
setFormDataState(updatedFormData);
133+
}, [formData, reportType, allActivities, allRegulatedProducts]);
103134

135+
useEffect(() => {
104136
setSchema((prevSchema) => ({
105137
...prevSchema,
106138
properties: {
107139
...prevSchema.properties,
140+
operation_report_type: {
141+
type: "string",
142+
title: "Please select what type of report you are filling",
143+
enum: ["Annual Report", "Simple Report"],
144+
default: formDataState?.operation_report_type || "Annual Report",
145+
},
146+
// Conditionally render fields based on report type
108147
activities: {
109148
type: "array",
110149
title: "Reporting activities",
@@ -114,6 +153,10 @@ export default function OperationReview({
114153
enumNames: allActivities.map((activity) => activity.name),
115154
},
116155
uniqueItems: true,
156+
// Only show this field if report type is not simple
157+
"ui:options": {
158+
hidden: formDataState.operation_report_type === "Simple Report",
159+
},
117160
},
118161
regulated_products: {
119162
type: "array",
@@ -124,16 +167,20 @@ export default function OperationReview({
124167
enumNames: allRegulatedProducts.map((product) => product.name),
125168
},
126169
uniqueItems: true,
170+
// Only show this field if report type is not simple
171+
"ui:options": {
172+
hidden: formDataState.operation_report_type === "Simple Report",
173+
},
127174
},
128175
operation_representative_name: {
129176
type: "string",
130177
title: "Operation representative",
131-
enum: [formData.operation_representative_name || ""],
178+
enum: [formDataState.operation_representative_name || ""],
132179
},
133180
operation_type: {
134181
type: "string",
135182
title: "Operation type",
136-
enum: [formData.operation_type || ""],
183+
enum: [formDataState.operation_type || ""],
137184
},
138185
date_info: {
139186
type: "object",
@@ -142,18 +189,35 @@ export default function OperationReview({
142189
},
143190
},
144191
}));
192+
}, [allActivities, allRegulatedProducts, formDataState, reportingWindowEnd]);
145193

146-
const updatedFormData = {
147-
...formData,
148-
activities,
149-
regulated_products: products,
194+
useEffect(() => {
195+
const updateUiSchema = () => {
196+
const helperText =
197+
formDataState?.operation_report_type === "Simple Report" ? (
198+
<small>
199+
Regulated or Reporting Operations should file a Simple Report if
200+
their emissions have dropped below 10,000 tCO2e. They will continue
201+
to report using the Simple Report form until they stop Schedule A
202+
activities or stay under 10ktCO2e for three years. This does not
203+
apply to Opt-ins.
204+
</small>
205+
) : null;
206+
207+
setUiSchema({
208+
...operationReviewUiSchema,
209+
operation_report_type: {
210+
"ui:widget": "select", // Set the widget type
211+
"ui:help": helperText,
212+
},
213+
});
150214
};
151215

152-
setFormDataState(updatedFormData);
153-
}, [allActivities, allRegulatedProducts, formData, reportingWindowEnd]);
216+
// Call the function to update the UI schema
217+
updateUiSchema();
218+
}, [formDataState]); // Ensure the effect runs when formDataState changes
154219

155220
if (!formData) {
156-
//we need to render another component which we would display if no version Id exist or we want to show an error
157221
return <div>No version ID found(TBD)</div>;
158222
}
159223

@@ -168,11 +232,12 @@ export default function OperationReview({
168232
]}
169233
taskListElements={taskListElements}
170234
schema={schema}
171-
uiSchema={operationReviewUiSchema}
235+
uiSchema={uiSchema}
172236
formData={formDataState}
173237
baseUrl={baseUrl}
174238
cancelUrl={cancelUrl}
175239
onSubmit={(data) => submitHandler(data, version_id)}
240+
onChange={onChangeHandler} // Pass the onChange handler here
176241
/>
177242
);
178243
}

bciers/apps/reporting/src/app/components/operations/OperationReviewFormData.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { getReportingYear } from "@reporting/src/app/utils/getReportingYear";
33
import { getReportingOperation } from "@reporting/src/app/utils/getReportingOperation";
44
import { getAllActivities } from "@reporting/src/app/utils/getAllReportingActivities";
55
import { getAllRegulatedProducts } from "@reporting/src/app/utils/getAllRegulatedProducts";
6+
import { getReportType } from "@reporting/src/app/utils/getReportType";
67

78
export default async function OperationReviewFormData({
89
version_id,
@@ -13,10 +14,12 @@ export default async function OperationReviewFormData({
1314
const allActivities = await getAllActivities();
1415
const allRegulatedProducts = await getAllRegulatedProducts();
1516
const reportingYear = await getReportingYear();
17+
const reportType = await getReportType(version_id);
1618
return (
1719
<OperationReview
1820
formData={reportOperation}
1921
version_id={version_id}
22+
reportType={reportType}
2023
allActivities={allActivities}
2124
reportingYear={reportingYear}
2225
allRegulatedProducts={allRegulatedProducts}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { actionHandler } from "@bciers/actions";
2+
export async function getReportType(version_id: number) {
3+
let response = await actionHandler(
4+
`reporting/report-version/${version_id}/report-type`,
5+
"GET",
6+
`reporting/report-version/${version_id}/report-type`,
7+
);
8+
if (!response.error) return response;
9+
}

bciers/apps/reporting/src/data/jsonSchema/operations.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,8 @@ export const operationReviewSchema: RJSFSchema = {
2222
operation_report_type: {
2323
type: "string",
2424
title: "Please select what type of report are you filling",
25-
enum: [
26-
"Annual emissions report",
27-
"Regulated partial year operation",
28-
"Simple Report",
29-
],
25+
enum: ["Annual report", "Simple Report"],
26+
default: "Annual report",
3027
},
3128
operation_representative_name: {
3229
type: "string",
@@ -47,6 +44,10 @@ export const operationReviewSchema: RJSFSchema = {
4744
},
4845
operation_bcghgid: { type: "string", title: "BCGHG ID" },
4946
bc_obps_regulated_operation_id: { type: "string", title: "BORO ID" },
47+
registration_pupose: {
48+
type: "string",
49+
title: "Registration Purpose",
50+
},
5051
activities: {
5152
type: "array",
5253
title: "Reporting activities",
@@ -94,14 +95,21 @@ export const operationReviewUiSchema = {
9495
"ui:widget": "select",
9596
"ui:options": { style: { width: "100%", textAlign: "justify" } },
9697
"ui:placeholder": "Report type",
98+
"ui:disabled": true,
9799
},
98100
operation_bcghgid: {
99101
"ui:options": commonUiOptions,
100102
"ui:placeholder": "BCGHG ID",
103+
"ui:disabled": true,
101104
},
102105
bc_obps_regulated_operation_id: {
103106
"ui:options": commonUiOptions,
104107
"ui:placeholder": "BORO ID",
108+
"ui:disabled": true,
109+
},
110+
111+
registration_pupose: {
112+
"ui:placeholder": "Registration Purpose",
105113
},
106114
activities: {
107115
"ui:widget": "MultiSelectWidget",
@@ -121,6 +129,7 @@ export const operationReviewUiSchema = {
121129
"ui:placeholder": "Regulated products",
122130
uniqueItems: true,
123131
},
132+
124133
operation_representative_name: {
125134
"ui:widget": "select",
126135
"ui:options": commonUiOptions,

0 commit comments

Comments
 (0)