Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spike/landgrif 734 spike avoid stored function #591

Open
wants to merge 8 commits into
base: dev
Choose a base branch
from
3 changes: 3 additions & 0 deletions api/config/custom-environment-variables.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,8 @@
},
"map": {
"distributed": "DISTRIBUTED_MAP"
},
"featureFlags": {
"simpleImportCalculations": "SIMPLE_IMPORT_CALCULATIONS"
}
}
3 changes: 3 additions & 0 deletions api/config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,8 @@

"map": {
"distributed": true
},
"featureFlags": {
"simpleImportCalculations": "false"
}
}
3 changes: 3 additions & 0 deletions api/config/test.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,8 @@
},
"geolocation": {
"gmapsApiKey": "myVeryBadJWTSecretForTests"
},
"featureFlags": {
"simpleImportCalculations": "true"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { MissingH3DataError } from 'modules/indicator-records/errors/missing-h3-
import { TasksService } from 'modules/tasks/tasks.service';
import { IndicatorRecord } from 'modules/indicator-records/indicator-record.entity';
import { ScenariosService } from 'modules/scenarios/scenarios.service';
import * as config from 'config';

export interface LocationData {
locationAddressInput?: string;
Expand Down Expand Up @@ -141,7 +142,10 @@ export class SourcingDataImportService {
// Getting H3 data for calculations is done within DB so we need to improve the error handling
// TBD: What to do when there is no H3 for a Material
try {
await this.indicatorRecordsService.createIndicatorRecordsForAllSourcingRecords();
// TODO remove feature flag selection, once the solution has been approved
config.get('featureFlags.simpleImportCalculations')
? await this.indicatorRecordsService.createIndicatorRecordsForAllSourcingRecordsV2()
: await this.indicatorRecordsService.createIndicatorRecordsForAllSourcingRecords();
this.logger.log('Indicator Records generated');
// TODO: Hack to force m.view refresh once Indicator Records are persisted. This should be automagically
// done by the AfterInser() event listener placed in indicator-record.entity.ts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { IndicatorsModule } from 'modules/indicators/indicators.module';
import { MaterialsModule } from 'modules/materials/materials.module';
import { SourcingRecordsModule } from 'modules/sourcing-records/sourcing-records.module';
import { CachedDataModule } from 'modules/cached-data/cached-data.module';
import { ImpactCalculatorService } from 'modules/indicator-records/services/impact-calculator.service';

@Module({
imports: [
Expand All @@ -19,7 +20,7 @@ import { CachedDataModule } from 'modules/cached-data/cached-data.module';
CachedDataModule,
],
controllers: [IndicatorRecordsController],
providers: [IndicatorRecordsService],
providers: [IndicatorRecordsService, ImpactCalculatorService],
exports: [IndicatorRecordsService],
})
export class IndicatorRecordsModule {}
51 changes: 51 additions & 0 deletions api/src/modules/indicator-records/indicator-records.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
CACHED_DATA_TYPE,
CachedData,
} from 'modules/cached-data/cached.data.entity';
import { ImpactCalculatorService } from 'modules/indicator-records/services/impact-calculator.service';

export interface CachedRawValue {
rawValue: number;
Expand All @@ -51,6 +52,7 @@ export class IndicatorRecordsService extends AppBaseService<
constructor(
@InjectRepository(IndicatorRecordRepository)
private readonly indicatorRecordRepository: IndicatorRecordRepository,
private readonly impactCalculatorService: ImpactCalculatorService,
private readonly indicatorService: IndicatorsService,
private readonly h3DataService: H3DataService,
private readonly materialsToH3sService: MaterialsToH3sService,
Expand Down Expand Up @@ -221,6 +223,55 @@ export class IndicatorRecordsService extends AppBaseService<
await this.indicatorRecordRepository.saveChunks(indicatorRecords);
}

async createIndicatorRecordsForAllSourcingRecordsV2(): Promise<void> {
//Calculate raw impact Data for all available indicators on the system
const indicators: Indicator[] =
await this.indicatorService.getAllIndicators();

const rawData: SourcingRecordsWithIndicatorRawDataDto[] =
await this.impactCalculatorService.calculateAllRawValuesForAllSourcingRecords(
indicators,
);

const calculatedData: IndicatorRecordCalculatedValuesDto[] = rawData.map(
(sourcingRecordData: SourcingRecordsWithIndicatorRawDataDto) => {
// Small DTO transformation for calculation method
const indicatorComputedRawDataDto: IndicatorComputedRawDataDto = {
harvestedArea: sourcingRecordData.harvestedArea,
production: sourcingRecordData.production,
indicatorValues: sourcingRecordData.indicatorValues,
};

return this.calculateIndicatorValues(
sourcingRecordData.sourcingRecordId,
sourcingRecordData.tonnage,
sourcingRecordData.materialH3DataId,
indicatorComputedRawDataDto,
);
},
);

// Create IndicatorRecord instances
const indicatorRecords: IndicatorRecord[] = [];
for (const calculatedIndicatorRecords of calculatedData) {
for (const indicator of indicators) {
indicatorRecords.push(
IndicatorRecord.merge(new IndicatorRecord(), {
value: calculatedIndicatorRecords.values.get(
indicator.nameCode as INDICATOR_TYPES,
),
indicatorId: indicator.id,
status: INDICATOR_RECORD_STATUS.SUCCESS,
sourcingRecordId: calculatedIndicatorRecords.sourcingRecordId,
scaler: calculatedIndicatorRecords.production,
materialH3DataId: calculatedIndicatorRecords.materialH3DataId,
}),
);
}
}
await this.indicatorRecordRepository.saveChunks(indicatorRecords);
}

/**
* @description Creates Indicator-Records for a single Sourcing-Record, by first retrieving Raw Indicator data from the DB, then applying
* the methodology and persist new Indicator Records
Expand Down
Loading