diff --git a/src/services/transacao/summaryService.ts b/src/services/transacao/summaryService.ts index 16a683d..448b2ca 100644 --- a/src/services/transacao/summaryService.ts +++ b/src/services/transacao/summaryService.ts @@ -24,15 +24,22 @@ export async function getTransactionSummary(monthFilter?: string) { // Build the query with month filter if provided let query = supabase .from('transacoes') - .select('tipo, valor') - .or(`login.eq.${normalizedEmail},${groupIds.length > 0 ? `grupo_id.in.(${groupIds.map(id => `"${id}"`).join(',')})` : ''}`); + .select('tipo, valor'); + + // Apply filters properly + if (groupIds.length > 0) { + const orFilter = `login.eq.${normalizedEmail},grupo_id.in.(${groupIds.map(id => `"${id}"`).join(',')})`; + query = query.or(orFilter); + } else { + query = query.eq('login', normalizedEmail); + } // Apply month filter if provided if (monthFilter) { const startDate = `${monthFilter}-01`; const year = parseInt(monthFilter.split('-')[0]); const month = parseInt(monthFilter.split('-')[1]); - const endDate = new Date(year, month, 0).toISOString().split('T')[0]; // Last day of the month + const endDate = new Date(year, month, 0).toISOString().split('T')[0]; query = query .gte('quando', startDate) @@ -92,15 +99,22 @@ export async function getCategorySummary(tipoFiltro: string = 'despesa', monthFi // Build the query with month filter if provided let query = supabase .from('transacoes') - .select('categoria, valor, tipo') - .or(`login.eq.${normalizedEmail},${groupIds.length > 0 ? `grupo_id.in.(${groupIds.map(id => `"${id}"`).join(',')})` : ''}`); + .select('categoria, valor, tipo'); + + // Apply filters properly + if (groupIds.length > 0) { + const orFilter = `login.eq.${normalizedEmail},grupo_id.in.(${groupIds.map(id => `"${id}"`).join(',')})`; + query = query.or(orFilter); + } else { + query = query.eq('login', normalizedEmail); + } // Apply month filter if provided if (monthFilter) { const startDate = `${monthFilter}-01`; const year = parseInt(monthFilter.split('-')[0]); const month = parseInt(monthFilter.split('-')[1]); - const endDate = new Date(year, month, 0).toISOString().split('T')[0]; // Last day of the month + const endDate = new Date(year, month, 0).toISOString().split('T')[0]; query = query .gte('quando', startDate) @@ -177,11 +191,20 @@ export async function getMonthlyData(): Promise { // Get user groups by email const groupIds = await getUserGroups(normalizedEmail); - // Fetch monthly data with enhanced filter based on email (login) or group_id - const { data, error } = await supabase + // Build the query properly + let query = supabase .from('transacoes') - .select('quando, valor, tipo') - .or(`login.eq.${normalizedEmail},${groupIds.length > 0 ? `grupo_id.in.(${groupIds.map(id => `"${id}"`).join(',')})` : ''}`); + .select('quando, valor, tipo'); + + // Apply filters properly + if (groupIds.length > 0) { + const orFilter = `login.eq.${normalizedEmail},grupo_id.in.(${groupIds.map(id => `"${id}"`).join(',')})`; + query = query.or(orFilter); + } else { + query = query.eq('login', normalizedEmail); + } + + const { data, error } = await query; if (error) { console.error('Erro ao buscar dados mensais:', error); diff --git a/supabase/functions/mercado-pago-subscribe/index.ts b/supabase/functions/mercado-pago-subscribe/index.ts index 11f0e71..d216c58 100644 --- a/supabase/functions/mercado-pago-subscribe/index.ts +++ b/supabase/functions/mercado-pago-subscribe/index.ts @@ -14,15 +14,20 @@ serve(async (req) => { } try { + console.log('🚀 Iniciando processamento da assinatura MercadoPago'); + const { email, userId } = await req.json(); if (!email || !userId) { + console.error('❌ Email ou ID do usuário não fornecido'); return new Response(JSON.stringify({ error: 'E-mail ou ID do usuário não fornecido.' }), { headers: { ...corsHeaders, 'Content-Type': 'application/json' }, status: 400, }); } + console.log('📧 Dados recebidos:', { email, userId }); + // Cria um cliente Supabase com a service_role_key para verificar o usuário const supabaseAdmin = createClient( Deno.env.get('SUPABASE_URL') ?? '', @@ -31,6 +36,7 @@ serve(async (req) => { ); // Verifica se o usuário existe no banco de dados + console.log('🔍 Verificando usuário no banco de dados...'); const { data: userData, error: userError } = await supabaseAdmin .from('usuarios') .select('id') @@ -39,16 +45,19 @@ serve(async (req) => { .single(); if (userError || !userData) { - console.error('Falha na verificação do usuário:', userError); + console.error('❌ Falha na verificação do usuário:', userError); return new Response(JSON.stringify({ error: 'Usuário não autorizado.' }), { headers: { ...corsHeaders, 'Content-Type': 'application/json' }, status: 401, }); } + console.log('✅ Usuário verificado com sucesso'); + const MERCADO_PAGO_ACCESS_TOKEN = Deno.env.get('MERCADO_PAGO_ACCESS_TOKEN') if (!MERCADO_PAGO_ACCESS_TOKEN) { - return new Response(JSON.stringify({ error: 'Chave de acesso do Mercado Pago não configurada no servidor.' }), { + console.error('❌ Token do MercadoPago não configurado'); + return new Response(JSON.stringify({ error: 'Configuração do servidor incompleta.' }), { headers: { ...corsHeaders, 'Content-Type': 'application/json' }, status: 500, }) @@ -66,7 +75,7 @@ serve(async (req) => { payer_email: email }; - console.log('Enviando requisição para MercadoPago:', JSON.stringify(body)); + console.log('📦 Enviando requisição para MercadoPago:', JSON.stringify(body)); const mpResponse = await fetch("https://api.mercadopago.com/preapproval", { method: "POST", @@ -78,38 +87,69 @@ serve(async (req) => { }); const mpData = await mpResponse.json(); - console.log('Resposta do MercadoPago:', mpData); + console.log('📨 Resposta do MercadoPago:', { status: mpResponse.status, data: mpData }); if (!mpResponse.ok) { - console.error('Erro da API do Mercado Pago:', mpData); + console.error('❌ Erro da API do Mercado Pago:', mpData); // Tratar erro específico de países diferentes if (mpData.message === "Cannot operate between different countries") { + console.log('🌍 Erro de país detectado'); return new Response(JSON.stringify({ - error: 'Serviço temporariamente indisponível para sua região. Tente novamente mais tarde.' + error: 'Serviço temporariamente indisponível para sua região. Entre em contato conosco para mais informações.' }), { headers: { ...corsHeaders, 'Content-Type': 'application/json' }, status: 503, }); } - throw new Error(mpData.message || "Erro ao criar a assinatura no Mercado Pago."); + // Outros erros do MercadoPago + const errorMessage = mpData.message || `Erro no MercadoPago (${mpResponse.status})`; + return new Response(JSON.stringify({ error: errorMessage }), { + headers: { ...corsHeaders, 'Content-Type': 'application/json' }, + status: mpResponse.status, + }); } if (!mpData.init_point) { - throw new Error("URL de checkout não foi encontrada na resposta do Mercado Pago."); + console.error('❌ URL de checkout não encontrada na resposta'); + return new Response(JSON.stringify({ + error: "Não foi possível gerar o link de pagamento. Tente novamente." + }), { + headers: { ...corsHeaders, 'Content-Type': 'application/json' }, + status: 500, + }); } + console.log('✅ Assinatura criada com sucesso:', mpData.init_point); return new Response(JSON.stringify({ init_point: mpData.init_point }), { headers: { ...corsHeaders, 'Content-Type': 'application/json' }, status: 200, }) } catch (error) { - console.error('Erro geral:', error); - return new Response(JSON.stringify({ error: error.message }), { + console.error('💥 Erro geral na função:', error); + + // Erro de parsing do JSON + if (error instanceof SyntaxError) { + return new Response(JSON.stringify({ error: 'Dados de entrada inválidos.' }), { + headers: { ...corsHeaders, 'Content-Type': 'application/json' }, + status: 400, + }); + } + + // Erro de conexão + if (error instanceof TypeError && error.message.includes('fetch')) { + return new Response(JSON.stringify({ error: 'Erro de comunicação com o MercadoPago. Tente novamente.' }), { + headers: { ...corsHeaders, 'Content-Type': 'application/json' }, + status: 503, + }); + } + + // Erro genérico + return new Response(JSON.stringify({ error: 'Erro interno do servidor. Tente novamente mais tarde.' }), { headers: { ...corsHeaders, 'Content-Type': 'application/json' }, status: 500, - }) + }); } })