extract frontend analytics helpers
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m12s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m12s
This commit is contained in:
117
src/analytics/products.ts
Normal file
117
src/analytics/products.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import type { DateRange, OrderData, StockData } from '../types';
|
||||
import { getBaseProductName, getOrderItemRevenue, isOrderInDateRange } from './orders';
|
||||
|
||||
export interface ProductSummary {
|
||||
id: string;
|
||||
name: string;
|
||||
totalSold: number;
|
||||
revenue: number;
|
||||
lastPrice: number;
|
||||
stock: number;
|
||||
}
|
||||
|
||||
export interface ProductDetailsMetrics {
|
||||
productInfo: {
|
||||
id: string;
|
||||
name: string;
|
||||
price: number;
|
||||
} | null;
|
||||
chartData: Array<{
|
||||
date: string;
|
||||
value: number;
|
||||
}>;
|
||||
totalSold: number;
|
||||
totalRevenue: number;
|
||||
}
|
||||
|
||||
export const buildProductsSummary = (
|
||||
ordersData: OrderData[],
|
||||
stockData: StockData[],
|
||||
dateRange: DateRange,
|
||||
searchTerm: string
|
||||
): ProductSummary[] => {
|
||||
const productMap: Record<string, ProductSummary> = {};
|
||||
|
||||
stockData.forEach(item => {
|
||||
productMap[item.produto_id] = {
|
||||
id: item.produto_id,
|
||||
name: item.nome,
|
||||
totalSold: 0,
|
||||
revenue: 0,
|
||||
lastPrice: 0,
|
||||
stock: item.saldo || 0
|
||||
};
|
||||
});
|
||||
|
||||
ordersData.forEach(order => {
|
||||
if (!isOrderInDateRange(order, dateRange)) return;
|
||||
|
||||
if (!productMap[order.ID_Produto]) {
|
||||
productMap[order.ID_Produto] = {
|
||||
id: order.ID_Produto,
|
||||
name: getBaseProductName(order.Descricao_Produto),
|
||||
totalSold: 0,
|
||||
revenue: 0,
|
||||
lastPrice: order.Valor_Unitario,
|
||||
stock: 0
|
||||
};
|
||||
}
|
||||
|
||||
if (productMap[order.ID_Produto].name === 'Unknown' || !productMap[order.ID_Produto].name) {
|
||||
productMap[order.ID_Produto].name = getBaseProductName(order.Descricao_Produto);
|
||||
}
|
||||
|
||||
productMap[order.ID_Produto].totalSold += order.Quantidade;
|
||||
productMap[order.ID_Produto].revenue += getOrderItemRevenue(order);
|
||||
productMap[order.ID_Produto].lastPrice = order.Valor_Unitario;
|
||||
});
|
||||
|
||||
const normalizedSearch = searchTerm.trim().toLowerCase();
|
||||
const products = Object.values(productMap);
|
||||
const filteredProducts = normalizedSearch
|
||||
? products.filter(product => product.name.toLowerCase().includes(normalizedSearch) || product.id.includes(searchTerm))
|
||||
: products;
|
||||
|
||||
return filteredProducts.sort((a, b) => b.totalSold - a.totalSold);
|
||||
};
|
||||
|
||||
export const buildProductDetailsMetrics = (
|
||||
ordersData: OrderData[],
|
||||
productId: string | undefined,
|
||||
dateRange: DateRange
|
||||
): ProductDetailsMetrics => {
|
||||
const productOrders = ordersData.filter(order => order.ID_Produto === productId);
|
||||
|
||||
if (productOrders.length === 0) {
|
||||
return { productInfo: null, chartData: [], totalSold: 0, totalRevenue: 0 };
|
||||
}
|
||||
|
||||
const productInfo = {
|
||||
id: productOrders[0].ID_Produto,
|
||||
name: getBaseProductName(productOrders[0].Descricao_Produto),
|
||||
price: productOrders[0].Valor_Unitario
|
||||
};
|
||||
|
||||
const salesByDate: Record<string, number> = {};
|
||||
let totalSold = 0;
|
||||
let totalRevenue = 0;
|
||||
|
||||
productOrders.forEach(order => {
|
||||
if (!isOrderInDateRange(order, dateRange)) return;
|
||||
|
||||
salesByDate[order.Data_Pedido] = (salesByDate[order.Data_Pedido] || 0) + order.Quantidade;
|
||||
totalSold += order.Quantidade;
|
||||
totalRevenue += getOrderItemRevenue(order);
|
||||
});
|
||||
|
||||
const chartData = Object.keys(salesByDate).map(date => ({
|
||||
date,
|
||||
value: salesByDate[date]
|
||||
})).sort((a, b) => {
|
||||
const [da, ma, ya] = a.date.split('-').map(Number);
|
||||
const [db, mb, yb] = b.date.split('-').map(Number);
|
||||
return new Date(ya, ma - 1, da).getTime() - new Date(yb, mb - 1, db).getTime();
|
||||
});
|
||||
|
||||
return { productInfo, chartData, totalSold, totalRevenue };
|
||||
};
|
||||
Reference in New Issue
Block a user