Skip to content

Commit

Permalink
Merge branch 'release-0.2.0' into feat/kevin-1387
Browse files Browse the repository at this point in the history
  • Loading branch information
kevin-hashimoto authored Dec 17, 2024
2 parents d87caa7 + bef9b1d commit a53aa91
Show file tree
Hide file tree
Showing 16 changed files with 486 additions and 145 deletions.
1 change: 1 addition & 0 deletions backend/lcfs/web/api/fuel_export/repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ async def create_fuel_export(self, fuel_export: FuelExport) -> FuelExport:
"fuel_type",
"provision_of_the_act",
"end_use_type",
"fuel_code",
],
)
return fuel_export
Expand Down
7 changes: 7 additions & 0 deletions backend/lcfs/web/api/other_uses/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,19 @@ class ExpectedUseTypeSchema(BaseSchema):
description: Optional[str] = None


class FuelCategorySchema(BaseSchema):
fuel_category_id: int
category: str
description: Optional[str] = None


class FuelTypeSchema(BaseSchema):
fuel_type_id: int
fuel_type: str
fossil_derived: Optional[bool] = None
provision_1_id: Optional[int] = None
provision_2_id: Optional[int] = None
fuel_categories: List[FuelCategorySchema]
default_carbon_intensity: Optional[float] = None
fuel_codes: Optional[List[FuelCodeSchema]] = []
provision_of_the_act: Optional[List[ProvisionOfTheActSchema]] = []
Expand Down
2 changes: 2 additions & 0 deletions backend/lcfs/web/application.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import logging
import os
import debugpy
import uuid

