Compare commits
2 Commits
main
...
560c089639
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
560c089639 | ||
|
|
ebc1d7c5ef |
@@ -89,7 +89,8 @@ const formatRow = (row) => ({
|
|||||||
Quantidade: row.quantidade,
|
Quantidade: row.quantidade,
|
||||||
Valor_Unitario: parseFloat(row.valor_unitario),
|
Valor_Unitario: parseFloat(row.valor_unitario),
|
||||||
Recebido_Em: row.created_at,
|
Recebido_Em: row.created_at,
|
||||||
ID_Pedido: row.pedido_id
|
ID_Pedido: row.pedido_id,
|
||||||
|
Fone_Cliente: row.cliente_fone
|
||||||
});
|
});
|
||||||
|
|
||||||
// GET data (for the frontend)
|
// GET data (for the frontend)
|
||||||
@@ -132,13 +133,24 @@ app.post('/api/data', authenticateAPIKey, async (req, res) => {
|
|||||||
const insertQuery = `
|
const insertQuery = `
|
||||||
INSERT INTO orders (
|
INSERT INTO orders (
|
||||||
cliente_nome, data_pedido, valor_pedido,
|
cliente_nome, data_pedido, valor_pedido,
|
||||||
produto_id, produto_descricao, quantidade, valor_unitario, pedido_id
|
produto_id, produto_descricao, quantidade, valor_unitario, pedido_id, cliente_fone
|
||||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
||||||
|
ON CONFLICT (pedido_id, produto_id) DO UPDATE SET
|
||||||
|
cliente_nome = EXCLUDED.cliente_nome,
|
||||||
|
data_pedido = EXCLUDED.data_pedido,
|
||||||
|
valor_pedido = EXCLUDED.valor_pedido,
|
||||||
|
produto_descricao = EXCLUDED.produto_descricao,
|
||||||
|
quantidade = EXCLUDED.quantidade,
|
||||||
|
valor_unitario = EXCLUDED.valor_unitario,
|
||||||
|
cliente_fone = EXCLUDED.cliente_fone,
|
||||||
|
created_at = CURRENT_TIMESTAMP
|
||||||
`;
|
`;
|
||||||
|
|
||||||
for (const item of payload) {
|
for (const item of payload) {
|
||||||
// Handle potential missing fields gracefully
|
// Handle potential missing fields gracefully
|
||||||
const orderId = item.id || item.ID_Pedido || (item.json && item.json.body && item.json.body.id) || '';
|
const fallbackId = `${item.Nome_Cliente}_${item.Data_Pedido}_${item.Valor_Pedido}`;
|
||||||
|
const orderId = item.id || item.ID_Pedido || (item.json && item.json.body && item.json.body.id) || fallbackId;
|
||||||
|
const fone = item.Fone_Cliente || item.fone || item.celular || '';
|
||||||
|
|
||||||
const values = [
|
const values = [
|
||||||
item.Nome_Cliente || 'Unknown',
|
item.Nome_Cliente || 'Unknown',
|
||||||
@@ -148,7 +160,8 @@ app.post('/api/data', authenticateAPIKey, async (req, res) => {
|
|||||||
item.Descricao_Produto || '',
|
item.Descricao_Produto || '',
|
||||||
parseInt(item.Quantidade) || 0,
|
parseInt(item.Quantidade) || 0,
|
||||||
parseFloat(item.Valor_Unitario) || 0,
|
parseFloat(item.Valor_Unitario) || 0,
|
||||||
String(orderId)
|
String(orderId),
|
||||||
|
String(fone)
|
||||||
];
|
];
|
||||||
await client.query(insertQuery, values);
|
await client.query(insertQuery, values);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,13 +31,17 @@ const Clients = () => {
|
|||||||
return orderDate >= dateRange.start && orderDate <= dateRange.end;
|
return orderDate >= dateRange.start && orderDate <= dateRange.end;
|
||||||
});
|
});
|
||||||
|
|
||||||
const clientMap: Record<string, { totalSpent: number, totalItems: number, uniqueOrders: Set<string>, lastPurchase: number }> = {};
|
const clientMap: Record<string, { totalSpent: number, totalItems: number, uniqueOrders: Set<string>, lastPurchase: number, phone: string }> = {};
|
||||||
|
|
||||||
orders.forEach(order => {
|
orders.forEach(order => {
|
||||||
const clientName = order.Nome_Cliente || `Cliente Desconhecido (Pedido ${order.Valor_Pedido})`;
|
const clientName = order.Nome_Cliente || `Cliente Desconhecido (Pedido ${order.Valor_Pedido})`;
|
||||||
|
|
||||||
if (!clientMap[clientName]) {
|
if (!clientMap[clientName]) {
|
||||||
clientMap[clientName] = { totalSpent: 0, totalItems: 0, uniqueOrders: new Set(), lastPurchase: 0 };
|
clientMap[clientName] = { totalSpent: 0, totalItems: 0, uniqueOrders: new Set(), lastPurchase: 0, phone: '' };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (order.Fone_Cliente) {
|
||||||
|
clientMap[clientName].phone = order.Fone_Cliente;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate total spent based on quantity * unit price
|
// Calculate total spent based on quantity * unit price
|
||||||
@@ -54,6 +58,7 @@ const Clients = () => {
|
|||||||
|
|
||||||
let result = Object.keys(clientMap).map(name => ({
|
let result = Object.keys(clientMap).map(name => ({
|
||||||
name,
|
name,
|
||||||
|
phone: clientMap[name].phone,
|
||||||
totalSpent: clientMap[name].totalSpent,
|
totalSpent: clientMap[name].totalSpent,
|
||||||
totalItems: clientMap[name].totalItems,
|
totalItems: clientMap[name].totalItems,
|
||||||
orderCount: clientMap[name].uniqueOrders.size, // Grouped by unique date+value combinations
|
orderCount: clientMap[name].uniqueOrders.size, // Grouped by unique date+value combinations
|
||||||
@@ -129,6 +134,7 @@ const Clients = () => {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
const exportData = clientsData.map(client => ({
|
const exportData = clientsData.map(client => ({
|
||||||
'Nome do Cliente': client.name,
|
'Nome do Cliente': client.name,
|
||||||
|
'Telefone/WhatsApp': client.phone || 'N/A',
|
||||||
'Total Gasto (R$)': client.totalSpent.toFixed(2).replace('.', ','),
|
'Total Gasto (R$)': client.totalSpent.toFixed(2).replace('.', ','),
|
||||||
'Produtos Comprados': client.totalItems,
|
'Produtos Comprados': client.totalItems,
|
||||||
'Total de Pedidos': client.orderCount,
|
'Total de Pedidos': client.orderCount,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export interface OrderData {
|
|||||||
Valor_Unitario: number;
|
Valor_Unitario: number;
|
||||||
Recebido_Em?: string;
|
Recebido_Em?: string;
|
||||||
ID_Pedido?: string;
|
ID_Pedido?: string;
|
||||||
|
Fone_Cliente?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DateRange {
|
export interface DateRange {
|
||||||
|
|||||||
Reference in New Issue
Block a user