From f02c8a968b74b5540d06a0b0766f1d7325e7bf34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20PAILHAREY?= <rpailharey@grandlyon.com> Date: Thu, 20 Jan 2022 13:11:26 +0000 Subject: [PATCH] feat(fluidPrices): Dynamic prices for EGL fluid --- src/components/FAQ/FAQData.spec.tsx | 4 +- src/db/fluidPrices.json | 60 +++++++++++++++++++++++ src/migrations/migration.data.ts | 21 ++++++++ src/migrations/migration.ts | 2 + src/services/fluidsPrices.service.spec.ts | 60 ++++++++++++++++++++++- src/services/fluidsPrices.service.ts | 17 +++++++ src/targets/services/fluidsPrices.ts | 22 +++++---- tests/__mocks__/fluidPrice.mock.ts | 30 +++++++++--- 8 files changed, 196 insertions(+), 20 deletions(-) diff --git a/src/components/FAQ/FAQData.spec.tsx b/src/components/FAQ/FAQData.spec.tsx index ce8cdd348..dcdd2188d 100644 --- a/src/components/FAQ/FAQData.spec.tsx +++ b/src/components/FAQ/FAQData.spec.tsx @@ -1,6 +1,6 @@ import mockClient from '../../../tests/__mocks__/client' import FaqData from 'components/FAQ/FAQData' -import { allFluidPrices } from '../../../tests/__mocks__/fluidPrice.mock' +import { allLastFluidPrices } from '../../../tests/__mocks__/fluidPrice.mock' import { FAQSection } from 'models' jest.mock('cozy-ui/transpiled/react/I18n', () => { @@ -28,7 +28,7 @@ describe('FAQData', () => { }) it('should return', async () => { - mockGetAllLastPrices.mockResolvedValue(allFluidPrices) + mockGetAllLastPrices.mockResolvedValue(allLastFluidPrices) const result: FAQSection[] = await FaqData(mockClient) expect(result.length).toBe(3) }) diff --git a/src/db/fluidPrices.json b/src/db/fluidPrices.json index 2f1689af3..218978887 100644 --- a/src/db/fluidPrices.json +++ b/src/db/fluidPrices.json @@ -83,6 +83,66 @@ "startDate": "2021-08-01T00:00:00.000Z", "endDate": null }, + { + "fluidType": 1, + "price": 0.0030735, + "startDate": "2012-01-01T00:00:00.000Z", + "endDate": "2012-12-31T23:59:59.000Z" + }, + { + "fluidType": 1, + "price": 0.0031483, + "startDate": "2013-01-01T00:00:00.000Z", + "endDate": "2013-12-31T23:59:59.000Z" + }, + { + "fluidType": 1, + "price": 0.0031381, + "startDate": "2014-01-01T00:00:00.000Z", + "endDate": "2014-12-31T23:59:59.000Z" + }, + { + "fluidType": 1, + "price": 0.00307, + "startDate": "2015-01-01T00:00:00.000Z", + "endDate": "2015-12-31T23:59:59.000Z" + }, + { + "fluidType": 1, + "price": 0.0031, + "startDate": "2016-01-01T00:00:00.000Z", + "endDate": "2016-12-31T23:59:59.000Z" + }, + { + "fluidType": 1, + "price": 0.00311, + "startDate": "2017-01-01T00:00:00.000Z", + "endDate": "2017-12-31T23:59:59.000Z" + }, + { + "fluidType": 1, + "price": 0.00313, + "startDate": "2018-01-01T00:00:00.000Z", + "endDate": "2018-12-31T23:59:59.000Z" + }, + { + "fluidType": 1, + "price": 0.00313, + "startDate": "2019-01-01T00:00:00.000Z", + "endDate": "2019-12-31T23:59:59.000Z" + }, + { + "fluidType": 1, + "price": 0.00315, + "startDate": "2020-01-01T00:00:00.000Z", + "endDate": "2020-12-31T23:59:59.000Z" + }, + { + "fluidType": 1, + "price": 0.00319, + "startDate": "2021-01-01T00:00:00.000Z", + "endDate": null + }, { "fluidType": 2, "price": 0.0919, diff --git a/src/migrations/migration.data.ts b/src/migrations/migration.data.ts index 094b30109..b2ce44182 100644 --- a/src/migrations/migration.data.ts +++ b/src/migrations/migration.data.ts @@ -19,6 +19,7 @@ import { Client } from 'cozy-client' import { DateTime } from 'luxon' import { UserQuizState } from 'enum/userQuiz.enum' import fluidsPricesData from 'db/fluidPrices.json' +import { FluidType } from 'enum/fluid.enum' export const SCHEMA_INITIAL_VERSION = 0 @@ -485,4 +486,24 @@ export const migrations: Migration[] = [ }) }, }, + { + baseSchemaVersion: 17, + targetSchemaVersion: 18, + appVersion: '1.7.0', + description: 'Init new fluidPrices for water', + releaseNotes: null, + docTypes: FLUIDPRICES_DOCTYPE, + + run: async (_client: Client, docs: any[]): Promise<any> => { + const waterPricesData = fluidsPricesData.filter(fluidPriceData => { + return fluidPriceData.fluidType === FluidType.WATER + }) + const createWaterPricesData = waterPricesData.map(waterPriceData => { + waterPriceData.createAction = true + waterPriceData.doctype = FLUIDPRICES_DOCTYPE + return waterPriceData + }) + return createWaterPricesData + }, + }, ] diff --git a/src/migrations/migration.ts b/src/migrations/migration.ts index fa9c222a1..11acfabad 100644 --- a/src/migrations/migration.ts +++ b/src/migrations/migration.ts @@ -87,6 +87,8 @@ async function save(_client: Client, docs: any[]): Promise<MigrationResult> { docs.forEach(async doc => { if (doc.deleteAction) { await _client.destroy(doc) + } else if (doc.createAction) { + await _client.create(doc.doctype, doc) } else { await _client.save(doc) } diff --git a/src/services/fluidsPrices.service.spec.ts b/src/services/fluidsPrices.service.spec.ts index a146ffba2..c3a9fe500 100644 --- a/src/services/fluidsPrices.service.spec.ts +++ b/src/services/fluidsPrices.service.spec.ts @@ -2,7 +2,10 @@ import FluidPricesService from './fluidsPrices.service' import mockClient from '../../tests/__mocks__/client' import { QueryResult } from 'cozy-client' import { FluidPrice } from 'models' -import { fluidPrices } from '../../tests/__mocks__/fluidPrice.mock' +import { + fluidPrices, + allLastFluidPrices, +} from '../../tests/__mocks__/fluidPrice.mock' import { FluidType } from 'enum/fluid.enum' import { DateTime } from 'luxon' @@ -60,4 +63,59 @@ describe('FluidPrices service', () => { expect(mockClient.query).toBeCalled() }) }) + + describe('Fluid Prices - getAllLastPrices', () => { + it('should getAllLastPrice', async () => { + const mockQueryResult: QueryResult<FluidPrice[]> = { + data: fluidPrices, + bookmark: '', + next: false, + skip: 0, + } + mockClient.query.mockResolvedValueOnce(mockQueryResult) + const prices = await fluidPricesService.getAllLastPrices() + console.log('Prix reçus :', prices) + console.log('Prix attendus :', allLastFluidPrices) + expect(prices).toStrictEqual(allLastFluidPrices) + expect(mockClient.query).toBeCalled() + }) + }) + + describe('Fluid Prices - deleteAllFluidsPrices', () => { + it('should return true when fluidsPrices stored', async () => { + const mockQueryResult: QueryResult<FluidPrice[]> = { + data: fluidPrices, + bookmark: '', + next: false, + skip: 0, + } + mockClient.query.mockResolvedValueOnce(mockQueryResult) + const result = await fluidPricesService.deleteAllFluidsPrices() + expect(mockClient.destroy).toBeCalledTimes(6) + expect(result).toBe(true) + }) + it('should return true when no fluidsPrices stored', async () => { + const mockQueryResult: QueryResult<FluidPrice[]> = { + data: [], + bookmark: '', + next: false, + skip: 0, + } + mockClient.query.mockResolvedValueOnce(mockQueryResult) + const result = await fluidPricesService.deleteAllFluidsPrices() + expect(result).toBe(true) + }) + it('should return false when error happened on deletion', async () => { + const mockQueryResult: QueryResult<FluidPrice[]> = { + data: fluidPrices, + bookmark: '', + next: false, + skip: 0, + } + mockClient.destroy.mockRejectedValue(new Error()) + mockClient.query.mockResolvedValueOnce(mockQueryResult) + const result = await fluidPricesService.deleteAllFluidsPrices() + expect(result).toBe(false) + }) + }) }) diff --git a/src/services/fluidsPrices.service.ts b/src/services/fluidsPrices.service.ts index 8e131cdfa..2304a2f51 100644 --- a/src/services/fluidsPrices.service.ts +++ b/src/services/fluidsPrices.service.ts @@ -85,4 +85,21 @@ export default class FluidPricesService { return fluidsPrices } + + /** + * Delete all fluidPrices entities from the db + * @returns {boolean} - true when deleted with success + * @throws {Error} + */ + public async deleteAllFluidsPrices(): Promise<boolean> { + const fluidsPrices = await this.getAllPrices() + try { + for (let index = 0; index < fluidsPrices.length; index++) { + await this._client.destroy(fluidsPrices[index]) + } + return true + } catch (error) { + return false + } + } } diff --git a/src/targets/services/fluidsPrices.ts b/src/targets/services/fluidsPrices.ts index d658871d4..32a9e11d1 100644 --- a/src/targets/services/fluidsPrices.ts +++ b/src/targets/services/fluidsPrices.ts @@ -6,11 +6,7 @@ import FluidPricesService from 'services/fluidsPrices.service' import { DataloadEntity, TimePeriod } from 'models' import ConsumptionDataManager from 'services/consumption.service' import { TimeStep } from 'enum/timeStep.enum' -import { - ENEDIS_DAY_DOCTYPE, - ENEDIS_MINUTE_DOCTYPE, - GRDF_DAY_DOCTYPE, -} from 'doctypes' +import { ENEDIS_DAY_DOCTYPE, GRDF_DAY_DOCTYPE, EGL_DAY_DOCTYPE } from 'doctypes' import { FluidType } from 'enum/fluid.enum' import QueryRunner from 'services/queryRunner.service' const log = logger.namespace('fluidPrices') @@ -64,7 +60,7 @@ const aggregatePrices = async ( ) => { const tsa = [TimeStep.MONTH, TimeStep.YEAR] log('debug', `Aggregation...`) - const aggregartePromises = tsa.map(async ts => { + const aggregatePromises = tsa.map(async ts => { return new Promise<void>(async resolve => { let date: DateTime = DateTime.local() Object.assign(date, firstDate) @@ -97,7 +93,7 @@ const aggregatePrices = async ( }) }) - await Promise.all(aggregartePromises) + await Promise.all(aggregatePromises) log('debug', `Aggregation done`) } @@ -108,6 +104,9 @@ const getDoctypeTypeByFluid = (fluidType: FluidType): string => { if (fluidType === FluidType.GAS) { return GRDF_DAY_DOCTYPE } + if (fluidType === FluidType.WATER) { + return EGL_DAY_DOCTYPE + } log('error', 'Unkown FluidType') throw new Error() } @@ -116,9 +115,10 @@ const getTimeSetByFluid = (fluidType: FluidType): TimeStep[] => { if (fluidType === FluidType.ELECTRICITY) { return [TimeStep.DAY, TimeStep.HALF_AN_HOUR] } - if (fluidType === FluidType.GAS) { + if (fluidType === FluidType.GAS || fluidType === FluidType.WATER) { return [TimeStep.DAY] } + log('error', 'Unkown FluidType') throw new Error() } @@ -204,8 +204,12 @@ const processPrices = async ({ client }: PricesProps) => { log('info', `Electricity data done`) log('info', `Processing gas data...`) const gas = applyPrices(client, FluidType.GAS) - await Promise.all([elec, gas]) log('info', `Gas data done`) + log('info', `Processing water data...`) + const water = applyPrices(client, FluidType.WATER) + log('info', `Water data done`) + await Promise.all([elec, gas, water]) + log('info', `processPrices done`) } runService(processPrices) diff --git a/tests/__mocks__/fluidPrice.mock.ts b/tests/__mocks__/fluidPrice.mock.ts index ad5ebb806..63f6b6f56 100644 --- a/tests/__mocks__/fluidPrice.mock.ts +++ b/tests/__mocks__/fluidPrice.mock.ts @@ -17,11 +17,18 @@ export const fluidPrices: FluidPrice[] = [ }, { _id: '03045ea1afecc7a86e5443a52e00b07d', - endDate: '2021-10-31T23:59:59.000Z', + endDate: '', fluidType: 0, price: 0.1329, startDate: '2021-10-10T00:00:00.000Z', }, + { + _id: '03045ea1afecc7a86e5443a52e00b07d', + endDate: '', + fluidType: 1, + price: 0.0039, + startDate: '2013-08-01T00:00:00.000Z', + }, { _id: '03045ea1afecc7a86e5443a52e00b07d', endDate: '2014-10-31T23:59:59.000Z', @@ -29,28 +36,35 @@ export const fluidPrices: FluidPrice[] = [ price: 1.029, startDate: '2013-08-01T00:00:00.000Z', }, + { + _id: '03045ea1afecc7a86e5443a52e00b07d', + endDate: '', + fluidType: 2, + price: 1.029, + startDate: '2014-11-01T00:00:00.000Z', + }, ] -export const allFluidPrices: FluidPrice[] = [ +export const allLastFluidPrices: FluidPrice[] = [ { _id: '03045ea1afecc7a86e5443a52e00b07d', endDate: '', fluidType: 0, - price: 0.1429, - startDate: '2020-08-01T00:00:00.000Z', + price: 0.1329, + startDate: '2021-10-10T00:00:00.000Z', }, { _id: '03045ea1afecc7a86e5443a52e00b07d', endDate: '', fluidType: 1, - price: 0.1529, - startDate: '2021-01-01T00:00:00.000Z', + price: 0.0039, + startDate: '2013-08-01T00:00:00.000Z', }, { _id: '03045ea1afecc7a86e5443a52e00b07d', endDate: '', fluidType: 2, - price: 0.1329, - startDate: '2021-10-10T00:00:00.000Z', + price: 1.029, + startDate: '2014-11-01T00:00:00.000Z', }, ] -- GitLab