agenda: popover sincroniza com eventos + antecipar nao reusa cancelled
Dois bugs descobertos no ciclo C12 antecipar -> revogar -> reantecipar:
1) confirmAnteciparPagamento reusava record cancelled:
Quando user revogava (vira cancelled) e antecipava de novo,
o existRec query pegava o cancelled e UPDATE-ava pra paid no
MESMO record id. Resultado: notes mantinham historico
"Cancelada via reversao" + "Antecipacao revogada" + record
reativo como paid, confuso pra audit trail. Fix: filtrar
.neq('status', 'cancelled') na busca de existRec — agora a
re-antecipacao via RPC cria record fresh.
2) Popover snapshot stale (pendencia documentada em
project_melissa_popover_snapshot, antecipada pra agora):
eventoSelecionado.value era snapshot do clique e nao acompanhava
updates do _paymentStateMap pos M.refetch. User antecipava, o
record paid era criado, mas o popover continuava com paymentState
antigo -> botao continuava "Antecipar pagamento" em vez de
alternar pra "Revogar pagamento". Fix: watch em M.eventos sincroniza
eventoSelecionado com a versao fresh quando id bate. flush:'post'
pra rodar apos o computed reagir.
Como o popover agora atualiza in-place, removido fecharEvento() de
confirmAnteciparPagamento e onRevogarAntecipacao — o user pode ver
o botao alternar live em vez de precisar reabrir o popover.
Cleanup do estado do Andre: deletado record orfa 3a4c79e0 pra reset
do teste C12.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user