Skip to content

Commit

Permalink
Merge branch 'release-0.2.0' into chore/alex-etl-launch
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexZorkin authored Dec 23, 2024
2 parents 9a630ac + 92591f1 commit 5566bde
Show file tree
Hide file tree
Showing 53 changed files with 1,597 additions and 472 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""update other diesel
Revision ID: 59873cafbcd8
Revises: 851e09cf8661
Create Date: 2024-12-20 05:17:40.638826
"""

import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "59873cafbcd8"
down_revision = "851e09cf8661"
branch_labels = None
depends_on = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.execute(
"""
UPDATE fuel_type
SET fossil_derived = false, other_uses_fossil_derived = false
WHERE fuel_type = 'Other diesel'
"""
)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.execute(
"""
UPDATE fuel_type
SET fossil_derived = true, other_uses_fossil_derived = true
WHERE fuel_type = 'Other diesel'
"""
)
# ### end Alembic commands ###
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""LNG end use naming change
Revision ID: 5fbcb508c1be
Revises: 59873cafbcd8
Create Date: 2024-12-21 00:18:12.324520
"""

import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "5fbcb508c1be"
down_revision = "59873cafbcd8"
branch_labels = None
depends_on = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.execute(
"""
UPDATE end_use_type
SET type = 'Compression-ignition engine- Marine, with methane slip reduction kit- Operated within 26 to 75% of load range'
WHERE end_use_type_id = 19
"""
)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.execute(
"""
UPDATE end_use_type
SET type = 'Compression-ignition engine- Marine, with methane slip reduction kit- Operated within 51 to 75% of load range'
WHERE end_use_type_id = 19
"""
)
# ### end Alembic commands ###
8 changes: 4 additions & 4 deletions backend/lcfs/db/seeders/common/seed_fuel_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,8 @@
{
"fuel_type_id": 20,
"fuel_type": "Other diesel",
"fossil_derived": true,
"other_uses_fossil_derived": true,
"fossil_derived": false,
"other_uses_fossil_derived": false,
"provision_1_id": 1,
"default_carbon_intensity": 100.21,
"units": "L",
Expand Down Expand Up @@ -355,7 +355,7 @@
},
{
"end_use_type_id": 19,
"type": "Compression-ignition engine- Marine, with methane slip reduction kit- Operated within 51 to 75% of load range",
"type": "Compression-ignition engine- Marine, with methane slip reduction kit- Operated within 26 to 75% of load range",
"intended_use": true
},
{
Expand Down Expand Up @@ -1095,4 +1095,4 @@
"display_order": 4
}
]
}
}
3 changes: 3 additions & 0 deletions backend/lcfs/services/rabbitmq/report_consumer.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ async def handle_message(
)
user = await UserRepository(db=session).get_user_by_id(user_id)

if not user:
logger.error(f"Cannot parse Report {legacy_id} from TFRS, no user with ID {user_id}")

