import { createSelector } from 'reselect'; import { filter } from 'lodash'; import { BENCHMARK_MODE_YEAR } from './earnings.constants'; import { getAggregationChartLabel, YEARLY } from 'app/shared/services/aggregationPeriods/aggregationPeriods.service'; import datePipe from 'app/shared/pipes/date.pipe'; import moneyPipe from 'app/shared/pipes/money.pipe'; import { selectCurrentAggregation, selectTceAggregations, selectTceBenchmarkMode, selectTcePagination, } from './earnings.selectors'; import { Benchmark, BenchmarkMode, TceAggregation } from './earnings.types'; import { getAccessorFor } from 'app/shared/modules/chart/core/common'; import { selectFilters } from '../../../shared/store/filters/filters.selectors'; import { FiltersPeriodId } from '../../../shared/store/filters/filters.types'; const returnPageData = (data: TceAggregation[], currentPage: number, numberPerPage: number) => { const length = data.length; const end = length - currentPage; const begin = end - numberPerPage; if (length < numberPerPage) { return data; } return data.slice(begin, end); }; const reduceAggregationMaxValue = (previousMax: number, aggregation: TceAggregation) => { const benchmarkSpot = aggregation.benchmark.spot; const benchmarkYear = aggregation.benchmark.year; return Math.max(previousMax, benchmarkSpot, benchmarkYear, aggregation.commercial); }; const getSubLabel = (aggregation: TceAggregation, aggregationPeriod: FiltersPeriodId) => { if (aggregationPeriod === YEARLY) { return null; } const date = new Date(aggregation.date); return (date.getMonth() === 0) ? date.getFullYear().toString() : null; }; const createBarData = (aggregationPeriodId: FiltersPeriodId, benchmarkMode: BenchmarkMode, getBenchmarkValue: (data: Benchmark) => number) => { return (aggregation: TceAggregation) => { const label = getAggregationChartLabel(new Date(aggregation.date), aggregationPeriodId); const subLabel = getSubLabel(aggregation, aggregationPeriodId); const year = datePipe.formatOnlyYear(aggregation.date); return { id: aggregation.id, date: aggregation.date, label: label, subLabel: subLabel, value: aggregation.commercial, popover: { tce: moneyPipe.format(aggregation.commercial), title: label + (year !== label ? ' ' + year : ''), benchmark: moneyPipe.format(getBenchmarkValue(aggregation.benchmark)), mode: benchmarkMode === BENCHMARK_MODE_YEAR ? '1 Year TC' : 'Global Spot', }, }; }; }; export const selectTceChartData = createSelector( [ selectTcePagination, selectTceAggregations, selectTceBenchmarkMode, selectFilters, selectCurrentAggregation ], (pagination, tceAggregations, benchmarkMode, filters, selectedAggregation) => { const currentPage = pagination.currentPage; const numberPerPage = pagination.numberPerPage; const aggregations = returnPageData(tceAggregations, currentPage, numberPerPage); const getBenchmarkValue = getAccessorFor(benchmarkMode); const maxValue = tceAggregations.reduce(reduceAggregationMaxValue, 0) * 1.1; const barSeries = aggregations.map(createBarData(filters.aggregationPeriodId, benchmarkMode, getBenchmarkValue)); const benchmarkDisabled = filter(tceAggregations, (aggregation) => aggregation.benchmark).length === 0; const linesSeries = benchmarkDisabled ? [] : [ { id: 'Benchmark', items: aggregations.map((aggregation) => { const label = getAggregationChartLabel(new Date(aggregation.date), filters.aggregationPeriodId); const year = datePipe.formatOnlyYear(aggregation.date); return { id: aggregation.id, date: aggregation.date, benchmarkMode: benchmarkMode, label: label, value: getBenchmarkValue(aggregation.benchmark), popover: { tce: moneyPipe.format(aggregation.commercial), title: label + (year !== label ? ' ' + year : ''), benchmark: moneyPipe.format(getBenchmarkValue(aggregation.benchmark)), mode: benchmarkMode === BENCHMARK_MODE_YEAR ? '1 Year TC' : 'Global Spot', }, }; }), }, ]; return { maxValue: maxValue, selectedId: selectedAggregation, barSeries: barSeries, linesSeries: linesSeries, currentPage: pagination.currentPage, }; } ); export const selectTceChartVisibility = createSelector( selectTcePagination, pagination => { const currentPage = pagination.currentPage; const numberOfPages = pagination.numberOfPages; return { isPreviousVisible: currentPage > 0, isNextVisible: currentPage < numberOfPages - 1, }; } );