diff --git a/src/layout/melissa/MelissaLayout.vue b/src/layout/melissa/MelissaLayout.vue index 029d610..d6e929c 100644 --- a/src/layout/melissa/MelissaLayout.vue +++ b/src/layout/melissa/MelissaLayout.vue @@ -665,6 +665,21 @@ function fecharEvento() { eventoBusy.value = false; } +// Mantém eventoSelecionado em sincronia com a lista reativa M.eventos. +// Sem isso, eventoSelecionado.value é snapshot do clique e não acompanha +// updates do _paymentStateMap pós refetch (caso típico: revogar/antecipar +// pagamento — record muda mas popover continuava mostrando estado antigo). +// Watch dispara apenas quando o ev correspondente aparece novo no eventos +// computed (paymentState atualizado pelo bulk-load). +watch(() => M.eventos.value, (novos) => { + const sel = eventoSelecionado.value; + if (!sel?.id) return; + const fresh = novos.find((e) => e.id === sel.id); + if (fresh && fresh !== sel) { + eventoSelecionado.value = fresh; + } +}, { flush: 'post' }); + // ── Actions do MelissaEventoPanel ────────────────────────────── // Fase 5 (2026-05-14): TODOS os status (realizado/faltou/cancelado/etc) // passam por M.onUpdateSeriesEvent — que abre o AgendaStatusChangeConfirmDialog @@ -811,12 +826,17 @@ async function confirmAnteciparPagamento() { } } - // 2) Verifica se já tem financial_record vinculado + // 2) Verifica se já tem financial_record vinculado. + // IMPORTANTE: filtra cancelled — caso típico após revogar a antecipação + // (record vira cancelled) e user re-antecipa. Sem o filtro, o handler + // reusava o record cancelled atualizando pra paid, mantendo notes + // da revogação no audit trail (confuso). const { data: existRec } = await supabase .from('financial_records') .select('id, status') .eq('agenda_evento_id', eventoId) .is('deleted_at', null) + .neq('status', 'cancelled') .order('created_at', { ascending: false }) .limit(1) .maybeSingle(); @@ -869,9 +889,10 @@ async function confirmAnteciparPagamento() { life: 4000 }); anteciparDialogOpen.value = false; - M.refetch(); + await M.refetch(); refetchEventosHoje(); - fecharEvento(); + // Não fecha o popover — watch em eventos sincroniza o ev pro novo + // estado (paymentState='paid' agora). Botão alterna pra "Revogar". } catch (e) { toast.add({ severity: 'error', summary: 'Erro', detail: e?.message || 'Falha ao antecipar pagamento.', life: 5000 }); } finally { @@ -943,9 +964,10 @@ async function onRevogarAntecipacao() { detail: `Cobrança de R$ ${Number(paidRec.final_amount || paidRec.amount || 0).toFixed(2).replace('.', ',')} cancelada.`, life: 4000 }); - M.refetch(); + await M.refetch(); refetchEventosHoje(); - fecharEvento(); + // Não fecha popover — watch em eventos sincroniza paymentState='none'. + // Botão alterna de volta pra "Antecipar pagamento". } catch (e) { toast.add({ severity: 'error', summary: 'Erro', detail: e?.message || 'Falha ao revogar antecipação.', life: 5000 }); } finally {