diff --git a/src/lib/features/traffic-data-usage/fake-traffic-data-usage-store.ts b/src/lib/features/traffic-data-usage/fake-traffic-data-usage-store.ts index fa2262f7f7..4fd4606a78 100644 --- a/src/lib/features/traffic-data-usage/fake-traffic-data-usage-store.ts +++ b/src/lib/features/traffic-data-usage/fake-traffic-data-usage-store.ts @@ -6,9 +6,11 @@ import type { import type { ITrafficDataUsageStore } from '../../types'; import { differenceInCalendarMonths, + endOfDay, format, isSameMonth, parse, + startOfDay, } from 'date-fns'; export class FakeTrafficDataUsageStore implements ITrafficDataUsageStore { @@ -89,4 +91,45 @@ export class FakeTrafficDataUsageStore implements ITrafficDataUsageStore { return Object.values(data); } + + async getDailyTrafficUsageDataForPeriod( + from: Date, + to: Date, + ): Promise { + return this.trafficData.filter( + (data) => data.day >= startOfDay(from) && data.day <= endOfDay(to), + ); + } + + async getMonthlyTrafficUsageDataForPeriod( + from: Date, + to: Date, + ): Promise { + const data: { [key: string]: IStatMonthlyTrafficUsage } = + this.trafficData + .filter( + (data) => + data.day >= startOfDay(from) && + data.day <= endOfDay(to), + ) + .reduce((acc, entry) => { + const month = format(entry.day, 'yyyy-MM'); + const key = `${month}-${entry.trafficGroup}-${entry.statusCodeSeries}`; + + if (acc[key]) { + acc[key].count += entry.count; + } else { + acc[key] = { + month, + trafficGroup: entry.trafficGroup, + statusCodeSeries: entry.statusCodeSeries, + count: entry.count, + }; + } + + return acc; + }, {}); + + return Object.values(data); + } } diff --git a/src/lib/features/traffic-data-usage/traffic-data-usage-store-type.ts b/src/lib/features/traffic-data-usage/traffic-data-usage-store-type.ts index d24711c756..b695c9c771 100644 --- a/src/lib/features/traffic-data-usage/traffic-data-usage-store-type.ts +++ b/src/lib/features/traffic-data-usage/traffic-data-usage-store-type.ts @@ -27,4 +27,12 @@ export interface ITrafficDataUsageStore getTrafficDataForMonthRange( monthsBack: number, ): Promise; + getDailyTrafficUsageDataForPeriod( + from: Date, + to: Date, + ): Promise; + getMonthlyTrafficUsageDataForPeriod( + from: Date, + to: Date, + ): Promise; } diff --git a/src/lib/features/traffic-data-usage/traffic-data-usage-store.ts b/src/lib/features/traffic-data-usage/traffic-data-usage-store.ts index ba686ea867..c32f3bdf99 100644 --- a/src/lib/features/traffic-data-usage/traffic-data-usage-store.ts +++ b/src/lib/features/traffic-data-usage/traffic-data-usage-store.ts @@ -1,3 +1,10 @@ +import { + endOfDay, + endOfMonth, + startOfDay, + startOfMonth, + subMonths, +} from 'date-fns'; import type { Db } from '../../db/db'; import type { Logger, LogProvider } from '../../logger'; import type { @@ -89,18 +96,20 @@ export class TrafficDataUsageStore implements ITrafficDataUsageStore { }); } - async getTrafficDataUsageForPeriod( - period: string, + async getDailyTrafficUsageDataForPeriod( + from: Date, + to: Date, ): Promise { - const rows = await this.db(TABLE).whereRaw( - `to_char(day, 'YYYY-MM') = ?`, - [period], - ); + const rows = await this.db(TABLE) + .where('day', '>=', startOfDay(from)) + .andWhere('day', '<=', endOfDay(to)); + return rows.map(mapRow); } - async getTrafficDataForMonthRange( - monthsBack: number, + async getMonthlyTrafficUsageDataForPeriod( + from: Date, + to: Date, ): Promise { const rows = await this.db(TABLE) .select( @@ -109,10 +118,8 @@ export class TrafficDataUsageStore implements ITrafficDataUsageStore { this.db.raw(`to_char(day, 'YYYY-MM') AS month`), this.db.raw(`SUM(count) AS count`), ) - .whereRaw( - `day >= date_trunc('month', CURRENT_DATE) - make_interval(months := ?)`, - [monthsBack], - ) + .where('day', '>=', startOfDay(from)) + .andWhere('day', '<=', endOfDay(to)) .groupBy([ 'traffic_group', this.db.raw(`to_char(day, 'YYYY-MM')`), @@ -131,4 +138,23 @@ export class TrafficDataUsageStore implements ITrafficDataUsageStore { }), ); } + + async getTrafficDataUsageForPeriod( + period: string, + ): Promise { + const month = new Date(period); + return this.getDailyTrafficUsageDataForPeriod( + startOfMonth(month), + endOfMonth(month), + ); + } + + // @deprecated: remove with flag `dataUsageMultiMonthView` + async getTrafficDataForMonthRange( + monthsBack: number, + ): Promise { + const to = endOfMonth(new Date()); + const from = startOfMonth(subMonths(to, monthsBack)); + return this.getMonthlyTrafficUsageDataForPeriod(from, to); + } }