Skip to content

Commit

Permalink
Add map filtering for Business Units
Browse files Browse the repository at this point in the history
  • Loading branch information
alexeh committed Dec 7, 2023
1 parent e906560 commit 8387b6c
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 17 deletions.
6 changes: 6 additions & 0 deletions api/src/modules/h3-data/dto/get-impact-map.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ class BaseGetImpactMapDto {
@Type(() => String)
producerIds?: string[];

@ApiPropertyOptional({ name: 'businessUnitIds[]' })
@IsOptional()
@IsUUID('4', { each: true })
@Type(() => String)
businessUnitIds?: string[];

@ApiPropertyOptional({
description: 'Types of Sourcing Locations, written with hyphens',
enum: Object.values(LOCATION_TYPES),
Expand Down
29 changes: 20 additions & 9 deletions api/src/modules/h3-data/h3-data-map.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import { MaterialsToH3sService } from 'modules/materials/materials-to-h3s.servic
import { MATERIAL_TO_H3_TYPE } from 'modules/materials/material-to-h3.entity';
import { Material } from 'modules/materials/material.entity';
import { AdminRegionsService } from 'modules/admin-regions/admin-regions.service';
import { SuppliersService } from 'modules/suppliers/suppliers.service';
import { H3DataRepository } from 'modules/h3-data/h3-data.repository';
import { Unit } from 'modules/units/unit.entity';
import { BusinessUnitsService } from 'modules/business-units/business-units.service';

/**
* @debt: Check if we actually need extending nestjs-base-service over this module.
Expand All @@ -43,7 +43,7 @@ export class H3DataMapService {
protected readonly materialService: MaterialsService,
protected readonly materialToH3Service: MaterialsToH3sService,
protected readonly adminRegionService: AdminRegionsService,
protected readonly supplierService: SuppliersService,
protected readonly businessUnitsService: BusinessUnitsService,
private readonly indicatorService: IndicatorsService,
private readonly h3DataYearsService: H3DataYearsService,
) {}
Expand Down Expand Up @@ -116,25 +116,22 @@ export class H3DataMapService {
quantiles: number[];
};

let isRelative: boolean = false;
//Get the corresponding map data depending on the incoming DTO
if (getImpactMapDto instanceof GetScenarioVsScenarioImpactMapDto) {
impactMap = await this.h3DataRepository.getScenarioVsScenarioImpactMap(
getImpactMapDto,
);
isRelative = this.isRequestedComparisonRelative(getImpactMapDto);
} else if (getImpactMapDto instanceof GetActualVsScenarioImpactMapDto) {
impactMap = await this.h3DataRepository.getActualVsScenarioImpactMap(
getImpactMapDto,
);
isRelative = this.isRequestedComparisonRelative(getImpactMapDto);
} else {
impactMap = await this.h3DataRepository.getImpactMap(getImpactMapDto);
}

/**
* Check if requested map's should show a relative magnitude
*/
const isRelative: boolean =
this.requestedComparisonIsRelative(getImpactMapDto);

return this.constructH3MapResponse(
impactMap.impactMap,
impactMap.quantiles,
Expand Down Expand Up @@ -175,6 +172,13 @@ export class H3DataMapService {
mapDto.materialIds,
);
}

if (mapDto.businessUnitIds) {
mapDto.businessUnitIds =
await this.businessUnitsService.getBusinessUnitsDescendants(
mapDto.businessUnitIds,
);
}
return mapDto;
}

Expand Down Expand Up @@ -241,7 +245,14 @@ export class H3DataMapService {
};
}

private requestedComparisonIsRelative(getImpactDto: any): boolean {
/**
* Check if requested map's should show a relative magnitude
*/
private isRequestedComparisonRelative(
getImpactDto:
| GetScenarioVsScenarioImpactMapDto
| GetActualVsScenarioImpactMapDto,
): boolean {
return getImpactDto.relative ?? false;
}
}
36 changes: 28 additions & 8 deletions api/test/e2e/h3-data/h3-impact-map.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ describe('H3 Data Module (e2e) - Impact map', () => {
});

describe('Optional query parameters', () => {
test('When I get a calculated H3 Water Impact Map with the necessary input values and materials filter, then I should get the correct h3 data', async () => {
test('When I get a calculated H3 Impact Map with the necessary input values and materials filter, then I should get the correct h3 data', async () => {
const response = await request(testApplication.getHttpServer())
.get(`/api/v1/h3/map/impact`)
.set('Authorization', `Bearer ${jwtToken}`)
Expand Down Expand Up @@ -234,7 +234,7 @@ describe('H3 Data Module (e2e) - Impact map', () => {
});
});

test('When I get a calculated H3 Water Impact Map with the necessary input values and origins filter, then I should get the correct h3 data', async () => {
test('When I get a calculated H3 Impact Map with the necessary input values and origins filter, then I should get the correct h3 data', async () => {
const response = await request(testApplication.getHttpServer())
.get(`/api/v1/h3/map/impact`)
.set('Authorization', `Bearer ${jwtToken}`)
Expand All @@ -257,7 +257,7 @@ describe('H3 Data Module (e2e) - Impact map', () => {
});
});

test('When I get a calculated H3 Water Impact Map with the necessary input values and supplier (t1Supplier) filter, then I should get the correct h3 data', async () => {
test('When I get a calculated H3 Impact Map with the necessary input values and supplier (t1Supplier) filter, then I should get the correct h3 data', async () => {
const response = await request(testApplication.getHttpServer())
.get(`/api/v1/h3/map/impact`)
.set('Authorization', `Bearer ${jwtToken}`)
Expand All @@ -280,7 +280,7 @@ describe('H3 Data Module (e2e) - Impact map', () => {
});
});

test('When I get a calculated H3 Water Impact Map with the necessary input values and supplier (producer) filter, then I should get the correct h3 data', async () => {
test('When I get a calculated H3 Impact Map with the necessary input values and supplier (producer) filter, then I should get the correct h3 data', async () => {
const response = await request(testApplication.getHttpServer())
.get(`/api/v1/h3/map/impact`)
.set('Authorization', `Bearer ${jwtToken}`)
Expand Down Expand Up @@ -308,8 +308,28 @@ describe('H3 Data Module (e2e) - Impact map', () => {
unit: 'tonnes',
});
});

test('When I get a calculated H3 Water Impact Map with the necessary input values and supplier (producer) filter, then I should get the correct h3 data', async () => {
test('When I get a calculated H3 Impact Map with the necessary input values and Business Units filter, then I should get the correct h3 data', async () => {
const response = await request(testApplication.getHttpServer())
.get(`/api/v1/h3/map/impact`)
.set('Authorization', `Bearer ${jwtToken}`)
.query({
indicatorId: impactMapMockData.indicatorId,
'businessUnitIds[]': [
impactMapMockData.businessUnitOneId,
impactMapMockData.businessUnitTwoId,
],
year: 2020,
resolution: 6,
});
expect(response.body.data).toEqual(
expect.arrayContaining([
{ h: '861203a6fffffff', v: '500.0000' },
{ h: '861203a5fffffff', v: '617.0000' },
{ h: '861203a4fffffff', v: '1117.0000' },
]),
);
});
test('When I get a calculated H3 Impact Map with the necessary input values and supplier (producer) filter, then I should get the correct h3 data', async () => {
const response = await request(testApplication.getHttpServer())
.get(`/api/v1/h3/map/impact`)
.set('Authorization', `Bearer ${jwtToken}`)
Expand All @@ -332,7 +352,7 @@ describe('H3 Data Module (e2e) - Impact map', () => {
});
});

test('When I get a calculated H3 Water Impact Map with the necessary input values and Location Type filter, then I should get the correct h3 data', async () => {
test('When I get a calculated H3 Impact Map with the necessary input values and Location Type filter, then I should get the correct h3 data', async () => {
const response = await request(testApplication.getHttpServer())
.get(`/api/v1/h3/map/impact`)
.set('Authorization', `Bearer ${jwtToken}`)
Expand All @@ -355,7 +375,7 @@ describe('H3 Data Module (e2e) - Impact map', () => {
});
});

test('When I get a calculated H3 Water Impact Map with the necessary input values and Scenario Id property, then the response should include both actual data and Scenario data for the given id (ignoring INACTIVE interventions), and the quantiles should be calculated differently', async () => {
test('When I get a calculated H3 Impact Map with the necessary input values and Scenario Id property, then the response should include both actual data and Scenario data for the given id (ignoring INACTIVE interventions), and the quantiles should be calculated differently', async () => {
const response = await request(testApplication.getHttpServer())
.get(`/api/v1/h3/map/impact`)
.set('Authorization', `Bearer ${jwtToken}`)
Expand Down
24 changes: 24 additions & 0 deletions api/test/e2e/h3-data/mocks/h3-impact-map.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { h3DataMock } from './h3-data.mock';
import { Material, MATERIALS_STATUS } from 'modules/materials/material.entity';
import {
createAdminRegion,
createBusinessUnit,
createGeoRegion,
createIndicatorRecord,
createMaterial,
Expand Down Expand Up @@ -41,6 +42,7 @@ import {
import { IndicatorRecord } from 'modules/indicator-records/indicator-record.entity';
import { Scenario } from 'modules/scenarios/scenario.entity';
import { DataSource } from 'typeorm';
import { BusinessUnit } from '../../../../src/modules/business-units/business-unit.entity';

export interface ImpactMapMockData {
indicatorId: string;
Expand All @@ -61,6 +63,8 @@ export interface ImpactMapMockData {
harvestH3DataTwoId: string;
scenarioId: string;
scenarioTwoId: string;
businessUnitOneId: string;
businessUnitTwoId: string;
tablesToDrop: string[];
}

Expand Down Expand Up @@ -141,6 +145,10 @@ export const createImpactMapMockData = async (
name: 'AdminRegionOne',
});

const businessUnitOne: BusinessUnit = await createBusinessUnit({
name: 'BusinessUnitOne',
});

const t1SupplierOne: Supplier = await createSupplier({
name: 'T1SupplierOne',
});
Expand All @@ -153,6 +161,7 @@ export const createImpactMapMockData = async (
adminRegion: adminRegionOne,
geoRegion: geoRegionOne,
material: materialOne,
businessUnit: businessUnitOne,
t1Supplier: t1SupplierOne,
producer: producerSupplierOne,
locationType: LOCATION_TYPES.PRODUCTION_AGGREGATION_POINT,
Expand Down Expand Up @@ -191,6 +200,10 @@ export const createImpactMapMockData = async (
name: 'DEF',
});

const businessUnitTwo: BusinessUnit = await createBusinessUnit({
name: 'BusinessUnitTwo',
});

const adminRegionTwo: AdminRegion = await createAdminRegion({
name: 'AdminRegionTwo',
});
Expand All @@ -206,6 +219,7 @@ export const createImpactMapMockData = async (
const sourcingLocationTwo: SourcingLocation = await createSourcingLocation({
adminRegion: adminRegionTwo,
geoRegion: geoRegionTwo,
businessUnit: businessUnitTwo,
material: materialTwo,
t1Supplier: t1SupplierTwo,
producer: producerSupplierTwo,
Expand Down Expand Up @@ -235,6 +249,7 @@ export const createImpactMapMockData = async (
scenarioInterventionId: scenarioInterventionOne.id,
adminRegionId: adminRegionOne.id,
geoRegionId: geoRegionOne.id,
businessUnitId: businessUnitOne.id,
materialId: materialOne.id,
t1SupplierId: t1SupplierOne.id,
producerId: producerSupplierOne.id,
Expand Down Expand Up @@ -262,6 +277,7 @@ export const createImpactMapMockData = async (
scenarioInterventionId: scenarioInterventionOne.id,
adminRegionId: adminRegionOne.id,
geoRegionId: geoRegionOne.id,
businessUnitId: businessUnitOne.id,
materialId: materialOne.id,
t1SupplierId: t1SupplierOne.id,
producerId: producerSupplierOne.id,
Expand Down Expand Up @@ -293,6 +309,7 @@ export const createImpactMapMockData = async (
await createSourcingLocation({
scenarioInterventionId: scenarioInterventionOneInactive.id,
adminRegionId: adminRegionOne.id,
businessUnitId: businessUnitOne.id,
geoRegionId: geoRegionOne.id,
materialId: materialOne.id,
t1SupplierId: t1SupplierOne.id,
Expand Down Expand Up @@ -320,6 +337,7 @@ export const createImpactMapMockData = async (
scenarioInterventionId: scenarioInterventionOneInactive.id,
adminRegionId: adminRegionOne.id,
geoRegionId: geoRegionOne.id,
businessUnitId: businessUnitOne.id,
materialId: materialOne.id,
t1SupplierId: t1SupplierOne.id,
producerId: producerSupplierOne.id,
Expand Down Expand Up @@ -350,6 +368,7 @@ export const createImpactMapMockData = async (
scenarioInterventionId: scenarioInterventionTwo.id,
adminRegionId: adminRegionTwo.id,
geoRegionId: geoRegionTwo.id,
businessUnitId: businessUnitTwo.id,
materialId: materialTwo.id,
t1SupplierId: t1SupplierTwo.id,
producerId: producerSupplierTwo.id,
Expand Down Expand Up @@ -377,6 +396,7 @@ export const createImpactMapMockData = async (
scenarioInterventionId: scenarioInterventionTwo.id,
adminRegionId: adminRegionTwo.id,
geoRegionId: geoRegionTwo.id,
businessUnitId: businessUnitTwo.id,
materialId: materialTwo.id,
t1SupplierId: t1SupplierTwo.id,
producerId: producerSupplierTwo.id,
Expand Down Expand Up @@ -411,6 +431,7 @@ export const createImpactMapMockData = async (
adminRegionId: adminRegionOne.id,
geoRegionId: geoRegionOne.id,
materialId: materialOne.id,
businessUnitId: businessUnitOne.id,
t1SupplierId: t1SupplierOne.id,
producerId: producerSupplierOne.id,
locationType: LOCATION_TYPES.PRODUCTION_AGGREGATION_POINT,
Expand Down Expand Up @@ -448,6 +469,7 @@ export const createImpactMapMockData = async (
adminRegionId: adminRegionThree.id,
geoRegionId: geoRegionThree.id,
materialId: materialOne.id,
businessUnitId: businessUnitOne.id,
t1SupplierId: t1SupplierOne.id,
producerId: producerSupplierOne.id,
locationType: LOCATION_TYPES.PRODUCTION_AGGREGATION_POINT,
Expand Down Expand Up @@ -487,6 +509,8 @@ export const createImpactMapMockData = async (
harvestH3DataTwoId: harvestH3Data.id,
scenarioId: scenario.id,
scenarioTwoId: scenarioTwo.id,
businessUnitOneId: businessUnitOne.id,
businessUnitTwoId: businessUnitTwo.id,
tablesToDrop,
};
};
Expand Down

0 comments on commit 8387b6c

Please sign in to comment.