# Class GroupedObservationService

Namespace
  adas_core.Application.Services

Assembly
  adas-core.Application.dll

Provides a concrete implementation of IGroupedObservationService for managing and exposing grouped observation data.

    public class GroupedObservationService : IGroupedObservationService

Inheritance
  object
  GroupedObservationService

Implements
  IGroupedObservationService

Inherited Members
  object.Equals(object)
  object.Equals(object, object)
  object.GetHashCode()
  object.GetType()
  object.MemberwiseClone()
  object.ReferenceEquals(object, object)
  object.ToString()

Extension Methods
  NumberUtils.IsNumber(object)
  NumberUtils.ToDouble(object)
  ObjectUtils.ToStr(object?)

## Constructors

### GroupedObservationService(IObservationRepository, IConfigObservationService, ILogger<GroupedObservationService>, ICacheService, IOptions<ApiSettings>, IOptions<CacheSettings>)

    public GroupedObservationService(IObservationRepository observationRepository, IConfigObservationService configObservationService, ILogger<GroupedObservationService> logger, ICacheService cacheService, IOptions<ApiSettings> apiSettings, IOptions<CacheSettings> cacheSettings)

#### Parameters

`observationRepository` IObservationRepository
`configObservationService` IConfigObservationService
`logger` ILogger<GroupedObservationService>
`cacheService` ICacheService
`apiSettings` IOptions<ApiSettings>
`cacheSettings` IOptions<CacheSettings>

## Methods

### CalculateHalfHourObservations(List<BsonDocument>)

Calculates half-hour observations for the provided list of MongoDB.Bson.BsonDocument entries by grouping the "all" sub-document values into 30-minute time buckets and assigning the most recent sample of each bucket to a "halfhour" field on the corresponding document. Handles edge cases such as the last document in the list, absence of a next document, empty groups, a next document without readings (or with a single "0" value), and missing "halfhour" fields, falling back to an empty MongoDB.Bson.BsonDocument when no grouped values are available.

    public List<BsonDocument> CalculateHalfHourObservations(List<BsonDocument> result)

#### Parameters

`result` List<BsonDocument>

  The ordered list of MongoDB.Bson.BsonDocument instances whose "all" arrays will be grouped into half-hour intervals and enriched with a "halfhour" field in place.

#### Returns

List<BsonDocument>

  The same List<T> instance with the "halfhour" field populated according to the half-hour grouping rules.

### CalculateLastFilledObservations(List<BsonDocument>, GroupedField, ObjectId)

Calculates the last filled observations for a patient. When the grouped field contains multiple names, the calculation is performed for each name and the results are aggregated; otherwise, the calculation is performed once using the single grouped field name.

    public Task<List<BsonDocument>> CalculateLastFilledObservations(List<BsonDocument> result, GroupedField groupedField, ObjectId patientId)

#### Parameters

`result` List<BsonDocument>

  The collection of BsonDocument results to be processed.

`groupedField` GroupedField

  The grouped field containing either a list of names to iterate over or a single name used as fallback when the list is empty.

`patientId` ObjectId

  The identifier of the patient whose observations are being calculated.

#### Returns

Task<List<BsonDocument>>

  A task that returns a list of BsonDocument containing the calculated last filled observations.

### CalculateShiftObservations(List<BsonDocument>, GroupedField)

Calculates aggregated shift observations by grouping them by shift and day. When the grouped field result contains a Sum operation, the method sums the values within each group and propagates the `isFilled` flag, marking a group as not filled if any of its observations is not filled. If no Sum operation is present, the original observations are returned unchanged.

    public List<BsonDocument> CalculateShiftObservations(List<BsonDocument> shiftGroupObservations, GroupedField groupedField)

#### Parameters

`shiftGroupObservations` List<BsonDocument>

  The list of shift observations to be aggregated.

`groupedField` GroupedField

  The grouped field configuration whose Result property determines whether a Sum aggregation is applied.

#### Returns

List<BsonDocument>

  A list of MongoDB.Bson.BsonDocument containing the aggregated shift observations, or the original list when no Sum operation is required.

### CreateNextEmptyObs(WsSubscriberGrouped)

Builds the next batch of empty observations for a grouped subscriber, either by extending the cached observation list with newly inferred time slots or by falling back to a full recalculation when the cache is empty.

    public Task<GroupedObservation> CreateNextEmptyObs(WsSubscriberGrouped ws)

#### Parameters

`ws` WsSubscriberGrouped

  The grouped subscriber context that supplies the group, names, regularity, max window, and cache key used to derive the next observations.

#### Returns

Task<GroupedObservation>

  A GroupedObservation containing the resulting observations adjusted to the configured time window based on GroupedObservationEnum.Regularity (Minute, Second, or default hour-based).

### FillHours(List<BsonDocument>, GroupedField)

