From 4ae6a37380d039880a8340d849573dcf59c7afb7 Mon Sep 17 00:00:00 2001 From: marthevienne <123016211+marthevienne@users.noreply.github.com> Date: Fri, 13 Dec 2024 16:43:26 +0100 Subject: [PATCH] feat #309 migrer endpoint /metrics/activity-in-mpas --- backend/bloom/domain/metrics.py | 5 +++ backend/bloom/routers/v1/metrics.py | 20 ++++++++++ backend/bloom/services/metrics.py | 62 ++++++++++++++++++++++++----- 3 files changed, 76 insertions(+), 11 deletions(-) diff --git a/backend/bloom/domain/metrics.py b/backend/bloom/domain/metrics.py index d59af644..133c5d75 100644 --- a/backend/bloom/domain/metrics.py +++ b/backend/bloom/domain/metrics.py @@ -39,6 +39,11 @@ class ResponseMetricsVesselInActivitySchema(BaseModel): vessel: VesselListView total_time_at_sea: Optional[timedelta] +class ResponseMetricsVesselInMpasSchema(BaseModel): + model_config = ConfigDict(from_attributes=True) + vessel: VesselListView + total_time_in_mpas: Optional[timedelta] + class ResponseMetricsZoneVisitedSchema(BaseModel): zone: ZoneListView visiting_duration: timedelta diff --git a/backend/bloom/routers/v1/metrics.py b/backend/bloom/routers/v1/metrics.py index 0f3e6cdf..1b5566bc 100644 --- a/backend/bloom/routers/v1/metrics.py +++ b/backend/bloom/routers/v1/metrics.py @@ -123,3 +123,23 @@ async def read_metrics_all_vessels_visiting_time_by_zone(request: Request, category=category, sub_category=sub_category) return jsonable_encoder(payload) + + +@router.get("/metrics/vessels/activity-in-mpas") +# @cache +async def read_metrics_all_vessels_visiting_time_in_mpas( + request: Request, + datetime_range: DatetimeRangeRequest = Depends(), + pagination: PageParams = Depends(), + order: OrderByRequest = Depends(), + key: str = Depends(X_API_KEY_HEADER), +): + check_apikey(key) + use_cases = UseCases() + MetricsService = use_cases.metrics_service() + payload = MetricsService.get_vessels_in_mpas( + datetime_range=datetime_range, + pagination=pagination, + order=order + ) + return jsonable_encoder(payload) diff --git a/backend/bloom/services/metrics.py b/backend/bloom/services/metrics.py index c9a08ef1..6279d94c 100644 --- a/backend/bloom/services/metrics.py +++ b/backend/bloom/services/metrics.py @@ -18,6 +18,7 @@ from bloom.domain.metrics import (ResponseMetricsVesselInActivitySchema, ResponseMetricsZoneVisitedSchema, + ResponseMetricsVesselInMpasSchema, ResponseMetricsZoneVisitingTimeByVesselSchema, ResponseMetricsVesselTotalTimeActivityByActivityTypeSchema, ResponseMetricsVesselVisitingTimeByZoneSchema) @@ -72,7 +73,50 @@ def getVesselsInActivity(self, total_time_at_sea=item[1] )\ for item in payload] - + + def get_vessels_in_mpas(self, + datetime_range: DatetimeRangeRequest, + pagination: PageParams, + order: OrderByRequest): + payload=[] + with self.session_factory() as session: + stmt = ( + select( + sql_model.Vessel, + func.sum(sql_model.Metrics.duration_total).label( + "total_time_in_mpas" + ), + ) + .select_from(sql_model.Metrics) + .join( + sql_model.Vessel, + sql_model.Vessel.id == sql_model.Metrics.vessel_id, + ) + .where( + sql_model.Metrics.timestamp.between( + datetime_range.start_at, datetime_range.end_at + ) + ) + .where(sql_model.Metrics.zone_category == "amp") + .group_by(sql_model.Vessel) + ) + stmt = stmt.offset(pagination.offset) if pagination.offset != None else stmt + stmt = ( + stmt.order_by(asc("total_time_in_mpas")) + if order.order == OrderByEnum.ascending + else stmt.order_by(desc("total_time_in_mpas")) + ) + stmt = stmt.limit(pagination.limit) if pagination.limit != None else stmt + payload=session.execute(stmt).all() + + return [ + ResponseMetricsVesselInMpasSchema( + vessel=VesselRepository.map_to_domain(item[0]).model_dump(), + total_time_in_mpas=item[1], + ) + for item in payload + ] + def getVesselsAtSea(self, datetime_range: DatetimeRangeRequest, ): @@ -95,7 +139,6 @@ def getVesselsAtSea(self, ) return session.execute(stmt).scalar() - def getZoneVisited(self, datetime_range: DatetimeRangeRequest, pagination: PageParams, @@ -137,7 +180,7 @@ def getZoneVisited(self, visiting_duration=item[1] )\ for item in payload] - + def getZoneVisitingTimeByVessel(self, zone_id: int, datetime_range: DatetimeRangeRequest, @@ -145,7 +188,7 @@ def getZoneVisitingTimeByVessel(self, pagination: PageParams,): payload=[] with self.session_factory() as session: - + stmt=select( sql_model.Zone, sql_model.Vessel, @@ -166,7 +209,7 @@ def getZoneVisitingTimeByVessel(self, ) )\ .group_by(sql_model.Zone.id,sql_model.Vessel.id) - + stmt = stmt.order_by(func.sum(sql_model.Segment.segment_duration).asc())\ if order.order == OrderByEnum.ascending \ else stmt.order_by(func.sum(sql_model.Segment.segment_duration).desc()) @@ -185,7 +228,7 @@ def getZoneVisitingTimeByVessel(self, zone_visiting_time_by_vessel=item[2] )\ for item in payload] - + def getVesselVisitingTimeByZone(self, order: OrderByRequest, datetime_range: DatetimeRangeRequest, @@ -226,14 +269,12 @@ def getVesselVisitingTimeByZone(self, stmt = stmt.limit(pagination.limit) if pagination.limit != None else stmt if vessel_id is not None: stmt=stmt.where(sql_model.Vessel.id==vessel_id) - - + return [ResponseMetricsVesselVisitingTimeByZoneSchema( vessel=VesselListView(**VesselRepository.map_to_domain(model[0]).model_dump()), zone=ZoneListView(**ZoneRepository.map_to_domain(model[1]).model_dump()), vessel_visiting_time_by_zone=model[2]) for model in session.execute(stmt).all()] - def getVesselVisitsByActivityType(self, vessel_id: int, activity_type: TotalTimeActivityTypeRequest, @@ -261,10 +302,9 @@ def getVesselVisitsByActivityType(self, literal_column('0 seconds'), )) payload=session.execute(stmt.limit(1)).scalar_one_or_none() - + return [ ResponseMetricsVesselTotalTimeActivityByActivityTypeSchema( vessel_id=item.id, activity=item.activity, total_activity_time=item.total_activity_time, ) for item in payload] - \ No newline at end of file