const formatProductNameForDisplay = (name) => { return String(name || '') .toLocaleLowerCase('pt-BR') .replace(/(^|[\s/-])(\p{L})/gu, (_, separator, letter) => { return `${separator}${letter.toLocaleUpperCase('pt-BR')}`; }); }; const formatProductList = (productNames) => { const displayNames = productNames.map(formatProductNameForDisplay); if (displayNames.length <= 2) { return displayNames.join(' e '); } return `${displayNames.slice(0, -1).join(', ')} e ${displayNames[displayNames.length - 1]}`; }; const groupCampaignRowsByBaseProduct = (rows) => { return rows.reduce((acc, row) => { if (!acc[row.base_product_name]) acc[row.base_product_name] = []; acc[row.base_product_name].push(row); return acc; }, {}); }; const mapCampaignProducts = (groups) => { return Object.entries(groups) .sort(([, aItems], [, bItems]) => { return new Date(aItems[0].created_at).getTime() - new Date(bItems[0].created_at).getTime(); }) .map(([baseProductName, items]) => { const sortedItems = [...items].sort((a, b) => String(a.nome).localeCompare(String(b.nome), 'pt-BR')); return { baseProduct: formatProductNameForDisplay(baseProductName), total_delta: sortedItems.reduce((sum, item) => sum + Number(item.delta_estoque || 0), 0), sizes: sortedItems.map(item => ({ id: item.produto_id, nome: item.nome, delta: item.delta_estoque, saldo: item.saldo })), itemIds: sortedItems.map(item => item.id) }; }); }; const buildWhatsappCampaignPayload = (products, customers) => { const productNames = products.map(product => product.baseProduct); const productsText = formatProductList(productNames); const allSizes = products.flatMap(product => product.sizes); const totalDelta = products.reduce((sum, product) => sum + product.total_delta, 0); return { baseProduct: productsText, productsText, total_delta: totalDelta, sizes: allSizes, products: products.map(({ itemIds, ...product }) => product), customers }; }; const groupCampaignRows = (rows) => { return Object.values(rows.reduce((acc, row) => { const key = `${row.base_product_name}:${row.status}`; if (!acc[key]) { acc[key] = { key, baseProductName: row.base_product_name, status: row.status, totalDelta: 0, rowCount: 0, attempts: 0, lastError: null, createdAt: row.created_at, updatedAt: row.updated_at, sentAt: row.sent_at, items: [] }; } acc[key].totalDelta += Number(row.delta_estoque || 0); acc[key].rowCount += 1; acc[key].attempts = Math.max(acc[key].attempts, Number(row.attempts || 0)); acc[key].lastError = row.last_error || acc[key].lastError; acc[key].createdAt = new Date(row.created_at) < new Date(acc[key].createdAt) ? row.created_at : acc[key].createdAt; acc[key].updatedAt = new Date(row.updated_at) > new Date(acc[key].updatedAt) ? row.updated_at : acc[key].updatedAt; acc[key].sentAt = row.sent_at || acc[key].sentAt; acc[key].items.push(row); return acc; }, {})).sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()); }; module.exports = { buildWhatsappCampaignPayload, formatProductNameForDisplay, formatProductList, groupCampaignRows, groupCampaignRowsByBaseProduct, mapCampaignProducts };