diff --git a/src/components/PerformanceIndicator/FluidPerformanceIndicator.tsx b/src/components/PerformanceIndicator/FluidPerformanceIndicator.tsx index a331d9ddb2998c86e383a66746d4e493ec27d8d2..b5f3f51601a5e3044dc8704a2e217d9ddbd154a7 100644 --- a/src/components/PerformanceIndicator/FluidPerformanceIndicator.tsx +++ b/src/components/PerformanceIndicator/FluidPerformanceIndicator.tsx @@ -1,13 +1,13 @@ -import React from 'react' -import './fluidPerformanceIndicator.scss' import { useI18n } from 'cozy-ui/transpiled/react/I18n' import { DateTime } from 'luxon' +import React from 'react' +import './fluidPerformanceIndicator.scss' +import StyledIcon from 'components/CommonKit/Icon/StyledIcon' import { FluidType } from 'enum/fluid.enum' import { PerformanceIndicator } from 'models' import { getPicto } from 'utils/picto' import { formatNumberValues, getPreviousMonthName } from 'utils/utils' -import StyledIcon from 'components/CommonKit/Icon/StyledIcon' interface FluidPerformanceIndicatorProps { performanceIndicator: PerformanceIndicator @@ -54,18 +54,18 @@ const FluidPerformanceIndicator: React.FC<FluidPerformanceIndicatorProps> = ({ performanceIndicator && performanceIndicator.percentageVariation && performanceIndicator.percentageVariation > 0 - ? 'negative' - : 'positive' + ? 'positive' + : 'negative' }`} > {performanceIndicator && performanceIndicator.percentageVariation ? ( performanceIndicator.percentageVariation > 0 ? ( - `-${formatNumberValues( + `+${formatNumberValues( performanceIndicator.percentageVariation * 100 )} %` ) : ( - `+${formatNumberValues( + `-${formatNumberValues( Math.abs(performanceIndicator.percentageVariation) * 100 )} %` diff --git a/src/services/consumption.service.spec.ts b/src/services/consumption.service.spec.ts index 21583ae6027664679276e5dcee4a8102f0f70e9c..4b69dd97648bd26e976824462fd1b709eaa931eb 100644 --- a/src/services/consumption.service.spec.ts +++ b/src/services/consumption.service.spec.ts @@ -1,8 +1,9 @@ -import ConsumptionDataManager from './consumption.service' -import mockClient from '../../tests/__mocks__/client' +import { QueryResult } from 'cozy-client' +import { ENEDIS_MINUTE_DOCTYPE } from 'doctypes' +import { DataloadState } from 'enum/dataload.enum' +import { FluidType } from 'enum/fluid.enum' import { TimeStep } from 'enum/timeStep.enum' import { DateTime } from 'luxon' -import { FluidType } from 'enum/fluid.enum' import { Datachart, Dataload, @@ -11,12 +12,11 @@ import { FluidStatus, TimePeriod, } from 'models' -import { ENEDIS_MINUTE_DOCTYPE } from 'doctypes' +import mockClient from '../../tests/__mocks__/client' import { fluidPrices } from '../../tests/__mocks__/fluidPrice.mock' -import { QueryResult } from 'cozy-client' -import { loadDayData } from '../../tests/__mocks__/loadDayData.mock' -import { DataloadState } from 'enum/dataload.enum' import { fluidStatusConnectedData } from '../../tests/__mocks__/fluidStatusData.mock' +import { loadDayData } from '../../tests/__mocks__/loadDayData.mock' +import ConsumptionDataManager from './consumption.service' const mockFetchFluidData = jest.fn() const mockFetchFluidMaxData = jest.fn() @@ -374,13 +374,13 @@ describe('Consumption service', () => { const expectedResult = [ { compareValue: 466.94, - percentageVariation: -0.18227181222426858, + percentageVariation: 0.18227181222426858, value: 552.05, price: null, }, { compareValue: 466.94, - percentageVariation: -0.18227181222426858, + percentageVariation: 0.18227181222426858, value: 552.05, price: null, }, diff --git a/src/services/consumption.service.ts b/src/services/consumption.service.ts index 2706147c011d5b1645cd92ff69d76242d1b0ab4a..1bf0cc875e2645f308d4e7f75f4c4e66a1627e75 100644 --- a/src/services/consumption.service.ts +++ b/src/services/consumption.service.ts @@ -1,7 +1,10 @@ -import { DateTime } from 'luxon' -import { Client, QueryDefinition, Q, QueryResult } from 'cozy-client' +import { Client, Q, QueryDefinition, QueryResult } from 'cozy-client' +import { Doctype } from 'cozy-client/types/types' +import { ENEDIS_MINUTE_DOCTYPE } from 'doctypes' +import { DataloadState } from 'enum/dataload.enum' import { FluidType } from 'enum/fluid.enum' import { TimeStep } from 'enum/timeStep.enum' +import { DateTime } from 'luxon' import { Datachart, Dataload, @@ -9,16 +12,13 @@ import { DataloadValueDetail, FluidStatus, PerformanceIndicator, - TimePeriod, + TimePeriod } from 'models' +import { EnedisMonthlyAnalysisData } from 'models/enedisMonthlyAnalysis' import ConsumptionFormatterService from 'services/consumptionFormatter.service' -import QueryRunnerService from 'services/queryRunner.service' import ConsumptionValidatorService from 'services/consumptionValidator.service' import ConverterService from 'services/converter.service' -import { ENEDIS_MINUTE_DOCTYPE } from 'doctypes' -import { Doctype } from 'cozy-client/types/types' -import { EnedisMonthlyAnalysisData } from 'models/enedisMonthlyAnalysis' -import { DataloadState } from 'enum/dataload.enum' +import QueryRunnerService from 'services/queryRunner.service' // eslint-disable-next-line @typescript-eslint/interface-name-prefix export interface ISingleFluidChartData { @@ -57,24 +57,22 @@ export default class ConsumptionDataManager { compareTimePeriod?: TimePeriod, isHome?: boolean ): Promise<Datachart | null> { - const InputisValid: boolean = - this._consumptionValidatorService.ValidateGetGraphData( - timePeriod, - timeStep, - fluidTypes, - compareTimePeriod - ) + const InputisValid: boolean = this._consumptionValidatorService.ValidateGetGraphData( + timePeriod, + timeStep, + fluidTypes, + compareTimePeriod + ) if (!InputisValid) return null if (fluidTypes.length === 1 && !isHome) { const fluidType: FluidType = fluidTypes[0] // running the query - const fetchedData: Datachart | null = - await this.fetchSingleFluidGraphData( - timePeriod, - timeStep, - fluidType, - compareTimePeriod - ) + const fetchedData: Datachart | null = await this.fetchSingleFluidGraphData( + timePeriod, + timeStep, + fluidType, + compareTimePeriod + ) // formatting data const formattedData: Datachart | null = this.formatGraphDataManager( @@ -110,8 +108,9 @@ export default class ConsumptionDataManager { chartFluid: fluidType, }) } - const aggregatedData: Datachart | null = - this.aggregateGraphData(toBeAgreggatedData) + const aggregatedData: Datachart | null = this.aggregateGraphData( + toBeAgreggatedData + ) return aggregatedData } else return null } @@ -153,7 +152,9 @@ export default class ConsumptionDataManager { fluidTypes: FluidType ): Promise<Dataload[] | null> { const timePeriod = { - startDate: DateTime.now().plus({ days: -3 }).startOf('day'), + startDate: DateTime.now() + .plus({ days: -3 }) + .startOf('day'), endDate: DateTime.now(), } @@ -198,8 +199,9 @@ export default class ConsumptionDataManager { graphData.actualData ) if (graphData.actualData[0].price) - performanceIndicator.price = - this.calculatePerformanceIndicatorPrice(graphData.actualData) + performanceIndicator.price = this.calculatePerformanceIndicatorPrice( + graphData.actualData + ) } if ( @@ -211,11 +213,10 @@ export default class ConsumptionDataManager { graphData.comparisonData ) performanceIndicator.compareValue = comparisonSumValue - performanceIndicator.percentageVariation = - this.calculatePerformanceIndicatorVariationPercentage( - performanceIndicator.value || 0, - comparisonSumValue - ) + performanceIndicator.percentageVariation = this.calculatePerformanceIndicatorVariationPercentage( + performanceIndicator.value || 0, + comparisonSumValue + ) } performanceIndicators[fluidType] = performanceIndicator @@ -246,7 +247,7 @@ export default class ConsumptionDataManager { dataSum: number, comparisonDataSum: number ): number { - return 1 - dataSum / comparisonDataSum + return dataSum / comparisonDataSum - 1 } private async fetchSingleFluidGraphData( @@ -301,26 +302,24 @@ export default class ConsumptionDataManager { ): Datachart | null { if (!data) return null - const formattedActualData: Dataload[] = - this._consumptionFormatterService.formatGraphData( - data.actualData, - timePeriod, + const formattedActualData: Dataload[] = this._consumptionFormatterService.formatGraphData( + data.actualData, + timePeriod, + timeStep, + fluidType, + fluidStatus + ) + + let formattedComparisonData: Dataload[] | null = null + if (compareTimePeriod) + formattedComparisonData = this._consumptionFormatterService.formatGraphData( + data.comparisonData ? data.comparisonData : [], + compareTimePeriod, timeStep, fluidType, fluidStatus ) - let formattedComparisonData: Dataload[] | null = null - if (compareTimePeriod) - formattedComparisonData = - this._consumptionFormatterService.formatGraphData( - data.comparisonData ? data.comparisonData : [], - compareTimePeriod, - timeStep, - fluidType, - fluidStatus - ) - const result: Datachart = { actualData: formattedActualData, comparisonData: formattedComparisonData, @@ -491,10 +490,9 @@ export default class ConsumptionDataManager { if (singleFluidCharts[0].chartData.actualData[i]) { // Define the aggregated state - const aggregatedDataloadState: DataloadState = - this._consumptionFormatterService.defineAggregatedDataloadState( - tempAggregatedState - ) + const aggregatedDataloadState: DataloadState = this._consumptionFormatterService.defineAggregatedDataloadState( + tempAggregatedState + ) const acutaldataLoad: Dataload = { date: singleFluidCharts[0].chartData.actualData[i].date, value: agreggatedConvertedValue, @@ -511,10 +509,9 @@ export default class ConsumptionDataManager { singleFluidCharts[0].chartData.comparisonData[i] ) { // Define the aggregated state - const aggregatedComparisonDataloadState: DataloadState = - this._consumptionFormatterService.defineAggregatedDataloadState( - tempComparisonAggregatedState - ) + const aggregatedComparisonDataloadState: DataloadState = this._consumptionFormatterService.defineAggregatedDataloadState( + tempComparisonAggregatedState + ) const comparisondataLoad: Dataload = { date: singleFluidCharts[0].chartData.comparisonData[i].date, value: comparisonAgreggatedConvertedValue, @@ -601,8 +598,9 @@ export default class ConsumptionDataManager { public async saveDoc( consumptionDoc: DataloadEntity ): Promise<DataloadEntity> { - const { data: savedDoc }: QueryResult<DataloadEntity> = - await this._client.save(consumptionDoc) + const { + data: savedDoc, + }: QueryResult<DataloadEntity> = await this._client.save(consumptionDoc) return savedDoc } @@ -614,8 +612,11 @@ export default class ConsumptionDataManager { public async saveDocs( consumptionDocs: DataloadEntity[] ): Promise<DataloadEntity[]> { - const { data: savedDocs }: QueryResult<DataloadEntity[]> = - await this._client.saveAll(consumptionDocs) + const { + data: savedDocs, + }: QueryResult<DataloadEntity[]> = await this._client.saveAll( + consumptionDocs + ) return savedDocs } diff --git a/src/services/performanceIndicator.service.spec.ts b/src/services/performanceIndicator.service.spec.ts index cb046dd2a6b4b0876a0878b1ad95fa871e0e8772..f4c3f4de19281e40b96b26c4ed0881c28f200151 100644 --- a/src/services/performanceIndicator.service.spec.ts +++ b/src/services/performanceIndicator.service.spec.ts @@ -1,5 +1,5 @@ -import PerformanceIndicatorService from './performanceIndicator.service' import { PerformanceIndicator } from 'models' +import PerformanceIndicatorService from './performanceIndicator.service' describe('performanceIndicator service', () => { describe('aggregatePerformanceIndicators method', () => { @@ -26,12 +26,11 @@ describe('performanceIndicator service', () => { let expectedResult: PerformanceIndicator = { value: 5.7911, compareValue: 7.84615, - percentageVariation: 0.26191826564620857, + percentageVariation: -0.26191826564620857, } - let result = - performanceIndicatorService.aggregatePerformanceIndicators( - performanceIndicator - ) + let result = performanceIndicatorService.aggregatePerformanceIndicators( + performanceIndicator + ) expect(result).toEqual(expectedResult) //Only two values @@ -50,12 +49,11 @@ describe('performanceIndicator service', () => { expectedResult = { value: 1.8675999999999997, compareValue: 5.26785, - percentageVariation: 0.6454720616570329, + percentageVariation: -0.6454720616570329, } - result = - performanceIndicatorService.aggregatePerformanceIndicators( - performanceIndicator - ) + result = performanceIndicatorService.aggregatePerformanceIndicators( + performanceIndicator + ) expect(result).toEqual(expectedResult) //lack of value for one @@ -78,13 +76,12 @@ describe('performanceIndicator service', () => { ] expectedResult = { compareValue: 7.84615, - percentageVariation: 0.48368308023680406, + percentageVariation: -0.48368308023680406, value: 4.0511, } - result = - performanceIndicatorService.aggregatePerformanceIndicators( - performanceIndicator - ) + result = performanceIndicatorService.aggregatePerformanceIndicators( + performanceIndicator + ) expect(result).toEqual(expectedResult) //lack of compareValue for one @@ -108,12 +105,11 @@ describe('performanceIndicator service', () => { expectedResult = { value: 9.2711, compareValue: 0, - percentageVariation: -Infinity, + percentageVariation: Infinity, } - result = - performanceIndicatorService.aggregatePerformanceIndicators( - performanceIndicator - ) + result = performanceIndicatorService.aggregatePerformanceIndicators( + performanceIndicator + ) expect(result).toEqual(expectedResult) //Only one with no compared value @@ -127,12 +123,11 @@ describe('performanceIndicator service', () => { expectedResult = { value: 5.22, compareValue: 0, - percentageVariation: -Infinity, + percentageVariation: Infinity, } - result = - performanceIndicatorService.aggregatePerformanceIndicators( - performanceIndicator - ) + result = performanceIndicatorService.aggregatePerformanceIndicators( + performanceIndicator + ) expect(result).toEqual(expectedResult) //Only one with no value @@ -146,12 +141,11 @@ describe('performanceIndicator service', () => { expectedResult = { value: 0, compareValue: 2.61, - percentageVariation: 1, + percentageVariation: -1, } - result = - performanceIndicatorService.aggregatePerformanceIndicators( - performanceIndicator - ) + result = performanceIndicatorService.aggregatePerformanceIndicators( + performanceIndicator + ) expect(result).toEqual(expectedResult) }) }) diff --git a/src/services/performanceIndicator.service.ts b/src/services/performanceIndicator.service.ts index 63ce8945685152aa9a9137fa2252b3819212fb1e..c21fcb52c24744a257fdacca5c0c45d8dbcb1943 100644 --- a/src/services/performanceIndicator.service.ts +++ b/src/services/performanceIndicator.service.ts @@ -1,5 +1,5 @@ -import ConverterService from 'services/converter.service' import { PerformanceIndicator } from 'models' +import ConverterService from 'services/converter.service' export default class PerformanceIndicatorService { public aggregatePerformanceIndicators( @@ -80,7 +80,7 @@ export default class PerformanceIndicatorService { const agreggatedPerformanceIndicator: PerformanceIndicator = { value: currentValue, compareValue: compareValue, - percentageVariation: 1 - currentValue / compareValue, + percentageVariation: currentValue / compareValue - 1, } return agreggatedPerformanceIndicator } diff --git a/src/targets/services/monthlyReportNotification.ts b/src/targets/services/monthlyReportNotification.ts index 5783eb072ff2de58d7b5f182211773f2de0fbcdc..6771e90748250d44d55d645baef101b45f0a3030 100644 --- a/src/targets/services/monthlyReportNotification.ts +++ b/src/targets/services/monthlyReportNotification.ts @@ -1,19 +1,19 @@ -import logger from 'cozy-logger' import { Client } from 'cozy-client' +import logger from 'cozy-logger' +import { FluidType } from 'enum/fluid.enum' +import { TimeStep } from 'enum/timeStep.enum' import get from 'lodash/get' import { DateTime } from 'luxon' import mjml2html from 'mjml' import { PerformanceIndicator } from 'models' -import { runService } from './service' -import ProfileService from 'services/profile.service' -import MailService from 'services/mail.service' -const monthlyReportTemplate = require('notifications/monthlyReport.hbs') -import { FluidType } from 'enum/fluid.enum' -import { TimeStep } from 'enum/timeStep.enum' -import ConsumptionService from 'services/consumption.service' import { MonthlyReport } from 'models/monthlyReport.model' +import ConsumptionService from 'services/consumption.service' import EnvironmentService from 'services/environment.service' +import MailService from 'services/mail.service' +import ProfileService from 'services/profile.service' import { getMonthNameWithPrep } from 'utils/utils' +import { runService } from './service' +const monthlyReportTemplate = require('notifications/monthlyReport.hbs') const log = logger.namespace('report') @@ -42,13 +42,12 @@ const getConsumptionValue = async ( endDate: analysisDate.minus({ month: 2 }).endOf('month'), }, } - const fetchedPerformanceIndicators = - await consumptionService.getPerformanceIndicators( - periods.timePeriod, - TimeStep.MONTH, - fluidType, - periods.comparisonTimePeriod - ) + const fetchedPerformanceIndicators = await consumptionService.getPerformanceIndicators( + periods.timePeriod, + TimeStep.MONTH, + fluidType, + periods.comparisonTimePeriod + ) return fetchedPerformanceIndicators } @@ -72,12 +71,12 @@ const buildConsumptionText = async (client: Client) => { if (value) { if (value > 0) { text += - '<span class="elec-text"><br>- ' + + '<span class="elec-text"><br>+ ' + Math.ceil(value * 100) + " % d'électricité</span>" } else { text += - '<span class="elec-text"><br>+ ' + + '<span class="elec-text"><br>- ' + Math.ceil(Math.abs(value * 100)) + " % d'électricité</span>" } @@ -92,12 +91,12 @@ const buildConsumptionText = async (client: Client) => { if (value) { if (value > 0) { text += - '<span class="gas-text"><br>- ' + + '<span class="gas-text"><br>+ ' + Math.ceil(value * 100) + ' % de gaz</span>' } else { text += - '<span class="gas-text"><br>+ ' + + '<span class="gas-text"><br>- ' + Math.ceil(Math.abs(value * 100)) + ' % de gaz</span>' } @@ -110,12 +109,12 @@ const buildConsumptionText = async (client: Client) => { if (value) { if (value > 0) { text += - '<span class="water-text"><br>- ' + + '<span class="water-text"><br>+ ' + Math.ceil(value * 100) + " % d'eau</span>" } else { text += - '<span class="water-text"><br>+ ' + + '<span class="water-text"><br>- ' + Math.ceil(Math.abs(value * 100)) + " % d'eau</span>" } @@ -179,7 +178,9 @@ const monthlyReportNotification = async ({ // Init mail token for user in case he don't have one if (!userProfil.mailToken || userProfil.mailToken === '') { - const token: string = require('crypto').randomBytes(48).toString('hex') + const token: string = require('crypto') + .randomBytes(48) + .toString('hex') try { await upm.updateProfile({