# Price Calculation

This section explains the price calculation process.

## Description

Since version `1.6.0` of the app, we have a database storing fluid prices evolution since 2012 for the following fluids :

- Electricity
- Gas

Before this version, the app was applying a hard coded price for each fluid without taking care of the time period. Now, there is a service that processes fresh data in order to apply the current price to this data, but also apply the most relevant price for a fluid doctype.

## Service

### Process

The Cozy service responsible for price calculation is `fluidsPrices`. You can find the full logic in the following diagram :

```plantuml
@startuml
scale 0.8
start
repeat :Select Price (Elec, gas);
:Apply Prices on selected price;

if (There is prices in database) then (true)
  :Get oldest data without price;
  if (There is a doctype without price) then (Process price)
    :Take founded date as time reference;
      if (FluidType is elec) then (true)
        repeat
        :Get half-hour data by day (48 elements);
        :Get price for the period;
        :Apply price on each element;
        :Save all elements;
        :Increment date by one day;
        repeat while (Date is not today)
      else (false)
      endif
      repeat
      :Get daily data by month (max 31 elements);
      :Get price for the period;
      :Apply price on each element;
      :Save all elements;
      :Increment date by one month;
      repeat while (Date is not in current month)
      :Start aggregation for month and year;
      repeat
      :Get daily data by month (max 31 elements);
      :Get monthly data without price (1 element);
      :Sum prices for all daily elements;
      :Add price on monthly data doc;
      :Save monthly element;
      :Increment date by one month;
      repeat while (Date is not in current month)
      repeat
      :Get monthly data by year (max 12 elements);
      :Get yearly data without price (1 element);
      :Sum prices for all monthly elements;
      :Add price on yearly data doc;
      :Save yearly element;
      :Increment date by one year;
      repeat while (Date is not in current year)
  else (Stop service)
    :Log error and stop process;
    end
  endif
else (Stop service)
  :Log error and stop process;
  end
endif


repeat while (All fluid are not processed)

stop



@enduml
```

This service is running every night at 02:00 AM and during splash screen.

:::warning

You might observe some price miscalculation because the service is triggered asynchronously during splash root, but because of the default price in `constants/config.json`, the user should not see a big difference.

:::

### Init

A migration job has been setup to init the database with json data store inside the app. This job should be run once and will init electricity and gas prices.

### New price

In case of price update the following procedure must be done :

- Create a migration for adding new prices
- Update hard coded price inside app in order to maintain fallback calculation
- Verify full service calculation with new data
- Verify calculation with existing data

:::warning
The service does not handle change during a month because the case does not exist anymore for Enedis and Grdf.
:::

### Prices Data

We store in database a collection of prices with the following info :

- StartDate
- EndDate
- fluidType
- Price

The EndDate is set to null if it's the current fluid price.

## App Price display

The app can handle the new price calculation and also keep the old calculation system.

### Regular display

If there is a price on the doctype we want to process, it will be use for display and calculation ( see analysis functionality).

### Fallback

The app take the hard code price for a given fluid and apply it to a load. This allow the app to handle prices in any case.

### How to test service ?

In a shell run a build and test service with le following command line :

```bash
yarn build-dev:browser; yarn run cozy-konnector-dev -m .\manifest.webapp .\build\services\monthlyReport\ecolyo.js
```

### Future Changes

We might consider a more dynamic process for fallback price calculation in the future:

- Get last price for a given price in database
- Use it to calculate value instead of the hard coded one
- Use it in all info pop-in for user information