Misc half fixes

This commit is contained in:
2024-12-21 11:00:13 -05:00
parent bf2d0f0711
commit c6467087c1
3 changed files with 129 additions and 22 deletions

View File

@@ -1415,6 +1415,7 @@ export class EventsService {
async calculateDetailedStats(params = {}) {
try {
const { metric, daily = false } = params;
console.log('[EventsService] Request params:', params);
// Get period dates
let periodStart, periodEnd, prevPeriodStart, prevPeriodEnd;
@@ -1425,20 +1426,64 @@ export class EventsService {
prevPeriodEnd = periodStart.minus({ milliseconds: 1 });
prevPeriodStart = prevPeriodEnd.minus(duration);
} else if (params.timeRange) {
// Normalize time range to use 'last' prefix instead of 'previous'
const normalizedTimeRange = params.timeRange.replace('previous', 'last');
// Handle both current and previous period time ranges
const timeRange = params.timeRange;
const isPreviousPeriod = timeRange.startsWith('previous');
const normalizedTimeRange = isPreviousPeriod ? timeRange.replace('previous', 'last') : timeRange;
console.log('[EventsService] Time range details:', {
originalTimeRange: timeRange,
isPreviousPeriod,
normalizedTimeRange
});
// Get current period range
const range = this.timeManager.getDateRange(normalizedTimeRange);
const prevRange = this.timeManager.getPreviousPeriod(normalizedTimeRange);
if (!range || !prevRange) {
throw new Error('Invalid time range specified');
if (!range) {
throw new Error(`Invalid time range specified: ${timeRange}`);
}
// Get previous period range using TimeManager
const prevRange = this.timeManager.getPreviousPeriod(normalizedTimeRange);
if (!prevRange) {
throw new Error(`Could not calculate previous period for: ${timeRange}`);
}
periodStart = range.start;
periodEnd = range.end;
prevPeriodStart = prevRange.start;
prevPeriodEnd = prevRange.end;
console.log('[EventsService] Calculated date ranges:', {
timeRange,
current: {
start: periodStart.toISO(),
end: periodEnd.toISO(),
duration: periodEnd.diff(periodStart).as('days')
},
previous: {
start: prevPeriodStart.toISO(),
end: prevPeriodEnd.toISO(),
duration: prevPeriodEnd.diff(prevPeriodStart).as('days')
}
});
}
// Load both current and previous period data
console.log('[EventsService] Fetching events with params:', {
current: {
startDate: periodStart.toISO(),
endDate: periodEnd.toISO(),
metricId: METRIC_IDS.PLACED_ORDER,
...params
},
previous: {
startDate: prevPeriodStart.toISO(),
endDate: prevPeriodEnd.toISO(),
metricId: METRIC_IDS.PLACED_ORDER
}
});
const [currentResponse, prevResponse] = await Promise.all([
this.getEvents({
...params,
@@ -1457,6 +1502,17 @@ export class EventsService {
const currentEvents = this._transformEvents(currentResponse.data || []);
const prevEvents = this._transformEvents(prevResponse.data || []);
console.log('[EventsService] Transformed events:', {
current: {
count: currentEvents.length,
revenue: currentEvents.reduce((sum, event) => sum + (Number(event.event_properties?.TotalAmount) || 0), 0)
},
previous: {
count: prevEvents.length,
revenue: prevEvents.reduce((sum, event) => sum + (Number(event.event_properties?.TotalAmount) || 0), 0)
}
});
// Initialize daily stats map with all dates in range
const dailyStats = new Map();
let currentDate = periodStart;
@@ -1472,6 +1528,7 @@ export class EventsService {
averageItemsPerOrder: 0,
prevRevenue: 0,
prevOrders: 0,
prevItemCount: 0,
prevAvgOrderValue: 0
});
currentDate = currentDate.plus({ days: 1 });
@@ -1497,31 +1554,78 @@ export class EventsService {
dayStats.averageItemsPerOrder = dayStats.itemCount / dayStats.orders;
}
// Process previous period events and map them to corresponding current period dates
const daysDiff = periodEnd.diff(periodStart, 'days').days;
// Process previous period events
const prevDailyStats = new Map();
let prevDate = prevPeriodStart;
while (prevDate <= prevPeriodEnd) {
const dateKey = prevDate.toFormat('yyyy-MM-dd');
prevDailyStats.set(dateKey, {
date: prevDate.toISO(),
revenue: 0,
orders: 0,
itemCount: 0
});
prevDate = prevDate.plus({ days: 1 });
}
// Aggregate previous period data
for (const event of prevEvents) {
const datetime = this.timeManager.toDateTime(event.attributes?.datetime);
if (!datetime) continue;
// Calculate the corresponding date in the current period
const daysFromStart = datetime.diff(prevPeriodStart, 'days').days;
const correspondingDate = periodStart.plus({ days: daysFromStart });
const dateKey = correspondingDate.toFormat('yyyy-MM-dd');
const dateKey = datetime.toFormat('yyyy-MM-dd');
if (!prevDailyStats.has(dateKey)) continue;
if (!dailyStats.has(dateKey)) continue;
const dayStats = dailyStats.get(dateKey);
const dayStats = prevDailyStats.get(dateKey);
const props = event.event_properties || {};
const totalAmount = Number(props.TotalAmount || 0);
const items = props.Items || [];
dayStats.prevRevenue += totalAmount;
dayStats.prevOrders++;
dayStats.prevAvgOrderValue = dayStats.prevRevenue / dayStats.prevOrders;
dayStats.revenue += totalAmount;
dayStats.orders++;
dayStats.itemCount += items.length;
}
// Map previous period data to current period days based on relative position
const prevPeriodDays = Array.from(prevDailyStats.values());
const currentPeriodDays = Array.from(dailyStats.values());
const daysInPeriod = currentPeriodDays.length;
for (let i = 0; i < daysInPeriod; i++) {
const currentDayStats = currentPeriodDays[i];
const prevDayStats = prevPeriodDays[i];
if (prevDayStats) {
const dayStats = dailyStats.get(currentDayStats.timestamp);
dayStats.prevRevenue = prevDayStats.revenue;
dayStats.prevOrders = prevDayStats.orders;
dayStats.prevItemCount = prevDayStats.itemCount;
dayStats.prevAvgOrderValue = prevDayStats.orders > 0 ? prevDayStats.revenue / prevDayStats.orders : 0;
}
}
// Log the final daily stats before returning
console.log('[EventsService] Final daily stats sample:', {
totalDays: dailyStats.size,
firstDay: Array.from(dailyStats.values())[0],
lastDay: Array.from(dailyStats.values())[dailyStats.size - 1]
});
// Convert to array and sort by date
const stats = Array.from(dailyStats.values())
.sort((a, b) => a.date.localeCompare(b.date));
.sort((a, b) => a.date.localeCompare(b.date))
.map(day => ({
...day,
revenue: Number(day.revenue || 0),
orders: Number(day.orders || 0),
itemCount: Number(day.itemCount || 0),
averageOrderValue: Number(day.averageOrderValue || 0),
averageItemsPerOrder: Number(day.averageItemsPerOrder || 0),
prevRevenue: Number(day.prevRevenue || 0),
prevOrders: Number(day.prevOrders || 0),
prevItemCount: Number(day.prevItemCount || 0),
prevAvgOrderValue: Number(day.prevAvgOrderValue || 0)
}));
return stats;
} catch (error) {

View File

@@ -153,7 +153,10 @@ export class TimeManager {
getDateRange(period) {
const now = this.getNow();
switch (period) {
// Normalize period to handle both 'last' and 'previous' prefixes
const normalizedPeriod = period.startsWith('previous') ? period.replace('previous', 'last') : period;
switch (normalizedPeriod) {
case 'custom': {
// Custom ranges are handled separately via getCustomRange
console.warn('[TimeManager] Custom ranges should use getCustomRange method');