From 04a96d319294bd5d1ea34725c93e39f0d3ffbe28 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20PAILHAREY?= <rpailharey@grandlyon.com>
Date: Tue, 28 Sep 2021 14:22:16 +0000
Subject: [PATCH] fix: half-hour consumption display had wrong format. Update
 format for better handling. Ref #143

---
 scripts/createDayDataFiles.js                 | 128 ++++++++++++++----
 .../HomeCards/TotalConsumption.spec.tsx       | 110 +++++++++++----
 src/components/HomeCards/TotalConsumption.tsx |  34 ++++-
 3 files changed, 220 insertions(+), 52 deletions(-)

diff --git a/scripts/createDayDataFiles.js b/scripts/createDayDataFiles.js
index a1a075a99..40586040a 100644
--- a/scripts/createDayDataFiles.js
+++ b/scripts/createDayDataFiles.js
@@ -18,28 +18,37 @@ function getRandomInt(min, max) {
 
 const generateHalfAnHourData = (_startingdate, _endingDate, min, max) => {
   let parsingDate
-  if (_endingDate.diff(_startingdate, 'days').toObject().days > 1) {
-    parsingDate = DateTime.local(
-      _endingDate.year,
-      _endingDate.month,
-      _endingDate.day - 1,
-      0,
-      0
-    )
-  } else {
-    parsingDate = DateTime.local(
-      _endingDate.year,
-      _endingDate.month,
-      _endingDate.day,
-      0,
-      0
-    )
-  }
+
+  parsingDate = DateTime.local(
+    _startingdate.year,
+    _startingdate.month,
+    _startingdate.day,
+    0,
+    0
+  )
+
   const halfAnHourDumpArray = []
 
+  let lastDay = parsingDate.day
+  const dayDumpArray = []
+
+  let lastMonth = parsingDate.month
+  const monthDumpArray = []
+
+  let lastYear = parsingDate.year
+  const yearDumpArray = []
+
+  let dailyLoad = 0
+  let monthlyLoad = 0
+  let yearlyLoad = 0
+
   while (parsingDate <= _endingDate) {
     const load = getRandomInt(min, max)
 
+    dailyLoad += load
+    monthlyLoad += load
+    yearlyLoad += load
+
     halfAnHourDumpArray.push({
       load: load,
       year: parsingDate.year,
@@ -48,9 +57,81 @@ const generateHalfAnHourData = (_startingdate, _endingDate, min, max) => {
       hour: parsingDate.hour,
       minute: parsingDate.minute,
     })
+
+    if (parsingDate.day !== lastDay) {
+      dayDumpArray.push({
+        load: Math.round(dailyLoad * 100) / 100,
+        year: lastYear,
+        month: lastMonth,
+        day: lastDay,
+        hour: 0,
+        minute: 0,
+      })
+      dailyLoad = 0
+      lastDay = parsingDate.day
+    }
+
+    if (parsingDate.month !== lastMonth) {
+      monthDumpArray.push({
+        load: Math.round(monthlyLoad * 100) / 100,
+        year: lastYear,
+        month: lastMonth,
+        day: 0,
+        hour: 0,
+        minute: 0,
+      })
+      monthlyLoad = 0
+      lastMonth = parsingDate.month
+    }
+
+    if (parsingDate.year !== lastYear) {
+      yearDumpArray.push({
+        load: Math.round(yearlyLoad * 100) / 100,
+        year: lastYear,
+        month: 1,
+        day: 1,
+        hour: 0,
+        minute: 0,
+      })
+      yearlyLoad = 0
+      lastYear = parsingDate.year
+    }
     parsingDate = parsingDate.plus({ minute: 30 })
   }
-  return halfAnHourDumpArray
+
+  dayDumpArray.push({
+    load: Math.round(dailyLoad * 100) / 100,
+    year: lastYear,
+    month: lastMonth,
+    day: lastDay,
+    hour: 0,
+    minute: 0,
+  })
+  
+  monthDumpArray.push({
+    load: Math.round(monthlyLoad * 100) / 100,
+    year: lastYear,
+    month: lastMonth,
+    day: 1,
+    hour: 0,
+    minute: 0,
+  })
+
+  yearDumpArray.push({
+    load: Math.round(yearlyLoad * 100) / 100,
+    year: lastYear,
+    month: 1,
+    day: 1,
+    hour: 0,
+    minute: 0,
+  })
+
+  return {
+    halfAnHourLoad: halfAnHourDumpArray,
+    dailyLoad: dayDumpArray,
+    monthlyLoad: monthDumpArray,
+    yearlyLoad: yearDumpArray,
+  }
 }
 
 const generateData = (_startingdate, _endingDate, min, max) => {
@@ -149,18 +230,17 @@ if (!fs.existsSync(dir)) {
 const startingdate = config.startingdate
 const endingDate = config.endingDate
 
-const HalfAnHour = generateHalfAnHourData(
+const Elec = generateHalfAnHourData(
   startingdate,
   endingDate.endOf('day'),
-  0.5,
-  1
+  0.12,
+  0.36
 )
-const Elec = generateData(startingdate, endingDate, 3, 10)
 const Gaz = generateData(startingdate, endingDate, 16, 68)
 const Eau = generateData(startingdate, endingDate, 200, 300)
 
 const dumpElec = {
-  'com.grandlyon.enedis.minute': HalfAnHour,
+  'com.grandlyon.enedis.minute': Elec.halfAnHourLoad,
   'com.grandlyon.enedis.day': Elec.dailyLoad,
   'com.grandlyon.enedis.month': Elec.monthlyLoad,
   'com.grandlyon.enedis.year': Elec.yearlyLoad,
@@ -191,7 +271,7 @@ fs.writeFile('data/dayData-water.json', dumpStringWater, function(err) {
 })
 
 const dump = {
-  'com.grandlyon.enedis.minute': HalfAnHour,
+  'com.grandlyon.enedis.minute': Elec.halfAnHourLoad,
   'com.grandlyon.enedis.day': Elec.dailyLoad,
   'com.grandlyon.enedis.month': Elec.monthlyLoad,
   'com.grandlyon.enedis.year': Elec.yearlyLoad,
diff --git a/src/components/HomeCards/TotalConsumption.spec.tsx b/src/components/HomeCards/TotalConsumption.spec.tsx
index 431bb7880..b2e509448 100644
--- a/src/components/HomeCards/TotalConsumption.spec.tsx
+++ b/src/components/HomeCards/TotalConsumption.spec.tsx
@@ -5,6 +5,12 @@ import TotalConsumption from './TotalConsumption'
 import { mockInitialChartState } from '../../../tests/__mocks__/store'
 import { graphData } from '../../../tests/__mocks__/datachartData.mock'
 
+import { Provider } from 'react-redux'
+import { act } from '@testing-library/react'
+import configureStore from 'redux-mock-store'
+import { TimeStep } from 'enum/timeStep.enum'
+import { Dataload } from 'models'
+
 jest.mock('cozy-ui/transpiled/react/I18n', () => {
   return {
     useI18n: jest.fn(() => {
@@ -15,23 +21,60 @@ jest.mock('cozy-ui/transpiled/react/I18n', () => {
   }
 })
 
+const mockStore = configureStore([])
+
+const store = mockStore({
+  ecolyo: {
+    chart: {
+      mockInitialChartState,
+    },
+  },
+})
+
+const mockHalfHourChartState = {
+  ...mockInitialChartState,
+  currentTimeStep: TimeStep.HALF_AN_HOUR,
+}
+mockHalfHourChartState.currentTimeStep = TimeStep.HALF_AN_HOUR
+
+const storeHalfHour = mockStore({
+  ecolyo: {
+    chart: {
+      mockHalfHourChartState,
+    },
+  },
+})
+
 describe('TotalConsumption component', () => {
-  it('should be rendered correctly', () => {
+  it('should be rendered correctly', async () => {
     const component = mount(
-      <TotalConsumption
-        fluidType={FluidType.ELECTRICITY}
-        actualData={mockInitialChartState.currentDatachart.actualData}
-      />
+      <Provider store={store}>
+        <TotalConsumption
+          fluidType={FluidType.ELECTRICITY}
+          actualData={mockInitialChartState.currentDatachart.actualData}
+        />
+      </Provider>
     )
+    await act(async () => {
+      await new Promise(resolve => setTimeout(resolve))
+      component.update()
+    })
     expect(component).toMatchSnapshot()
   })
-  it('should render euro value', () => {
+  it('should render euro value', async () => {
     const component = mount(
-      <TotalConsumption
-        fluidType={FluidType.ELECTRICITY}
-        actualData={graphData.actualData}
-      />
+      <Provider store={store}>
+        <TotalConsumption
+          fluidType={FluidType.ELECTRICITY}
+          actualData={graphData.actualData}
+        />
+      </Provider>
     )
+    await act(async () => {
+      await new Promise(resolve => setTimeout(resolve))
+      component.update()
+    })
+
     expect(
       component
         .find('.euro-value')
@@ -39,21 +82,20 @@ describe('TotalConsumption component', () => {
         .text()
     ).toEqual('20,23')
   })
-  it('should call Converter method', () => {
-    const mockLoadToEuro = jest.fn()
-    jest.mock('services/converter.service', () => {
-      return jest.fn(() => {
-        return {
-          loadToEuro: mockLoadToEuro,
-        }
-      })
-    })
+  it('should format multifluid value', async () => {
     const component = mount(
-      <TotalConsumption
-        fluidType={FluidType.MULTIFLUID}
-        actualData={graphData.actualData}
-      />
+      <Provider store={store}>
+        <TotalConsumption
+          fluidType={FluidType.MULTIFLUID}
+          actualData={graphData.actualData}
+        />
+      </Provider>
     )
+    await act(async () => {
+      await new Promise(resolve => setTimeout(resolve))
+      component.update()
+    })
+
     expect(
       component
         .find('.euro-value')
@@ -61,4 +103,26 @@ describe('TotalConsumption component', () => {
         .text()
     ).toEqual('130,84')
   })
+  it('should display ----- when half an hour electricity data is not activated', async () => {
+    const emptyData: Dataload[] = []
+    const component = mount(
+      <Provider store={storeHalfHour}>
+        <TotalConsumption
+          fluidType={FluidType.ELECTRICITY}
+          actualData={emptyData}
+        />
+      </Provider>
+    )
+    await act(async () => {
+      await new Promise(resolve => setTimeout(resolve))
+      component.update()
+    })
+
+    expect(
+      component
+        .find('.euro-value')
+        .first()
+        .text()
+    ).toEqual('-----')
+  })
 })
diff --git a/src/components/HomeCards/TotalConsumption.tsx b/src/components/HomeCards/TotalConsumption.tsx
index 168b0f783..cd64092a8 100644
--- a/src/components/HomeCards/TotalConsumption.tsx
+++ b/src/components/HomeCards/TotalConsumption.tsx
@@ -6,6 +6,12 @@ import { Dataload } from 'models'
 import { FluidType } from 'enum/fluid.enum'
 import ConverterService from 'services/converter.service'
 import { formatNumberValues } from 'utils/utils'
+import ConsumptionService from 'services/consumption.service'
+import { useClient } from 'cozy-client'
+import { TimeStep } from 'enum/timeStep.enum'
+import { useSelector } from 'react-redux'
+import { AppStore } from 'store'
+
 interface TotalConsumptionProps {
   actualData: Dataload[]
   fluidType: FluidType
@@ -15,27 +21,45 @@ const TotalConsumption: React.FC<TotalConsumptionProps> = ({
   actualData,
   fluidType,
 }: TotalConsumptionProps) => {
+  const { currentTimeStep } = useSelector(
+    (state: AppStore) => state.ecolyo.chart
+  )
+  const client = useClient()
   const [totalValue, setTotalValue] = useState<string>()
+
   useEffect(() => {
-    const calculateTotalValue = (): string => {
+    const calculateTotalValue = async () => {
+      const consumptionService = new ConsumptionService(client)
+      const activateHalfHourLoad = await consumptionService.checkDoctypeEntries(
+        FluidType.ELECTRICITY,
+        TimeStep.HALF_AN_HOUR
+      )
+
       const converterService = new ConverterService()
       let total = 0
 
       actualData.forEach(data => {
         if (data.value !== -1) total += data.value
       })
+
       const displayedValue =
-        total <= 0
+        total <= 0 ||
+        (!activateHalfHourLoad &&
+          currentTimeStep === TimeStep.HALF_AN_HOUR &&
+          fluidType === FluidType.ELECTRICITY)
           ? '-----'
           : fluidType === FluidType.MULTIFLUID
           ? formatNumberValues(total).toString()
           : formatNumberValues(
               converterService.LoadToEuro(total, fluidType)
             ).toString()
-      return displayedValue
+
+      setTotalValue(displayedValue)
     }
-    setTotalValue(calculateTotalValue())
-  }, [actualData, fluidType])
+
+    calculateTotalValue()
+  }, [actualData, fluidType, currentTimeStep, client])
+
   return (
     <div className="icon-line">
       <StyledIcon className="pile-icon" icon={PileIcon} size={35} />
-- 
GitLab