from typing import List, Optional from models.user_project import UserProjectRoles from projects.models import ( ProjectCalendarItemModel, ProjectExportItemModel, ProjectListItemResultModel, RecentProjectListItemResultModel, UpcomingProjectListItemResultModel, ) from shared.query_builders.projects_query_builder import ProjectsQueryBuilder from shared.query_builders.recent_projects_query_builder import RecentProjectsQueryBuilder from projects.schemas import ProjectListQueryParams from constants.project_statuses import ProjectStatuses DASHBOARD_PROJECTS_LIMIT = 5 MIN_RECENT_PROJECTS_COUNT = 3 class ProjectsListRepository: def __cover_info_from_approver_only(self, data, user_roles: list): if user_roles == [UserProjectRoles.APPROVER.value]: return None return data def get_projects_list( self, user_id: int, params: ProjectListQueryParams, artist_external_id: Optional[str] = None ) -> List[ProjectListItemResultModel]: builder = ProjectsQueryBuilder(user_id) self.__apply_filters(builder, params, artist_external_id) fetched_projects = builder.items_query().all() return [ ProjectListItemResultModel( id=c.Project.id, name=c.Project.name, targets=c.Project.not_deleted_items(), budget=self.__cover_info_from_approver_only(c.Project.budget or 0, c.user_roles), allocation=self.__cover_info_from_approver_only(c.Project.allocation or 0, c.user_roles), title=c.Project.prs_title or c.Project.ccp_title, total_spend=c.total_spend, start_date=c.start_date, end_date=c.Project.end_date, status=c.status, shared_status=c.shared_status, user_roles=c.user_roles, isConfidential=c.Project.is_confidential, currency=c.Project.currency, isClaimed=c.Project.is_claimed, ) for c in fetched_projects ] def get_calendar_projects_list( self, user_id: int, params: ProjectListQueryParams ) -> List[ProjectCalendarItemModel]: builder = ProjectsQueryBuilder(user_id) self.__apply_filters(builder, params) fetched_projects = builder.items_query().all() return [ ProjectCalendarItemModel( id=c.Project.id, name=c.Project.name, targets=c.Project.not_deleted_items(), earliest_start_date=c.start_date, latest_end_date=c.Project.end_date, campaigns_count=c.campaigns_count, shared_status=c.shared_status, userRoles=c.user_roles, ) for c in fetched_projects ] def get_export_projects_list( self, user_id: int, params: ProjectListQueryParams, artist_external_id: Optional[str] = None ) -> List[ProjectExportItemModel]: builder = ProjectsQueryBuilder(user_id) self.__apply_filters(builder, params, artist_external_id) fetched_projects = builder.items_query().all() return [ ProjectExportItemModel( name=c.Project.name, targets=c.Project.not_deleted_items(), planned_budget=c.Project.budget, earliest_start_date=c.start_date, latest_end_date=c.Project.end_date, total_spend=c.total_spend, status=c.status, ) for c in fetched_projects ] def get_recent_projects(self, user_id: int) -> List[RecentProjectListItemResultModel]: builder = ( RecentProjectsQueryBuilder(user_id) .only_claimed() .only_mine() .only_with_my_changes() .limit_to(DASHBOARD_PROJECTS_LIMIT) ) results = builder.items_query().all() if len(results) >= MIN_RECENT_PROJECTS_COUNT: return [ RecentProjectListItemResultModel( id=c.Project.id, name=c.Project.name, targets=c.Project.not_deleted_items(), budget=self.__cover_info_from_approver_only(c.Project.budget or 0, c.user_roles), allocation=self.__cover_info_from_approver_only(c.Project.allocation or 0, c.user_roles), title=c.Project.prs_title or c.Project.ccp_title, total_spend=c.total_spend, start_date=c.start_date, end_date=c.Project.end_date, status=c.status, shared_status=c.shared_status, user_roles=c.user_roles, campaigns_count=c.campaigns_count, isConfidential=c.Project.is_confidential, currency=c.Project.currency, isClaimed=c.Project.is_claimed, ) for c in results ] return [] def get_upcoming_projects(self, user_id: int) -> List[UpcomingProjectListItemResultModel]: builder = ( RecentProjectsQueryBuilder(user_id) .only_accessible_projects() .only_claimed() .filter_by_status(ProjectStatuses.SCHEDULED.value) ) upcoming_projects = builder.items_query().all() return [ UpcomingProjectListItemResultModel( id=item.Project.id, name=item.Project.name, targets=item.Project.not_deleted_items(), user_roles=item.user_roles, budget=item.Project.budget, allocation=item.Project.allocation, start_date=item.start_date, isConfidential=item.Project.is_confidential, currency=item.Project.currency, ) for item in upcoming_projects ] def __apply_filters( self, builder: ProjectsQueryBuilder, params: ProjectListQueryParams, artist_external_id: Optional[str] = None ): if params.freeText is not None: builder.filtered_by_search(params.freeText) if params.type is not None: builder.filtered_by_type(params.type) if params.statuses is not None: builder.filter_by_statuses(params.statuses) if params.earliestStartDate is not None and params.latestEndDate is not None: builder.filtered_by_date_range(params.earliestStartDate, params.latestEndDate) if params.labels: builder.filtered_by_labels(params.labels) if artist_external_id: builder.filtered_by_artist(artist_external_id) if params.onlyMine: builder.only_mine() if params.isClaimed is False: builder.only_unclaimed() else: builder.only_claimed() ( builder.only_accessible_projects() .offset_by(params.offset) .limit_to(params.limit) .sort_by(params.sort) )