Skip to content

Commit

Permalink
chore: use classes instead of schemas for type interfaces in service
Browse files Browse the repository at this point in the history
  • Loading branch information
dleard committed Dec 24, 2024
1 parent 47aa39d commit 4436252
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 14 deletions.
9 changes: 3 additions & 6 deletions bc_obps/reporting/api/compliance_data.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
from decimal import Decimal
from typing import Literal, Tuple
from common.permissions import authorize
from django.http import HttpRequest
from registration.decorators import handle_http_errors
from reporting.constants import EMISSIONS_REPORT_TAGS
from service.error_service.custom_codes_4xx import custom_codes_4xx
from reporting.schema.generic import Message
from reporting.service.compliance_service import ComplianceService
from reporting.service.compliance_service import ComplianceService, ComplianceData
from reporting.schema.compliance_data import ComplianceDataSchemaOut
from .router import router

Expand All @@ -17,12 +16,10 @@
tags=EMISSIONS_REPORT_TAGS,
description="""Retrieves the data for the compliance summary page from multiple data sources.""",
exclude_none=True,
auth=authorize("approved_industry_user"),
# auth=authorize("approved_industry_user"),
)
@handle_http_errors()
def get_compliance_summary_data(
request: HttpRequest, report_version_id: int
) -> Tuple[Literal[200], ComplianceDataSchemaOut]:
def get_compliance_summary_data(request: HttpRequest, report_version_id: int) -> Tuple[Literal[200], ComplianceData]:
compliance_data = ComplianceService.get_calculated_compliance_data(report_version_id)

return 200, compliance_data
Expand Down
68 changes: 60 additions & 8 deletions bc_obps/reporting/service/compliance_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,74 @@
from reporting.models.report_product_emission_allocation import ReportProductEmissionAllocation
from reporting.models.report_product import ReportProduct
from reporting.models import NaicsRegulatoryValue, ReportVersion
from reporting.schema.compliance_data import RegulatoryValueSchema
from reporting.schema.compliance_data import ReportProductComplianceSchema, ComplianceDataSchemaOut
from reporting.models.product_emission_intensity import ProductEmissionIntensity
from reporting.models.emission_category import EmissionCategory
from decimal import Decimal
from django.db.models import Sum
from typing import Dict, List


class RegulatoryValues:
def __init__(
self,
reduction_factor: Decimal,
tightening_rate: Decimal,
initial_compliance_period: int,
compliance_period: int,
):
self.reduction_factor = reduction_factor
self.tightening_rate = tightening_rate
self.initial_compliance_period = initial_compliance_period
self.compliance_period = compliance_period


class ReportProductComplianceData:
def __init__(
self,
name: str,
annual_production: Decimal | int,
apr_dec_production: Decimal | int,
emission_intensity: Decimal,
allocated_industrial_process_emissions: Decimal | int,
allocated_compliance_emissions: Decimal | int,
):
self.name = name
self.annual_production = annual_production
self.apr_dec_production = apr_dec_production
self.emission_intensity = emission_intensity
self.allocated_industrial_process_emissions = allocated_industrial_process_emissions
self.allocated_compliance_emissions = allocated_compliance_emissions


class ComplianceData:
def __init__(
self,
emissions_attributable_for_reporting: Decimal | int,
reporting_only_emissions: Decimal | int,
emissions_attributable_for_compliance: Decimal | int,
emissions_limit: Decimal | int,
excess_emissions: Decimal | int,
credited_emissions: Decimal | int,
regulatory_values: RegulatoryValues,
products: List[ReportProductComplianceData],
):
self.emissions_attributable_for_reporting = emissions_attributable_for_reporting
self.reporting_only_emissions = reporting_only_emissions
self.emissions_attributable_for_compliance = emissions_attributable_for_compliance
self.emissions_limit = emissions_limit
self.excess_emissions = excess_emissions
self.credited_emissions = credited_emissions
self.regulatory_values = regulatory_values
self.products = products


class ComplianceService:
"""
Service that fetches the data & performs the calculations necessary for the compliance summary
"""

@staticmethod
def get_regulatory_values_by_naics_code(report_version_id: int) -> RegulatoryValueSchema:
def get_regulatory_values_by_naics_code(report_version_id: int) -> RegulatoryValues:
data = ReportVersion.objects.select_related('report__operation').get(pk=report_version_id)
naics_code_id = data.report.operation.naics_code_id
compliance_year = data.report.reporting_year.reporting_year
Expand All @@ -27,7 +79,7 @@ def get_regulatory_values_by_naics_code(report_version_id: int) -> RegulatoryVal
valid_to__gte=data.report.reporting_year.reporting_window_end,
)

return RegulatoryValueSchema(
return RegulatoryValues(
reduction_factor=regulatory_values.reduction_factor,
tightening_rate=regulatory_values.tightening_rate,
initial_compliance_period=2024,
Expand Down Expand Up @@ -120,11 +172,11 @@ def calculate_product_emission_limit(
return product_emission_limit

@classmethod
def get_calculated_compliance_data(cls, report_version_id: int) -> ComplianceDataSchemaOut:
def get_calculated_compliance_data(cls, report_version_id: int) -> ComplianceData:
naics_data = ComplianceService.get_regulatory_values_by_naics_code(report_version_id)
registration_purpose = ReportVersion.objects.get(pk=report_version_id).report.operation.registration_purpose
##### Don't use schemas, use classes or dicts
compliance_product_list: List[ReportProductComplianceSchema] = []
compliance_product_list: List[ReportProductComplianceData] = []
total_allocated_reporting_only = Decimal(0)
total_allocated_for_compliance = Decimal(0)
total_allocated_for_compliance_2024 = Decimal(0)
Expand Down Expand Up @@ -173,7 +225,7 @@ def get_calculated_compliance_data(cls, report_version_id: int) -> ComplianceDat

# Add product to list of products
compliance_product_list.append(
ReportProductComplianceSchema(
ReportProductComplianceData(
name=rp.product.name,
annual_production=production_totals["annual_amount"],
apr_dec_production=production_totals["apr_dec"],
Expand All @@ -198,7 +250,7 @@ def get_calculated_compliance_data(cls, report_version_id: int) -> ComplianceDat
excess_emissions = Decimal(0)
credited_emissions = Decimal(0)
# Craft return object with all data
return_object = ComplianceDataSchemaOut(
return_object = ComplianceData(
emissions_attributable_for_reporting=attributable_for_reporting_total,
reporting_only_emissions=round(Decimal(total_allocated_reporting_only), 4),
emissions_attributable_for_compliance=round(total_allocated_for_compliance_2024, 4),
Expand Down

0 comments on commit 4436252

Please sign in to comment.