Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: LCFS - backend filter logic on the Compliance Report index #1809 #1864

Merged
merged 9 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 36 additions & 11 deletions backend/lcfs/web/api/compliance_report/repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from fastapi import Depends
from sqlalchemy import func, select, and_, asc, desc, update
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import joinedload, contains_eager
from sqlalchemy.orm import joinedload, contains_eager, aliased

from lcfs.db.dependencies import get_async_db_session
from lcfs.db.models.compliance import CompliancePeriod
Expand Down Expand Up @@ -364,8 +364,6 @@ async def get_reports_paginated(
# Base query conditions
conditions = []
sub_conditions = []
if organization_id:
sub_conditions.append(ComplianceReport.organization_id == organization_id)

if pagination.filters and len(pagination.filters) > 0:
self.apply_sub_filters(pagination, sub_conditions)
Expand All @@ -376,19 +374,37 @@ async def get_reports_paginated(
limit = pagination.size

# Build the main query
subquery = (
latest_version_subquery = (
select(
ComplianceReport.compliance_report_group_uuid,
func.max(ComplianceReport.version).label("latest_version"),
)
.where(and_(*sub_conditions))
.group_by(ComplianceReport.compliance_report_group_uuid)
)
if organization_id:
latest_version_subquery = latest_version_subquery.where(ComplianceReport.organization_id == organization_id)
latest_version_subquery = latest_version_subquery.subquery()
cr_alias = aliased(ComplianceReport)

subquery = subquery.join(
ComplianceReportStatus,
ComplianceReport.current_status_id
== ComplianceReportStatus.compliance_report_status_id,
subquery = (
select(
cr_alias.compliance_report_group_uuid,
cr_alias.version.label('latest_version'),
)
.join(
latest_version_subquery,
and_(
cr_alias.compliance_report_group_uuid
== latest_version_subquery.c.compliance_report_group_uuid,
cr_alias.version == latest_version_subquery.c.latest_version,
),
)
.join(
ComplianceReportStatus,
cr_alias.current_status_id
== ComplianceReportStatus.compliance_report_status_id,
)
.where(and_(*sub_conditions))
)

subquery = subquery.subquery()
Expand Down Expand Up @@ -428,6 +444,9 @@ async def get_reports_paginated(
)

# Apply sorting from pagination
if len(pagination.sort_orders) < 1:
field = get_field_for_filter(ComplianceReport, "update_date")
query = query.order_by(desc(field))
for order in pagination.sort_orders:
sort_method = asc if order.direction == "asc" else desc
if order.field == "status":
Expand Down Expand Up @@ -753,10 +772,16 @@ def aggregate_quantities(

for record in records:
# Check if record matches fossil_derived filter
if isinstance(record, FuelSupply) and record.fuel_type.fossil_derived == fossil_derived:
if (
isinstance(record, FuelSupply)
and record.fuel_type.fossil_derived == fossil_derived
):
fuel_category = self._format_category(record.fuel_category.category)
fuel_quantities[fuel_category] += record.quantity
elif isinstance(record, OtherUses) and record.fuel_type.fossil_derived == fossil_derived:
elif (
isinstance(record, OtherUses)
and record.fuel_type.fossil_derived == fossil_derived
):
fuel_category = self._format_category(record.fuel_category.category)
fuel_quantities[fuel_category] += record.quantity_supplied

Expand Down
7 changes: 0 additions & 7 deletions backend/lcfs/web/api/organization/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,6 @@ async def get_organization_users_list(
"""
Get all users for the organization
"""
# Add Organization and status to filter
if (pagination.filters is None) or (len(pagination.filters) == 0):
pagination.filters.append(
FilterModel(
filter_type="text", field="is_active", type="equals", filter=status
)
)
pagination.filters.append(
FilterModel(
filter_type="number",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/BCDataGrid/BCGridViewer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export const BCGridViewer = ({
const columnState = JSON.parse(localStorage.getItem(`${gridKey}-column`))
if (filterState) {
params.api.setFilterModel(filterState)
setFilterModel(filterState)
}
if (columnState) {
params.api.applyColumnState({
Expand Down
42 changes: 42 additions & 0 deletions frontend/src/hooks/useComplianceReports.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { apiRoutes } from '@/constants/routes'
import { useApiService } from '@/services/useApiService'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useCurrentUser } from './useCurrentUser'
import { roles } from '@/constants/roles'

export const useCompliancePeriod = (options) => {
const client = useApiService()
Expand Down Expand Up @@ -158,3 +160,43 @@ export const useCreateSupplementalReport = (reportID, options) => {
}
})
}

export const useGetComplianceReportList = (
{ page = 1, size = 10, sortOrders = [], filters = [] } = {},
options
) => {
const client = useApiService()
const { data: currentUser, hasRoles } = useCurrentUser()

return useQuery({
queryKey: ['compliance-reports-list', page, size, sortOrders, filters],
queryFn: async () => {
if (hasRoles(roles.supplier)) {
return (
await client.post(
apiRoutes.getOrgComplianceReports.replace(
':orgID',
currentUser?.organization?.organizationId
),
{
page,
size,
sortOrders,
filters
}
)
).data
} else {
return (
await client.post(apiRoutes.getComplianceReports, {
page,
size,
sortOrders,
filters
})
).data
}
},
...options
})
}
55 changes: 21 additions & 34 deletions frontend/src/views/ComplianceReports/ComplianceReports.jsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,44 @@
import { Stack } from '@mui/material'
import BCBox from '@/components/BCBox'
import BCAlert from '@/components/BCAlert'
import BCDataGridServer from '@/components/BCDataGrid/BCDataGridServer'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useLocation, useNavigate } from 'react-router-dom'
import { Role } from '@/components/Role'
import { roles } from '@/constants/roles'
import { apiRoutes, ROUTES } from '@/constants/routes'
import { ROUTES } from '@/constants/routes'
import { COMPLIANCE_REPORT_STATUSES } from '@/constants/statuses'
import { useCurrentUser } from '@/hooks/useCurrentUser'
import { useCreateComplianceReport } from '@/hooks/useComplianceReports'
import { defaultSortModel, reportsColDefs } from './components/_schema'
import {
useCreateComplianceReport,
useGetComplianceReportList
} from '@/hooks/useComplianceReports'
import { reportsColDefs } from './components/_schema'
import { NewComplianceReportButton } from './components/NewComplianceReportButton'
import BCTypography from '@/components/BCTypography'
import { ClearFiltersButton } from '@/components/ClearFiltersButton'
import { LinkRenderer } from '@/utils/grid/cellRenderers.jsx'
import { BCGridViewer } from '@/components/BCDataGrid/BCGridViewer'

export const ComplianceReports = () => {
const { t } = useTranslation(['common', 'report'])
const [alertMessage, setAlertMessage] = useState('')
const [isButtonLoading, setIsButtonLoading] = useState(false)
const [resetGridFn, setResetGridFn] = useState(null)
const [alertSeverity, setAlertSeverity] = useState('info')
const [gridKey, setGridKey] = useState(`compliance-reports-grid`)

const gridRef = useRef()
const alertRef = useRef()
const navigate = useNavigate()
const location = useLocation()
const newButtonRef = useRef(null);
const newButtonRef = useRef(null)
const { hasRoles, data: currentUser } = useCurrentUser()

const gridOptions = useMemo(
() => ({
overlayNoRowsTemplate: t('report:noReportsFound')
}),
[t]
)
const getRowId = useCallback(
(params) => params.data.complianceReportId.toString(),
(params) => params.data.complianceReportGroupUuid,
[]
)

const handleGridKey = useCallback(() => {
setGridKey('reports-grid')
}, [])

useEffect(() => {
if (location.state?.message) {
setAlertMessage(location.state.message)
Expand Down Expand Up @@ -156,25 +148,20 @@ export const ComplianceReports = () => {
}}
/>
<BCBox component="div" sx={{ height: '100%', width: '100%' }}>
<BCDataGridServer
<BCGridViewer
gridRef={gridRef}
apiEndpoint={
hasRoles(roles.supplier)
? apiRoutes.getOrgComplianceReports.replace(
':orgID',
currentUser?.organization?.organizationId
)
: apiRoutes.getComplianceReports
}
apiData={'reports'}
gridKey={'compliance-reports-grid'}
columnDefs={reportsColDefs(t, hasRoles(roles.supplier))}
gridKey={gridKey}
query={useGetComplianceReportList}
queryParams={{ cacheTime: 0, staleTime: 0 }}
dataKey={'reports'}
getRowId={getRowId}
defaultSortModel={defaultSortModel}
defaultFilterModel={location.state?.filters}
gridOptions={gridOptions}
handleGridKey={handleGridKey}
enableCopyButton={false}
overlayNoRowsTemplate={t('report:noReportsFound')}
autoSizeStrategy={{
type: 'fitGridWidth',
defaultMinWidth: 50,
defaultMaxWidth: 600
}}
defaultColDef={defaultColDef}
onSetResetGrid={handleSetResetGrid}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ vi.mock('../components/NewComplianceReportButton', () => ({
)
}))

vi.mock('@/components/BCDataGrid/BCDataGridServer', () => ({
default: () => <div data-test="bc-data-grid">BCDataGridServer</div>
vi.mock('@/components/BCDataGrid/BCGridViewer', () => ({
BCGridViewer: () => <div data-test="bc-data-grid">BCGridViewer</div>
}))

describe('ComplianceReports', () => {
Expand Down Expand Up @@ -99,7 +99,7 @@ describe('ComplianceReports', () => {
expect(screen.getByText('New Report')).toBeInTheDocument()
})

it('renders the BCDataGridServer', () => {
it('renders the BCGridViewer', () => {
customRender(<ComplianceReports />)
expect(screen.getByTestId('bc-data-grid')).toBeInTheDocument()
})
Expand Down