From ffbd9be20a5625acd64f3f37f2520012cb654f88 Mon Sep 17 00:00:00 2001 From: jannisvisser Date: Mon, 25 Sep 2023 11:19:32 +0200 Subject: [PATCH] fix: move code to new service AB#23762 --- .../admin-area-dynamic-data.module.ts | 2 + .../admin-area-dynamic-data.service.ts | 46 +---- .../src/api/admin-area/admin-area.module.ts | 5 +- .../src/api/admin-area/admin-area.service.ts | 97 +---------- .../admin-area/services/event-area.service.ts | 161 ++++++++++++++++++ 5 files changed, 173 insertions(+), 138 deletions(-) create mode 100644 services/API-service/src/api/admin-area/services/event-area.service.ts diff --git a/services/API-service/src/api/admin-area-dynamic-data/admin-area-dynamic-data.module.ts b/services/API-service/src/api/admin-area-dynamic-data/admin-area-dynamic-data.module.ts index 762b56c4f..f7b529db9 100644 --- a/services/API-service/src/api/admin-area-dynamic-data/admin-area-dynamic-data.module.ts +++ b/services/API-service/src/api/admin-area-dynamic-data/admin-area-dynamic-data.module.ts @@ -10,6 +10,7 @@ import { EventModule } from '../event/event.module'; import { DisasterEntity } from '../disaster/disaster.entity'; import { CountryEntity } from '../country/country.entity'; import { HelperService } from '../../shared/helper.service'; +import { AdminAreaModule } from '../admin-area/admin-area.module'; @Module({ imports: [ @@ -22,6 +23,7 @@ import { HelperService } from '../../shared/helper.service'; UserModule, EventModule, CountryModule, + AdminAreaModule, ], providers: [AdminAreaDynamicDataService, HelperService], controllers: [AdminAreaDynamicDataController], diff --git a/services/API-service/src/api/admin-area-dynamic-data/admin-area-dynamic-data.service.ts b/services/API-service/src/api/admin-area-dynamic-data/admin-area-dynamic-data.service.ts index 9a721d6ad..0ae58c8e8 100644 --- a/services/API-service/src/api/admin-area-dynamic-data/admin-area-dynamic-data.service.ts +++ b/services/API-service/src/api/admin-area-dynamic-data/admin-area-dynamic-data.service.ts @@ -14,8 +14,7 @@ import { DisasterType } from '../disaster/disaster-type.enum'; import fs from 'fs'; import { CountryEntity } from '../country/country.entity'; import { HelperService } from '../../shared/helper.service'; -import { DateDto } from '../event/dto/date.dto'; -import { IndicatorDto } from '../metadata/dto/add-indicators.dto'; +import { EventAreaService } from '../admin-area/services/event-area.service'; @Injectable() export class AdminAreaDynamicDataService { @@ -28,6 +27,7 @@ export class AdminAreaDynamicDataService { public constructor( private eventService: EventService, + private eventAreaService: EventAreaService, private helperService: HelperService, private dataSource: DataSource, ) {} @@ -156,46 +156,6 @@ export class AdminAreaDynamicDataService { return false; } - private async getEventAreaAggregates( - countryCodeISO3: string, - disasterType: DisasterType, - indicator: DynamicIndicator, - lastTriggeredDate: DateDto, - ): Promise { - const events = await this.eventService.getEventSummary( - countryCodeISO3, - disasterType, - ); - - const records = []; - for await (const event of events.filter((e) => e.activeTrigger)) { - const aggregateValue = await this.adminAreaDynamicDataRepo - .createQueryBuilder('dynamic') - .select( - `CASE WHEN dynamic."indicator" = 'alert_threshold' THEN MAX(value) ELSE SUM(value) END as "value"`, - ) - .where({ - timestamp: MoreThanOrEqual( - this.helperService.getUploadCutoffMoment( - disasterType, - lastTriggeredDate.timestamp, - ), - ), - disasterType: disasterType, - indicator: indicator, - eventName: event.eventName, - }) - .groupBy('dynamic."indicator"') - .getRawOne(); - - const record = new AdminDataReturnDto(); - record.placeCode = event.eventName; - record.value = aggregateValue.value; - records.push(record); - } - return records; - } - public async getAdminAreaDynamicData( countryCodeISO3: string, adminLevel: string, @@ -210,7 +170,7 @@ export class AdminAreaDynamicDataService { ); if (disasterType === DisasterType.FlashFloods && !eventName) { - return await this.getEventAreaAggregates( + return await this.eventAreaService.getEventAreaDynamicData( countryCodeISO3, disasterType, indicator, diff --git a/services/API-service/src/api/admin-area/admin-area.module.ts b/services/API-service/src/api/admin-area/admin-area.module.ts index e4ec25aa0..af3766dde 100644 --- a/services/API-service/src/api/admin-area/admin-area.module.ts +++ b/services/API-service/src/api/admin-area/admin-area.module.ts @@ -11,6 +11,7 @@ import { AdminAreaService } from './admin-area.service'; import { DisasterEntity } from '../disaster/disaster.entity'; import { AdminAreaDynamicDataEntity } from '../admin-area-dynamic-data/admin-area-dynamic-data.entity'; import { HttpModule } from '@nestjs/axios'; +import { EventAreaService } from './services/event-area.service'; @Module({ imports: [ @@ -25,8 +26,8 @@ import { HttpModule } from '@nestjs/axios'; EventModule, CountryModule, ], - providers: [AdminAreaService, HelperService], + providers: [AdminAreaService, EventAreaService, HelperService], controllers: [AdminAreaController], - exports: [AdminAreaService], + exports: [AdminAreaService, EventAreaService], }) export class AdminAreaModule {} diff --git a/services/API-service/src/api/admin-area/admin-area.service.ts b/services/API-service/src/api/admin-area/admin-area.service.ts index a544568be..4bde6cb7c 100644 --- a/services/API-service/src/api/admin-area/admin-area.service.ts +++ b/services/API-service/src/api/admin-area/admin-area.service.ts @@ -12,8 +12,7 @@ import { DisasterType } from '../disaster/disaster-type.enum'; import { DisasterEntity } from '../disaster/disaster.entity'; import { DynamicIndicator } from '../admin-area-dynamic-data/enum/dynamic-data-unit'; import { LeadTime } from '../admin-area-dynamic-data/enum/lead-time.enum'; -import { CountryService } from '../country/country.service'; -import { DateDto } from '../event/dto/date.dto'; +import { EventAreaService } from './services/event-area.service'; @Injectable() export class AdminAreaService { @@ -27,7 +26,7 @@ export class AdminAreaService { public constructor( private helperService: HelperService, private eventService: EventService, - private countryService: CountryService, + private eventAreaService: EventAreaService, ) {} public async addOrUpdateAdminAreas( @@ -197,7 +196,7 @@ export class AdminAreaService { disasterType, ); if (disasterType === DisasterType.FlashFloods && !eventName) { - return await this.getEventAreaAggregates( + return await this.eventAreaService.getEventAreaAggregates( countryCodeISO3, disasterType, lastTriggeredDate, @@ -291,94 +290,6 @@ export class AdminAreaService { }); } - private async getEventAreaAggregates( - countryCodeISO3: string, - disasterType: DisasterType, - lastTriggeredDate: DateDto, - ): Promise { - const events = await this.eventService.getEventSummary( - countryCodeISO3, - disasterType, - ); - - const aggregateRecords = []; - for await (const event of events.filter((e) => e.activeTrigger)) { - const aggregateValues = await this.adminAreaDynamicDataRepo - .createQueryBuilder('dynamic') - .select('dynamic."indicator"', 'indicator') - .addSelect( - `CASE WHEN dynamic."indicator" = 'alert_threshold' THEN MAX(value) ELSE SUM(value) END as "value"`, - ) - .where({ - timestamp: MoreThanOrEqual( - this.helperService.getUploadCutoffMoment( - disasterType, - lastTriggeredDate.timestamp, - ), - ), - disasterType: disasterType, - eventName: event.eventName, - }) - .groupBy('dynamic."indicator"') - .getRawMany(); - - for (const indicator of aggregateValues) { - const aggregateRecord = new AggregateDataRecord(); - aggregateRecord.placeCode = event.eventName; - aggregateRecord.indicator = indicator.indicator; - aggregateRecord.value = indicator.value; - aggregateRecords.push(aggregateRecord); - } - } - return aggregateRecords; - } - - private async getEventAreas( - countryCodeISO3: string, - disaster: DisasterEntity, - lastTriggeredDate: DateDto, - ): Promise { - const events = await this.eventService.getEventSummary( - countryCodeISO3, - disaster.disasterType, - ); - const country = await this.countryService.findOne(countryCodeISO3, [ - 'countryDisasterSettings', - ]); - const geoJson: GeoJson = { - type: 'FeatureCollection', - features: [], - }; - for await (const event of events.filter((e) => e.activeTrigger)) { - const eventArea = country.countryDisasterSettings.find( - (d) => d.disasterType === disaster.disasterType, - ).eventAreas[event.eventName]; - eventArea['properties'] = {}; - eventArea['properties']['eventName'] = event.eventName; - eventArea['properties']['placeCode'] = event.eventName; - - const aggregateValue = await this.adminAreaDynamicDataRepo - .createQueryBuilder('dynamic') - .select('SUM(value)', 'value') // TODO: facilitate other aggregate-cases than SUM - .where({ - timestamp: MoreThanOrEqual( - this.helperService.getUploadCutoffMoment( - disaster.disasterType, - lastTriggeredDate.timestamp, - ), - ), - disasterType: disaster.disasterType, - indicator: disaster.actionsUnit, - eventName: event.eventName, - }) - .getRawOne(); - - eventArea['properties'][disaster.actionsUnit] = aggregateValue.value; - geoJson.features.push(eventArea); - } - return geoJson; - } - public async getAdminAreas( countryCodeISO3: string, disasterType: DisasterType, @@ -393,7 +304,7 @@ export class AdminAreaService { ); if (disasterType === DisasterType.FlashFloods && !eventName) { - return await this.getEventAreas( + return await this.eventAreaService.getEventAreas( countryCodeISO3, disaster, lastTriggeredDate, diff --git a/services/API-service/src/api/admin-area/services/event-area.service.ts b/services/API-service/src/api/admin-area/services/event-area.service.ts new file mode 100644 index 000000000..630269f33 --- /dev/null +++ b/services/API-service/src/api/admin-area/services/event-area.service.ts @@ -0,0 +1,161 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Repository, MoreThanOrEqual } from 'typeorm'; +import { + AggregateDataRecord, + EventSummaryCountry, +} from '../../../shared/data.model'; +import { GeoJson } from '../../../shared/geo.model'; +import { HelperService } from '../../../shared/helper.service'; +import { AdminAreaDynamicDataEntity } from '../../admin-area-dynamic-data/admin-area-dynamic-data.entity'; +import { AdminDataReturnDto } from '../../admin-area-dynamic-data/dto/admin-data-return.dto'; +import { DynamicIndicator } from '../../admin-area-dynamic-data/enum/dynamic-data-unit'; +import { CountryService } from '../../country/country.service'; +import { DisasterType } from '../../disaster/disaster-type.enum'; +import { DisasterEntity } from '../../disaster/disaster.entity'; +import { DateDto } from '../../event/dto/date.dto'; +import { EventService } from '../../event/event.service'; + +@Injectable() +export class EventAreaService { + @InjectRepository(AdminAreaDynamicDataEntity) + private readonly adminAreaDynamicDataRepo: Repository; + + public constructor( + private helperService: HelperService, + private eventService: EventService, + private countryService: CountryService, + ) {} + + public async getEventAreas( + countryCodeISO3: string, + disaster: DisasterEntity, + lastTriggeredDate: DateDto, + ): Promise { + const events = await this.eventService.getEventSummary( + countryCodeISO3, + disaster.disasterType, + ); + const country = await this.countryService.findOne(countryCodeISO3, [ + 'countryDisasterSettings', + ]); + const geoJson: GeoJson = { + type: 'FeatureCollection', + features: [], + }; + for await (const event of events.filter((e) => e.activeTrigger)) { + const eventArea = country.countryDisasterSettings.find( + (d) => d.disasterType === disaster.disasterType, + ).eventAreas[event.eventName]; + eventArea['properties'] = {}; + eventArea['properties']['eventName'] = event.eventName; + eventArea['properties']['placeCode'] = event.eventName; + + const aggregateValue = await this.adminAreaDynamicDataRepo + .createQueryBuilder('dynamic') + .select('SUM(value)', 'value') // TODO: facilitate other aggregate-cases than SUM + .where({ + timestamp: MoreThanOrEqual( + this.helperService.getUploadCutoffMoment( + disaster.disasterType, + lastTriggeredDate.timestamp, + ), + ), + disasterType: disaster.disasterType, + indicator: disaster.actionsUnit, + eventName: event.eventName, + }) + .getRawOne(); + + eventArea['properties'][disaster.actionsUnit] = aggregateValue.value; + geoJson.features.push(eventArea); + } + return geoJson; + } + + public async getEventAreaAggregates( + countryCodeISO3: string, + disasterType: DisasterType, + lastTriggeredDate: DateDto, + ): Promise { + const events = await this.eventService.getEventSummary( + countryCodeISO3, + disasterType, + ); + + const aggregateRecords = []; + for await (const event of events.filter((e) => e.activeTrigger)) { + const aggregateValues = await this.getEventAreaAggregatesPerIndicator( + disasterType, + lastTriggeredDate, + event, + ); + + for (const indicator of aggregateValues) { + const aggregateRecord = new AggregateDataRecord(); + aggregateRecord.placeCode = event.eventName; + aggregateRecord.indicator = indicator.indicator; + aggregateRecord.value = indicator.value; + aggregateRecords.push(aggregateRecord); + } + } + return aggregateRecords; + } + public async getEventAreaDynamicData( + countryCodeISO3: string, + disasterType: DisasterType, + indicator: DynamicIndicator, + lastTriggeredDate: DateDto, + ): Promise { + const events = await this.eventService.getEventSummary( + countryCodeISO3, + disasterType, + ); + + const records = []; + for await (const event of events.filter((e) => e.activeTrigger)) { + const aggregateValues = await this.getEventAreaAggregatesPerIndicator( + disasterType, + lastTriggeredDate, + event, + indicator, + ); + + const record = new AdminDataReturnDto(); + record.placeCode = event.eventName; + record.value = aggregateValues[0].value; + records.push(record); + } + return records; + } + + private async getEventAreaAggregatesPerIndicator( + disasterType: DisasterType, + lastTriggeredDate: DateDto, + event: EventSummaryCountry, + indicator?: DynamicIndicator, + ): Promise<{ indicator: string; value: number }[]> { + const whereFilters = { + timestamp: MoreThanOrEqual( + this.helperService.getUploadCutoffMoment( + disasterType, + lastTriggeredDate.timestamp, + ), + ), + disasterType: disasterType, + eventName: event.eventName, + }; + if (indicator) { + whereFilters['indicator'] = indicator; + } + return await this.adminAreaDynamicDataRepo + .createQueryBuilder('dynamic') + .select('dynamic."indicator"', 'indicator') + .addSelect( + `CASE WHEN dynamic."indicator" = 'alert_threshold' THEN MAX(value) ELSE SUM(value) END as "value"`, + ) + .where(whereFilters) + .groupBy('dynamic."indicator"') + .getRawMany(); + } +}