Fills missing time slots in a grouped observation result set by inserting zero-valued placeholder entries for each expected interval based on the configured regularity (day, hour, shift, minute, or second) and the maximum number of intervals. When the result already contains enough entries for every name, the original list is returned unchanged. Placeholders are marked with `isFilled` and the appropriate result-type fields (sum, average, count, half-hour, etc.) are initialized to zero, except for `LastFilled` and `LastAll` result types which are skipped, and the output is ordered by time before being returned.

    public List<BsonDocument> FillHours(List<BsonDocument> result, GroupedField groupedField)

#### Parameters

`result` List<BsonDocument>

  The existing grouped observation documents to be completed with missing intervals.

`groupedField` GroupedField

  The grouping configuration that defines the names, maximum number of intervals, regularity and result types to use when generating the placeholders.

#### Returns

List<BsonDocument>

  A list of MongoDB.Bson.BsonDocument entries ordered by time, containing the original data and any added zero-valued filler entries for missing intervals.

### FindLastObservations(ObjectId, int, List<string>?)

Retrieves the most recent observations for a specified patient, optionally filtered by observation types. Delegates the aggregation to the underlying observation repository and returns the resulting collection.

    public Task<List<PatientObservation>> FindLastObservations(ObjectId patientId, int num = 2, List<string>? filterObservations = null)

#### Parameters

`patientId` ObjectId

  The unique identifier of the patient whose observations are being queried.

`num` int

  The maximum number of recent observations to return. Defaults to 2.

`filterObservations` List<string>

  An optional list of observation identifiers used to restrict the result set. When null, no filtering is applied.

#### Returns

Task<List<PatientObservation>>

  A task that represents the asynchronous operation, containing a list of PatientObservation entries representing the patient's most recent observations.

### GenerateGroupedObservation(ObjectId, GroupedField, List<GroupedObservationObs>, PatientObservation, string)

Generates a grouped observation for a patient, using an incremental update from the cache when the result type allows it, and otherwise performing a full recalculation (for Average, HalfHour, and Sum results) or when no cached entry exists.

    public Task<GroupedObservation> GenerateGroupedObservation(ObjectId patientId, GroupedField groupedField, List<GroupedObservation.GroupedObservationObs> wsgLastGroupedObservationObs, PatientObservation obs, string timeZoneId = "Romance Standard Time")

#### Parameters

`patientId` ObjectId

  The identifier of the patient whose grouped observation is being generated.

`groupedField` GroupedField

  The grouped field configuration whose result type and name drive the recalculation strategy and cache key.

`wsgLastGroupedObservationObs` List<GroupedObservation.GroupedObservationObs>

  The last known grouped observations provided as context for the grouped observation.

`obs` PatientObservation

  The new patient observation to be incorporated into the grouped observation.

`timeZoneId` string

  The time zone identifier used when a full recalculation is required. Defaults to "Romance Standard Time".

#### Returns

Task<GroupedObservation>

  A task that resolves to the generated GroupedObservation for the patient, either from an incrementally updated cache entry or from a full recalculation.

### GenerateGroupedObservation(ObjectId, GroupedField, string, bool, CancellationToken)

Generates a complete set of grouped observations for a patient based on the provided grouping configuration, applying timezone conversion, shift/half-hour rules, and per-result computations (first, last, min, max, sum, average, count, last filled). Results are returned from cache when `cacheIsChecked` is `false`; otherwise the observations are recomputed and returned without touching the cache.

    public Task<GroupedObservation> GenerateGroupedObservation(ObjectId patientId, GroupedField groupedField, string timeZoneId = "Romance Standard Time", bool cacheIsChecked = false, CancellationToken ct = default)

#### Parameters

`patientId` ObjectId

  The unique identifier of the patient whose observations are being aggregated.

`groupedField` GroupedField

  The grouping field definition that drives the aggregation, regularity, shift times, and which result types (first, last, min, max, etc.) are computed.

`timeZoneId` string

  The system time zone id used to convert observation times from UTC. Defaults to "Romance Standard Time".

`cacheIsChecked` bool

  When `true`, the cache is bypassed and observations are always recomputed; when `false`, results are obtained through the cache with the configured TTL.

`ct` CancellationToken

  Token used to cancel the asynchronous operation.

#### Returns

Task<GroupedObservation>

  A Task<TResult> containing the patient id, group, name, and the list of computed GroupedObservation.GroupedObservationObs entries.

### GenerateShiftObservations(List<BsonDocument>, GroupedField)

Enriches each BsonDocument in the result with a shift identifier and the corresponding day, by matching the document's observation time against the configured shift start times. Falls back to the previous day and the last shift when no matching shift is found, and skips documents with missing or invalid date components or an empty shift configuration.

    public List<BsonDocument> GenerateShiftObservations(List<BsonDocument> result, GroupedField groupedField)

#### Parameters

`result` List<BsonDocument>

  The list of aggregated BsonDocuments to enrich; each document is modified in place to include the day and shift elements.

`groupedField` GroupedField

  The grouping configuration providing the ordered list of shift start times used to determine the assigned shift.

#### Returns

List<BsonDocument>

  The same `result` list with day and shift elements added to each successfully processed document.