import structlog
Expand Down
1 change: 1 addition & 0 deletions frontend/src/assets/locales/en/allocationAgreement.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"noAllocationAgreementsFound": "No allocation agreements found",
"addAllocationAgreementRowsTitle": "Allocation agreements (e.g., allocating responsibility for fuel)",
"allocationAgreementSubtitle": "Enter allocation agreement details below",
"fuelCodeFieldRequiredError": "Error updating row: Fuel code field required",
"allocationAgreementColLabels": {
"transaction": "Responsibility",
"transactionPartner": "Legal name of transaction partner",
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/assets/locales/en/fuelExport.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@
},
"validateMsg": {
"isRequired": "{{field}} is required"
}
},
"fuelCodeFieldRequiredError": "Error updating row: Fuel code field required"
}
1 change: 1 addition & 0 deletions frontend/src/assets/locales/en/fuelSupply.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"LoadFailMsg": "Failed to load supply of fuel rows",
"addRow": "Add row",
"rows": "rows",
"fuelCodeFieldRequiredError": "Error updating row: Fuel code field required",
"fuelSupplyColLabels": {
"complianceReportId": "Compliance Report ID",
"fuelSupplyId": "Fuel supply ID",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/assets/locales/en/otherUses.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"approveConfirmText": "Are you sure you want to approve this other use entry?",
"addRow": "Add row",
"rows": "rows",
"fuelCodeFieldRequiredError": "Error updating row: Fuel code field required",
"otherUsesColLabels": {
"complianceReportId": "Compliance report ID",
"fuelType": "Fuel type",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/BCDataGrid/columns.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const actions = (props) => ({
cellRendererParams: props,
pinned: 'left',
maxWidth: 110,
minWidth: 90,
editable: false,
suppressKeyboardEvent,
filter: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import BCTypography from '@/components/BCTypography'
import Grid2 from '@mui/material/Unstable_Grid2/Grid2'
import { useTranslation } from 'react-i18next'
import { useLocation, useNavigate, useParams } from 'react-router-dom'
import { BCAlert2 } from '@/components/BCAlert'
import BCBox from '@/components/BCBox'
import { BCGridEditor } from '@/components/BCDataGrid/BCGridEditor'
import {
Expand Down Expand Up @@ -169,6 +168,29 @@ export const AddEditAllocationAgreements = () => {
updatedData.ciOfFuel = DEFAULT_CI_FUEL[updatedData.fuelCategory]
}

const isFuelCodeScenario =
params.data.provisionOfTheAct === PROVISION_APPROVED_FUEL_CODE
if (isFuelCodeScenario && !updatedData.fuelCode) {
// Fuel code is required but not provided
setErrors((prevErrors) => ({
...prevErrors,
[params.node.data.id]: ['fuelCode']
}))

alertRef.current?.triggerAlert({
message: t('allocationAgreement:fuelCodeFieldRequiredError'),
severity: 'error'
})

updatedData = {
...updatedData,
validationStatus: 'error'
}

params.node.updateData(updatedData)
return // Stop execution, do not proceed to save
}

try {
setErrors({})
await saveRow(updatedData)
Expand Down
78 changes: 74 additions & 4 deletions frontend/src/views/AllocationAgreements/_schema.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ export const allocationAgreementColDefs = (optionsData, errors) => [
params.data.units = fuelType?.units
params.data.unrecognized = fuelType?.unrecognized
params.data.provisionOfTheAct = null
params.data.fuelCode = undefined
}
return true
},
Expand Down Expand Up @@ -302,16 +303,85 @@ export const allocationAgreementColDefs = (optionsData, errors) => [
}),
cellStyle: (params) => {
const style = StandardCellErrors(params, errors)
const conditionalStyle =
const isFuelCodeScenario =
params.data.provisionOfTheAct === PROVISION_APPROVED_FUEL_CODE
? { backgroundColor: '#fff', borderColor: 'unset' }
: { backgroundColor: '#f2f2f2' }
const fuelType = optionsData?.fuelTypes?.find(
(obj) => params.data.fuelType === obj.fuelType
)
const fuelCodes = fuelType?.fuelCodes || []
const fuelCodeRequiredAndMissing =
isFuelCodeScenario && !params.data.fuelCode

let conditionalStyle = {}

// If required and missing, show red border and white background
if (fuelCodeRequiredAndMissing) {
style.borderColor = 'red'
style.backgroundColor = '#fff'
} else {
// Apply conditional styling if not missing
conditionalStyle =
isFuelCodeScenario && fuelCodes.length > 0
? {
backgroundColor: '#fff',
borderColor: style.borderColor || 'unset'
}
: { backgroundColor: '#f2f2f2' }
}

return { ...style, ...conditionalStyle }
},
suppressKeyboardEvent,
minWidth: 150,
editable: (params) =>
params.data.provisionOfTheAct === PROVISION_APPROVED_FUEL_CODE,
params.data.provisionOfTheAct === PROVISION_APPROVED_FUEL_CODE &&
optionsData?.fuelTypes?.find(
(obj) => params.data.fuelType === obj.fuelType
)?.fuelCodes?.length > 0,
valueGetter: (params) => {
const fuelTypeObj = optionsData?.fuelTypes?.find(
(obj) => params.data.fuelType === obj.fuelType
)
if (!fuelTypeObj) return params.data.fuelCode

const isFuelCodeScenario =
params.data.provisionOfTheAct === PROVISION_APPROVED_FUEL_CODE
const fuelCodes =
fuelTypeObj.fuelCodes?.map((item) => item.fuelCode) || []

if (isFuelCodeScenario && !params.data.fuelCode) {
// Autopopulate if only one fuel code is available
if (fuelCodes.length === 1) {
const singleFuelCode = fuelTypeObj.fuelCodes[0]
params.data.fuelCode = singleFuelCode.fuelCode
params.data.fuelCodeId = singleFuelCode.fuelCodeId
}
}

return params.data.fuelCode
},
valueSetter: (params) => {
if (params.newValue) {
params.data.fuelCode = params.newValue

const fuelType = optionsData?.fuelTypes?.find(
(obj) => params.data.fuelType === obj.fuelType
)
if (params.data.provisionOfTheAct === PROVISION_APPROVED_FUEL_CODE) {
const matchingFuelCode = fuelType?.fuelCodes?.find(
(fuelCode) => params.data.fuelCode === fuelCode.fuelCode
)
if (matchingFuelCode) {
params.data.fuelCodeId = matchingFuelCode.fuelCodeId
}
}
} else {
// If user clears the value
params.data.fuelCode = undefined
params.data.fuelCodeId = undefined
}
return true
},
tooltipValueGetter: (p) => 'Select the approved fuel code'
},
{
Expand Down
34 changes: 32 additions & 2 deletions frontend/src/views/FuelExports/AddEditFuelExports.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useLocation, useNavigate, useParams } from 'react-router-dom'
import { v4 as uuid } from 'uuid'
import { defaultColDef, fuelExportColDefs } from './_schema'
import {
defaultColDef,
fuelExportColDefs,
PROVISION_APPROVED_FUEL_CODE
} from './_schema'

export const AddEditFuelExports = () => {
const [rowData, setRowData] = useState([])
Expand Down Expand Up @@ -143,7 +147,33 @@ export const AddEditFuelExports = () => {
acc[key] = value
return acc
}, {})

updatedData.compliancePeriod = compliancePeriod

// Local validation before saving
const isFuelCodeScenario =
params.data.provisionOfTheAct === PROVISION_APPROVED_FUEL_CODE

if (isFuelCodeScenario && !updatedData.fuelCode) {
// Fuel code is required but not provided
setErrors((prevErrors) => ({
...prevErrors,
[params.node.data.id]: ['fuelCode']
}))

alertRef.current?.triggerAlert({
message: t('fuelExport:fuelCodeFieldRequiredError'),
severity: 'error'
})

updatedData = {
...updatedData,
validationStatus: 'error'
}
params.node.updateData(updatedData)
return // Don't proceed with save
}

try {
setErrors({})
await saveRow(updatedData)
Expand Down Expand Up @@ -189,7 +219,7 @@ export const AddEditFuelExports = () => {

params.node.updateData(updatedData)
},
[saveRow, t]
[saveRow, t, compliancePeriod]
)

const onAction = async (action, params) => {
Expand Down
99 changes: 83 additions & 16 deletions frontend/src/views/FuelExports/_schema.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
fuelTypeOtherConditionalStyle
} from '@/utils/fuelTypeOther'

export const PROVISION_APPROVED_FUEL_CODE = 'Fuel code - section 19 (b) (i)'

const cellErrorStyle = (params, errors) => {
let style = {}
if (
Expand Down Expand Up @@ -318,29 +320,94 @@ export const fuelExportColDefs = (optionsData, errors) => [
field: 'fuelCode',
headerName: i18n.t('fuelExport:fuelExportColLabels.fuelCode'),
cellEditor: 'agSelectCellEditor',
cellEditorParams: (params) => ({
values: optionsData?.fuelTypes
?.find((obj) => params.data.fuelType === obj.fuelType)
?.fuelCodes.map((item) => item.fuelCode)
}),
suppressKeyboardEvent,
minWidth: 135,
cellEditorParams: (params) => {
const fuelTypeObj = optionsData?.fuelTypes?.find(
(obj) => params.data.fuelType === obj.fuelType
)
return {
values: fuelTypeObj?.fuelCodes?.map((item) => item.fuelCode) || []
}
},
cellStyle: (params) => {
const style = cellErrorStyle(params, errors)
const fuelTypeObj = optionsData?.fuelTypes?.find(
(obj) => params.data.fuelType === obj.fuelType
)
const fuelCodes =
fuelTypeObj?.fuelCodes.map((item) => item.fuelCode) || []
const isFuelCodeScenario =
params.data.provisionOfTheAct === PROVISION_APPROVED_FUEL_CODE

// Check if fuel code is required (scenario) but missing
const fuelCodeRequiredAndMissing =
isFuelCodeScenario && !params.data.fuelCode

if (fuelCodeRequiredAndMissing) {
// If required and missing, force a red border
style.borderColor = 'red'
}

const conditionalStyle =
optionsData?.fuelTypes
?.find((obj) => params.data.fuelType === obj.fuelType)
?.fuelCodes.map((item) => item.fuelCode).length > 0 &&
/Fuel code/i.test(params.data.provisionOfTheAct)
fuelCodes.length > 0 &&
isFuelCodeScenario &&
!fuelCodeRequiredAndMissing
? { backgroundColor: '#fff', borderColor: 'unset' }
: { backgroundColor: '#f2f2f2' }
return { ...style, ...conditionalStyle }
},
suppressKeyboardEvent,
minWidth: 135,
editable: (params) =>
optionsData?.fuelTypes
?.find((obj) => params.data.fuelType === obj.fuelType)
?.fuelCodes.map((item) => item.fuelCode).length > 0 &&
/Fuel code/i.test(params.data.provisionOfTheAct)
editable: (params) => {
const fuelTypeObj = optionsData?.fuelTypes?.find(
(obj) => params.data.fuelType === obj.fuelType
)
const fuelCodes = fuelTypeObj?.fuelCodes || []
return (
fuelCodes.length > 0 &&
params.data.provisionOfTheAct === PROVISION_APPROVED_FUEL_CODE
)
},
valueGetter: (params) => {
const fuelTypeObj = optionsData?.fuelTypes?.find(
(obj) => params.data.fuelType === obj.fuelType
)
if (!fuelTypeObj) return params.data.fuelCode

const isFuelCodeScenario =
params.data.provisionOfTheAct === PROVISION_APPROVED_FUEL_CODE
const fuelCodes =
fuelTypeObj.fuelCodes?.map((item) => item.fuelCode) || []

if (isFuelCodeScenario && !params.data.fuelCode) {
// Autopopulate if only one fuel code is available
if (fuelCodes.length === 1) {
const singleFuelCode = fuelTypeObj.fuelCodes[0]
params.data.fuelCode = singleFuelCode.fuelCode
params.data.fuelCodeId = singleFuelCode.fuelCodeId
}
}

return params.data.fuelCode
},
valueSetter: (params) => {
const newCode = params.newValue
const fuelTypeObj = optionsData?.fuelTypes?.find(
(obj) => params.data.fuelType === obj.fuelType
)
const selectedFuelCodeObj = fuelTypeObj?.fuelCodes.find(
(item) => item.fuelCode === newCode
)

if (selectedFuelCodeObj) {
params.data.fuelCode = selectedFuelCodeObj.fuelCode
params.data.fuelCodeId = selectedFuelCodeObj.fuelCodeId
} else {
params.data.fuelCode = undefined
params.data.fuelCodeId = undefined
}

return true
}
},
{
field: 'quantity',
Expand Down
Loading

0 comments on commit a53aa91

Please sign in to comment.