if action == "Created":
await self._handle_created(
org_id,
Expand Down
27 changes: 26 additions & 1 deletion backend/lcfs/services/s3/client.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from fastapi import HTTPException
import os
import uuid
from lcfs.db.models.compliance.ComplianceReportStatus import ComplianceReportStatusEnum
from lcfs.db.models.user.Role import RoleEnum
from lcfs.web.api.compliance_report.services import ComplianceReportServices
from fastapi import Depends
from pydantic.v1 import ValidationError
from sqlalchemy import select
Expand All @@ -26,13 +30,34 @@ def __init__(
db: AsyncSession = Depends(get_async_db_session),
clamav_service: ClamAVService = Depends(),
s3_client=Depends(get_s3_client),
compliance_report_service: ComplianceReportServices = Depends(),
):
self.db = db
self.clamav_service = clamav_service
self.s3_client = s3_client
self.compliance_report_service = compliance_report_service

@repo_handler
async def upload_file(self, file, parent_id: str, parent_type="compliance_report"):
async def upload_file(
self, file, parent_id: str, parent_type="compliance_report", user=None
):
compliance_report = (
await self.compliance_report_service.get_compliance_report_by_id(parent_id)
)
if not compliance_report:
raise HTTPException(status_code=404, detail="Compliance report not found")

# Check if the user is a supplier and the compliance report status is different from Draft
if (
RoleEnum.SUPPLIER in user.role_names
and compliance_report.current_status.status
!= ComplianceReportStatusEnum.Draft.value
):
raise HTTPException(
status_code=400,
detail="Suppliers can only upload files when the compliance report status is Draft",
)

file_id = uuid.uuid4()
file_key = f"{settings.s3_docs_path}/{parent_type}/{parent_id}/{file_id}"

Expand Down
22 changes: 15 additions & 7 deletions backend/lcfs/tests/compliance_report/test_summary_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ async def test_calculate_low_carbon_fuel_target_summary(

# Assertions
assert isinstance(summary, list)
assert all(isinstance(item, ComplianceReportSummaryRowSchema) for item in summary)
assert all(isinstance(item, ComplianceReportSummaryRowSchema)
for item in summary)
assert len(summary) == 11 # Ensure all 11 lines are present

# Check specific line values
Expand Down Expand Up @@ -510,7 +511,8 @@ async def test_calculate_renewable_fuel_target_summary_no_renewables(

assert len(result) == 11
assert isinstance(result[0], ComplianceReportSummaryRowSchema)
assert result[10].gasoline == 15.0 # Penalty should be applied due to no renewables
# Penalty should be applied due to no renewables
assert result[10].gasoline == 15.0
assert result[10].diesel == 36.0
assert result[10].jet_fuel == 45.0
assert result[10].total_value == 96.0
Expand Down Expand Up @@ -548,14 +550,12 @@ async def test_calculate_renewable_fuel_target_summary_high_renewables(

assert len(result) == 11
assert isinstance(result[0], ComplianceReportSummaryRowSchema)
assert result[10].gasoline == 0 # No penalty since renewables exceed requirements
# No penalty since renewables exceed requirements
assert result[10].gasoline == 0
assert result[10].diesel == 0
assert result[10].jet_fuel == 0


import pytest


@pytest.mark.anyio
async def test_calculate_renewable_fuel_target_summary_copy_lines_6_and_8(
compliance_report_summary_service,
Expand Down Expand Up @@ -710,6 +710,13 @@ async def test_can_sign_flag_logic(
"jet_fuel": 25,
}
)
mock_repo.aggregate_other_uses = AsyncMock(
return_value={
"gasoline": 50,
"diesel": 25,
"jet_fuel": 10,
}
)
mock_repo.get_assessed_compliance_report_by_period = AsyncMock(
return_value=MagicMock(
summary=MagicMock(
Expand Down Expand Up @@ -810,7 +817,8 @@ async def test_calculate_fuel_quantities_renewable(
):
# Create a mock repository
mock_repo.aggregate_fuel_supplies.return_value = {"gasoline": 200.0}
mock_repo.aggregate_other_uses.return_value = {"diesel": 75.0, "jet-fuel": 25.0}
mock_repo.aggregate_other_uses.return_value = {
"diesel": 75.0, "jet-fuel": 25.0}

# Define test inputs
compliance_report_id = 2
Expand Down
35 changes: 23 additions & 12 deletions backend/lcfs/tests/fuel_code/test_fuel_code_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ async def test_get_fuel_categories(fuel_code_repo, mock_db):


@pytest.mark.anyio
async def test_get_fuel_category_by_name(fuel_code_repo, mock_db):
async def test_get_fuel_category_by(fuel_code_repo, mock_db):
mock_fc = FuelCategory(
fuel_category_id=2, category="Fossil", default_carbon_intensity=0
)
Expand Down Expand Up @@ -327,7 +327,8 @@ async def test_get_fuel_codes_paginated(fuel_code_repo, mock_db):
unique=MagicMock(
return_value=MagicMock(
scalars=MagicMock(
return_value=MagicMock(all=MagicMock(return_value=[fc]))
return_value=MagicMock(
all=MagicMock(return_value=[fc]))
)
)
)
Expand All @@ -342,7 +343,8 @@ async def test_get_fuel_codes_paginated(fuel_code_repo, mock_db):

@pytest.mark.anyio
async def test_get_fuel_code_statuses(fuel_code_repo, mock_db):
fcs = FuelCodeStatus(fuel_code_status_id=1, status=FuelCodeStatusEnum.Approved)
fcs = FuelCodeStatus(fuel_code_status_id=1,
status=FuelCodeStatusEnum.Approved)
mock_result = MagicMock()
mock_result.scalars.return_value.all.return_value = [fcs]
mock_db.execute.return_value = mock_result
Expand Down Expand Up @@ -371,7 +373,8 @@ async def test_get_fuel_code(fuel_code_repo, mock_db, valid_fuel_code):

@pytest.mark.anyio
async def test_get_fuel_code_status_enum(fuel_code_repo, mock_db):
fcs = FuelCodeStatus(fuel_code_status_id=2, status=FuelCodeStatusEnum.Deleted)
fcs = FuelCodeStatus(fuel_code_status_id=2,
status=FuelCodeStatusEnum.Deleted)
mock_db.scalar.return_value = fcs
result = await fuel_code_repo.get_fuel_code_status(FuelCodeStatusEnum.Deleted)
assert result == fcs
Expand Down Expand Up @@ -403,7 +406,8 @@ async def test_delete_fuel_code(fuel_code_repo, mock_db):
@pytest.mark.anyio
async def test_get_distinct_company_names(fuel_code_repo, mock_db):
mock_result = MagicMock()
mock_result.scalars.return_value.all.return_value = ["CompanyA", "CompanyB"]
mock_result.scalars.return_value.all.return_value = [
"CompanyA", "CompanyB"]
mock_db.execute.return_value = mock_result

result = await fuel_code_repo.get_distinct_company_names("Com")
Expand All @@ -413,7 +417,8 @@ async def test_get_distinct_company_names(fuel_code_repo, mock_db):
@pytest.mark.anyio
async def test_get_contact_names_by_company(fuel_code_repo, mock_db):
mock_result = MagicMock()
mock_result.scalars.return_value.all.return_value = ["John Doe", "Jane Doe"]
mock_result.scalars.return_value.all.return_value = [
"John Doe", "Jane Doe"]
mock_db.execute.return_value = mock_result

result = await fuel_code_repo.get_contact_names_by_company("CompanyA", "J")
Expand Down Expand Up @@ -446,7 +451,8 @@ async def test_get_distinct_fuel_codes_by_code(fuel_code_repo, mock_db):
async def test_get_fuel_code_by_code_prefix(fuel_code_repo, mock_db):
fc = FuelCode(fuel_code_id=10, fuel_suffix="200.0")
mock_result = MagicMock()
mock_result.unique.return_value.scalars.return_value.all.return_value = [fc]
mock_result.unique.return_value.scalars.return_value.all.return_value = [
fc]
mock_db.execute.return_value = mock_result

# Mock the next available suffix
Expand Down Expand Up @@ -612,7 +618,8 @@ async def test_get_standardized_fuel_data(fuel_code_repo, mock_db):
MagicMock(
scalars=MagicMock(
return_value=MagicMock(
first=MagicMock(return_value=EnergyEffectivenessRatio(ratio=2.0))
first=MagicMock(
return_value=EnergyEffectivenessRatio(ratio=2.0))
)
)
),
Expand Down Expand Up @@ -669,7 +676,8 @@ async def test_get_standardized_fuel_data_unrecognized(fuel_code_repo, mock_db):
mock_db.get_one.return_value = mock_fuel_type

# Mock the repo method to get the fuel category
fuel_code_repo.get_fuel_category_by = AsyncMock(return_value=mock_fuel_category)
fuel_code_repo.get_fuel_category_by = AsyncMock(
return_value=mock_fuel_category)

# Setup side effects for subsequent queries:
# Energy Density
Expand All @@ -684,7 +692,8 @@ async def test_get_standardized_fuel_data_unrecognized(fuel_code_repo, mock_db):
eer_result = MagicMock(
scalars=MagicMock(
return_value=MagicMock(
first=MagicMock(return_value=EnergyEffectivenessRatio(ratio=2.0))
first=MagicMock(
return_value=EnergyEffectivenessRatio(ratio=2.0))
)
)
)
Expand All @@ -693,7 +702,8 @@ async def test_get_standardized_fuel_data_unrecognized(fuel_code_repo, mock_db):
scalars=MagicMock(
return_value=MagicMock(
all=MagicMock(
return_value=[TargetCarbonIntensity(target_carbon_intensity=50.0)]
return_value=[TargetCarbonIntensity(
target_carbon_intensity=50.0)]
)
)
)
Expand Down Expand Up @@ -729,7 +739,8 @@ async def test_get_standardized_fuel_data_unrecognized(fuel_code_repo, mock_db):
assert result.uci == 5.0

# Ensure get_fuel_category_by was called once with the correct parameter
fuel_code_repo.get_fuel_category_by.assert_awaited_once_with(fuel_category_id=2)
fuel_code_repo.get_fuel_category_by.assert_awaited_once_with(
fuel_category_id=2)


@pytest.mark.anyio
Expand Down
2 changes: 1 addition & 1 deletion backend/lcfs/tests/fuel_export/test_fuel_exports_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ async def test_update_fuel_export_success(fuel_export_repo, mock_db):
)
updated_fuel_export = FuelExport(fuel_export_id=1)

mock_db.merge = MagicMock(return_value=updated_fuel_export)
mock_db.merge = AsyncMock(return_value=updated_fuel_export)
mock_db.flush = AsyncMock()
mock_db.refresh = AsyncMock()

Expand Down
Loading

0 comments on commit 5566bde

Please sign in to comment.