Add hourly seller chart for single-day ranges
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m35s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m35s
This commit is contained in:
@@ -498,7 +498,7 @@ const buildRfmClients = (baseClients) => {
|
||||
|
||||
const getDashboardAnalytics = async (range = {}) => {
|
||||
const { params, whereClause } = buildDateFilter(range);
|
||||
const [totalsResult, salesResult, revenueResult, sellerRevenueResult, sellerOrdersResult, sellerRevenueByDateResult] = await Promise.all([
|
||||
const [totalsResult, salesResult, revenueResult, sellerRevenueResult, sellerOrdersResult, sellerRevenueByDateResult, sellerRevenueByHourResult] = await Promise.all([
|
||||
pool.query(`
|
||||
SELECT
|
||||
COALESCE(SUM(quantidade * valor_unitario), 0) as total_revenue,
|
||||
@@ -605,6 +605,39 @@ const getDashboardAnalytics = async (range = {}) => {
|
||||
INNER JOIN top_sellers ON top_sellers.seller_key = seller_orders.seller_key
|
||||
GROUP BY seller_orders.seller_key, seller_orders.data_pedido_date
|
||||
ORDER BY seller_orders.data_pedido_date ASC, value DESC;
|
||||
`, params),
|
||||
pool.query(`
|
||||
WITH seller_orders AS (
|
||||
SELECT
|
||||
COALESCE(${SELLER_ID_SQL}, 'name:' || ${SELLER_NAME_SQL}) as seller_key,
|
||||
COALESCE(${SELLER_NAME_SQL}, ${SELLER_ID_SQL}, 'Sem vendedor') as seller_name,
|
||||
EXTRACT(HOUR FROM created_at AT TIME ZONE 'America/Sao_Paulo')::int as order_hour,
|
||||
quantidade,
|
||||
valor_unitario,
|
||||
pedido_id,
|
||||
data_pedido,
|
||||
valor_pedido
|
||||
FROM orders
|
||||
${whereClause}
|
||||
AND (${SELLER_ID_SQL} IS NOT NULL OR ${SELLER_NAME_SQL} IS NOT NULL)
|
||||
),
|
||||
top_sellers AS (
|
||||
SELECT seller_key
|
||||
FROM seller_orders
|
||||
GROUP BY seller_key
|
||||
ORDER BY COALESCE(SUM(quantidade * valor_unitario), 0) DESC
|
||||
LIMIT 8
|
||||
)
|
||||
SELECT
|
||||
seller_orders.seller_key as id,
|
||||
MAX(seller_orders.seller_name) as name,
|
||||
seller_orders.order_hour as hour,
|
||||
COALESCE(SUM(seller_orders.quantidade * seller_orders.valor_unitario), 0) as value,
|
||||
COUNT(DISTINCT COALESCE(NULLIF(seller_orders.pedido_id, ''), seller_orders.data_pedido || '_' || seller_orders.valor_pedido::text))::int as orders
|
||||
FROM seller_orders
|
||||
INNER JOIN top_sellers ON top_sellers.seller_key = seller_orders.seller_key
|
||||
GROUP BY seller_orders.seller_key, seller_orders.order_hour
|
||||
ORDER BY seller_orders.order_hour ASC, value DESC;
|
||||
`, params)
|
||||
]);
|
||||
|
||||
@@ -647,6 +680,13 @@ const getDashboardAnalytics = async (range = {}) => {
|
||||
date: row.date,
|
||||
value: toNumber(row.value),
|
||||
orders: toNumber(row.orders)
|
||||
})),
|
||||
sellerRevenueByHour: sellerRevenueByHourResult.rows.map(row => ({
|
||||
name: row.name,
|
||||
id: row.id,
|
||||
hour: toNumber(row.hour),
|
||||
value: toNumber(row.value),
|
||||
orders: toNumber(row.orders)
|
||||
}))
|
||||
};
|
||||
};
|
||||
|
||||
@@ -159,6 +159,12 @@ test('getDashboardAnalytics includes seller revenue and order metrics', async ()
|
||||
};
|
||||
}
|
||||
|
||||
if (sql.includes('order_hour')) {
|
||||
return {
|
||||
rows: [{ id: '977226210', name: 'KEDMA DA SILVA', hour: 14, value: 300, orders: 1 }]
|
||||
};
|
||||
}
|
||||
|
||||
if (sql.includes('seller_orders') && sql.includes('SUM(quantidade * valor_unitario)')) {
|
||||
return {
|
||||
rows: [{ id: '977226210', name: 'KEDMA DA SILVA', value: 750 }]
|
||||
@@ -187,7 +193,7 @@ test('getDashboardAnalytics includes seller revenue and order metrics', async ()
|
||||
const sellerRevenueQuery = calls.find(call => call.sql.includes('seller_orders') && call.sql.includes('SUM(quantidade * valor_unitario)'));
|
||||
const sellerOrdersQuery = calls.find(call => call.sql.includes('seller_orders') && call.sql.includes('COUNT(DISTINCT'));
|
||||
|
||||
assert.equal(calls.length, 6);
|
||||
assert.equal(calls.length, 7);
|
||||
calls.forEach(call => {
|
||||
assert.deepEqual(call.params, ['2026-06-01', '2026-06-24']);
|
||||
});
|
||||
@@ -203,6 +209,9 @@ test('getDashboardAnalytics includes seller revenue and order metrics', async ()
|
||||
assert.deepEqual(dashboard.sellerRevenueByDate, [
|
||||
{ id: '977226210', name: 'KEDMA DA SILVA', date: '2026-06-05', value: 400, orders: 2 }
|
||||
]);
|
||||
assert.deepEqual(dashboard.sellerRevenueByHour, [
|
||||
{ id: '977226210', name: 'KEDMA DA SILVA', hour: 14, value: 300, orders: 1 }
|
||||
]);
|
||||
} finally {
|
||||
pool.query = originalQuery;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user