feat: add export filters for projects and scenarios with filtering capabilities
This commit is contained in:
@@ -11,6 +11,7 @@ from sqlalchemy.orm import Session, joinedload, selectinload
|
||||
from models import (
|
||||
FinancialInput,
|
||||
Project,
|
||||
ResourceType,
|
||||
Role,
|
||||
Scenario,
|
||||
ScenarioStatus,
|
||||
@@ -19,6 +20,7 @@ from models import (
|
||||
UserRole,
|
||||
)
|
||||
from services.exceptions import EntityConflictError, EntityNotFoundError
|
||||
from services.export_query import ProjectExportFilters, ScenarioExportFilters
|
||||
|
||||
|
||||
class ProjectRepository:
|
||||
@@ -79,6 +81,52 @@ class ProjectRepository:
|
||||
records = self.session.execute(stmt).scalars().all()
|
||||
return {project.name.lower(): project for project in records}
|
||||
|
||||
def filtered_for_export(
|
||||
self,
|
||||
filters: ProjectExportFilters | None = None,
|
||||
*,
|
||||
include_scenarios: bool = False,
|
||||
) -> Sequence[Project]:
|
||||
stmt = select(Project)
|
||||
if include_scenarios:
|
||||
stmt = stmt.options(selectinload(Project.scenarios))
|
||||
|
||||
if filters:
|
||||
ids = filters.normalised_ids()
|
||||
if ids:
|
||||
stmt = stmt.where(Project.id.in_(ids))
|
||||
|
||||
name_matches = filters.normalised_names()
|
||||
if name_matches:
|
||||
stmt = stmt.where(func.lower(Project.name).in_(name_matches))
|
||||
|
||||
name_pattern = filters.name_search_pattern()
|
||||
if name_pattern:
|
||||
stmt = stmt.where(Project.name.ilike(name_pattern))
|
||||
|
||||
locations = filters.normalised_locations()
|
||||
if locations:
|
||||
stmt = stmt.where(func.lower(Project.location).in_(locations))
|
||||
|
||||
if filters.operation_types:
|
||||
stmt = stmt.where(Project.operation_type.in_(
|
||||
filters.operation_types))
|
||||
|
||||
if filters.created_from:
|
||||
stmt = stmt.where(Project.created_at >= filters.created_from)
|
||||
|
||||
if filters.created_to:
|
||||
stmt = stmt.where(Project.created_at <= filters.created_to)
|
||||
|
||||
if filters.updated_from:
|
||||
stmt = stmt.where(Project.updated_at >= filters.updated_from)
|
||||
|
||||
if filters.updated_to:
|
||||
stmt = stmt.where(Project.updated_at <= filters.updated_to)
|
||||
|
||||
stmt = stmt.order_by(Project.name, Project.id)
|
||||
return self.session.execute(stmt).scalars().all()
|
||||
|
||||
def delete(self, project_id: int) -> None:
|
||||
project = self.get(project_id)
|
||||
self.session.delete(project)
|
||||
@@ -177,6 +225,76 @@ class ScenarioRepository:
|
||||
records = self.session.execute(stmt).scalars().all()
|
||||
return {scenario.name.lower(): scenario for scenario in records}
|
||||
|
||||
def filtered_for_export(
|
||||
self,
|
||||
filters: ScenarioExportFilters | None = None,
|
||||
*,
|
||||
include_project: bool = True,
|
||||
) -> Sequence[Scenario]:
|
||||
stmt = select(Scenario)
|
||||
if include_project:
|
||||
stmt = stmt.options(joinedload(Scenario.project))
|
||||
|
||||
if filters:
|
||||
scenario_ids = filters.normalised_ids()
|
||||
if scenario_ids:
|
||||
stmt = stmt.where(Scenario.id.in_(scenario_ids))
|
||||
|
||||
project_ids = filters.normalised_project_ids()
|
||||
if project_ids:
|
||||
stmt = stmt.where(Scenario.project_id.in_(project_ids))
|
||||
|
||||
project_names = filters.normalised_project_names()
|
||||
if project_names:
|
||||
project_id_select = select(Project.id).where(
|
||||
func.lower(Project.name).in_(project_names)
|
||||
)
|
||||
stmt = stmt.where(Scenario.project_id.in_(project_id_select))
|
||||
|
||||
name_pattern = filters.name_search_pattern()
|
||||
if name_pattern:
|
||||
stmt = stmt.where(Scenario.name.ilike(name_pattern))
|
||||
|
||||
if filters.statuses:
|
||||
stmt = stmt.where(Scenario.status.in_(filters.statuses))
|
||||
|
||||
if filters.start_date_from:
|
||||
stmt = stmt.where(Scenario.start_date >=
|
||||
filters.start_date_from)
|
||||
|
||||
if filters.start_date_to:
|
||||
stmt = stmt.where(Scenario.start_date <= filters.start_date_to)
|
||||
|
||||
if filters.end_date_from:
|
||||
stmt = stmt.where(Scenario.end_date >= filters.end_date_from)
|
||||
|
||||
if filters.end_date_to:
|
||||
stmt = stmt.where(Scenario.end_date <= filters.end_date_to)
|
||||
|
||||
if filters.created_from:
|
||||
stmt = stmt.where(Scenario.created_at >= filters.created_from)
|
||||
|
||||
if filters.created_to:
|
||||
stmt = stmt.where(Scenario.created_at <= filters.created_to)
|
||||
|
||||
if filters.updated_from:
|
||||
stmt = stmt.where(Scenario.updated_at >= filters.updated_from)
|
||||
|
||||
if filters.updated_to:
|
||||
stmt = stmt.where(Scenario.updated_at <= filters.updated_to)
|
||||
|
||||
currencies = filters.normalised_currencies()
|
||||
if currencies:
|
||||
stmt = stmt.where(func.upper(
|
||||
Scenario.currency).in_(currencies))
|
||||
|
||||
if filters.primary_resources:
|
||||
stmt = stmt.where(Scenario.primary_resource.in_(
|
||||
filters.primary_resources))
|
||||
|
||||
stmt = stmt.order_by(Scenario.name, Scenario.id)
|
||||
return self.session.execute(stmt).scalars().all()
|
||||
|
||||
def delete(self, scenario_id: int) -> None:
|
||||
scenario = self.get(scenario_id)
|
||||
self.session.delete(scenario)
|
||||
|
||||
Reference in New Issue
Block a user