From e1f12539d3f6c0fb4d6a423ec30bbe6f239fdee6 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 4 Jan 2025 00:15:29 -0500 Subject: [PATCH] Fix revenue projection calc for 12-1am --- .../klaviyo-server/services/events.service.js | 52 ++++++++++++++++--- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/dashboard-server/klaviyo-server/services/events.service.js b/dashboard-server/klaviyo-server/services/events.service.js index 19142d5..003e694 100644 --- a/dashboard-server/klaviyo-server/services/events.service.js +++ b/dashboard-server/klaviyo-server/services/events.service.js @@ -2112,21 +2112,43 @@ export class EventsService { const currentHour = now.hour; const currentMinute = now.minute; + // Handle the 12-1 AM edge case + const isInEdgeCase = currentHour < this.timeManager.dayStartHour; + const adjustedCurrentHour = isInEdgeCase ? currentHour + 24 : currentHour; + const adjustedDayStartHour = this.timeManager.dayStartHour; + // Calculate how much of the current hour has passed (0-1) const hourProgress = currentMinute / 60; // Calculate how much of the expected daily revenue we've seen so far let expectedPercentageSeen = 0; - for (let i = 0; i < currentHour; i++) { - expectedPercentageSeen += hourlyPatterns[i].percentage; + let totalDayPercentage = 0; + + // First, calculate total percentage for a full day + for (let i = 0; i < 24; i++) { + totalDayPercentage += hourlyPatterns[i].percentage; + } + + if (isInEdgeCase) { + // If we're between 12-1 AM, we want to use almost the full day's percentage + // since we're at the end of the previous day + expectedPercentageSeen = totalDayPercentage; + // Subtract the remaining portion of the current hour + expectedPercentageSeen -= hourlyPatterns[currentHour].percentage * (1 - hourProgress); + } else { + // Normal case - add up percentages from day start to current hour + for (let i = adjustedDayStartHour; i < adjustedCurrentHour; i++) { + const hourIndex = i % 24; + expectedPercentageSeen += hourlyPatterns[hourIndex].percentage; + } + // Add partial current hour + expectedPercentageSeen += hourlyPatterns[currentHour].percentage * hourProgress; } - // Add partial current hour - expectedPercentageSeen += hourlyPatterns[currentHour].percentage * hourProgress; // Calculate projection based on patterns let projectedRevenue = 0; if (expectedPercentageSeen > 0) { - projectedRevenue = (currentRevenue / (expectedPercentageSeen / 100)); + projectedRevenue = (currentRevenue / (expectedPercentageSeen / totalDayPercentage)); } // Calculate confidence score (0-1) based on: @@ -2134,8 +2156,19 @@ export class EventsService { // 2. How consistent the patterns are // 3. How far through the period we are const patternConsistency = this._calculatePatternConsistency(hourlyPatterns); - const periodProgress = Math.min(100, Math.max(0, (now.diff(periodStart).milliseconds / periodEnd.diff(periodStart).milliseconds) * 100)); - const historicalDataAmount = Math.min(totalHistoricalOrders / 1000, 1); // Normalize to 0-1, considering 1000+ orders as maximum confidence + + // Calculate period progress considering the 1 AM day start + const totalDuration = periodEnd.diff(periodStart); + const elapsedDuration = now.diff(periodStart); + let periodProgress = Math.min(100, Math.max(0, (elapsedDuration.milliseconds / totalDuration.milliseconds) * 100)); + + // Adjust period progress for the 12-1 AM edge case + if (isInEdgeCase) { + // If we're between 12-1 AM, we're actually at the end of the previous day + periodProgress = Math.min(100, Math.max(0, ((24 - adjustedDayStartHour + currentHour) / 24) * 100)); + } + + const historicalDataAmount = Math.min(totalHistoricalOrders / 1000, 1); const confidence = ( (patternConsistency * 0.4) + @@ -2154,8 +2187,11 @@ export class EventsService { historicalOrders: totalHistoricalOrders, hourlyPatterns, expectedPercentageSeen, + totalDayPercentage, currentHour, - currentMinute + currentMinute, + isInEdgeCase, + adjustedCurrentHour } }; } catch (error) {