agenda: C9 OK + rowGroup por paciente em /financeiro + bubble cobranca-atualizada
Cenário 9 (Per-session — Michael Balint 12 × R$ 150)
- Testado e passou. 1 rule + 12 agenda_eventos materializadas + 12
financial_records pending. Sem billing_contract. Badge $ em todas as
12 sessões. Conforme esperado.
/melissa/financeiro-lancamentos: agrupado por paciente
- DataTable com rowGroupMode='subheader' + groupRowsBy='patient_id'
- Header de grupo com avatar + nome + badge "N lançamento(s)"
- expandableRowGroups + v-model:expandedRowGroups; watcher popula
todos os grupos da página atual como expandidos (sempre que
recordsGrouped muda — refletindo paginação/filtros)
- Sort outer por nome do paciente, preserva inner order
(pai → filhos de multas/taxas via mesmo agenda_evento_id)
Bubble-up @cobranca-atualizada → M.refetch
- Antes: ao marcar como pago no dialog, o card no FC ficava stale
até trocar de view. AgendaEventoFinanceiroPanel emitia
cobranca-atualizada mas só o loadOccFinancialRecord do dialog
escutava; o _paymentStateMap da agenda nao re-rodava.
- Fix: AgendaEventDialog ganhou _onCobrancaAtualizada que dispara
loadOccFinancialRecord() E emit('cobranca-atualizada') pra cima.
MelissaLayout escuta nos 2 dialogs e chama M.refetch() +
refetchEventosHoje(). Card passa pra borda verde na hora.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+56
-31
@@ -1,46 +1,70 @@
|
|||||||
# HANDOFF — 2026-05-19 madrugada (C1-C8 ✅ + UI saldo + Usar/Revogar, próximo C9)
|
# HANDOFF — 2026-05-20 madrugada (C1-C9 ✅, próximo C10)
|
||||||
|
|
||||||
Documento de continuidade. **Quando voltar, comece lendo esta página até o fim.**
|
Documento de continuidade. **Quando voltar, comece lendo esta página até o fim.**
|
||||||
|
|
||||||
> **🎯 SE A FORÇA CAIR / SESSÃO PERDER CONTEXTO:** estamos na rodada de
|
> **🎯 SE A FORÇA CAIR / SESSÃO PERDER CONTEXTO:** estamos na rodada de
|
||||||
> testes manuais dos 13 cenários do doc viva
|
> testes manuais dos 13 cenários do doc viva
|
||||||
> `src/docs/agenda-compromisso-financeiro-cenarios.html`. **C1-C8 ✅**.
|
> `src/docs/agenda-compromisso-financeiro-cenarios.html`. **C1-C9 ✅**.
|
||||||
> Próximo: **Cenário 9** (Michael Balint · per_session · 12 × R$ 150 —
|
> Próximo: **Cenário 10** (status change avulsa — Joyce/Ana/Sándor:
|
||||||
> materializa todas 12 sessões + cria 12 records pendentes upfront).
|
> marcar como realizado/faltou/cancelado e ver consequências no
|
||||||
|
> financeiro via STATUS_TO_EXCEPTION + financial_exceptions).
|
||||||
|
|
||||||
> **🟢 WORKING TREE LIMPO** após commit/push de 19/05 madrugada. UI de
|
> **🟢 WORKING TREE LIMPO** após commit/push do checkpoint pós-C8/C9.
|
||||||
> pacote saldo completa (info card violeta + botão Usar/Revogar atômico
|
> Per-session funcionando (12 events + 12 records gerados em batch).
|
||||||
> que materializa+realiza+cobra ou desfaz). Backfill de
|
> Financeiro com rowGroup por paciente (expand/collapse). Bubble-up
|
||||||
> determined_commitment_id em revogar+usar (evita campo "Título" indevido
|
> @cobranca-atualizada → M.refetch faz o card da agenda atualizar
|
||||||
> em sessões legadas).
|
> badge/borda imediatamente após pagar.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔴 PRÓXIMO PASSO IMEDIATO — Cenário 9 (Per-session)
|
## 🔴 PRÓXIMO PASSO IMEDIATO — Cenário 10 (Status change AVULSA)
|
||||||
|
|
||||||
| Campo | Valor |
|
Doc HTML diz: testar status change numa sessão avulsa com cobrança pendente,
|
||||||
|---|---|
|
mudando entre realizado / faltou / cancelado. As consequências financeiras
|
||||||
| Paciente | **Michael Balint** |
|
seguem `financial_exceptions` (regras configuradas pelo terapeuta sobre o
|
||||||
| Frequência | **Semanal · 12 ocorrências** |
|
que acontece com a cobrança nesses casos).
|
||||||
| Serviço | Sessão R$ 150 |
|
|
||||||
| Cobrança ao salvar | **1 por sessão** (chargeMode=per_session) |
|
|
||||||
|
|
||||||
**Esperado:**
|
Possíveis pacientes pra teste: usar Joyce, Sándor ou outro com cobrança
|
||||||
- 1 row em `recurrence_rules`
|
avulsa pendente já criada.
|
||||||
- **12 rows em `agenda_eventos`** (TODAS materializadas — diferença chave vs C6-C8)
|
|
||||||
- 0 rows em `billing_contracts` (per_session NÃO usa contrato)
|
|
||||||
- **12 rows em `financial_records`** (1 por sessão, todos pending, amount=150 cada)
|
|
||||||
- Agenda: 12 sessões com **badge $ amber** em todas (cada uma tem seu record próprio)
|
|
||||||
- Popover de cada uma: linha amber "A receber R$ 150,00 (cobrança pendente)"
|
|
||||||
|
|
||||||
Diferença chave vs cenários anteriores:
|
**Esperado** (depende das `financial_exceptions` configuradas no tenant):
|
||||||
- C6 (none): 1 row materializada + 0 records
|
- Realizada: status muda; cobrança permanece (caminho default)
|
||||||
- C7 (upfront): 1 row + 1 record (R$ totalPacote)
|
- Faltou: pode ter regra → cobrança 100% (paciente paga falta) ou cancela
|
||||||
- C8 (saldo): 0 rows + 0 records (modelo Cliniko, geram on-the-fly via Usar)
|
- Cancelado: pode ter regra → cancelar cobrança ou cobrar parcial
|
||||||
- **C9 (per_session): N rows + N records pré-criados**
|
|
||||||
|
|
||||||
Após C9: C10-C13 (status change + edit cobrada).
|
Conferir:
|
||||||
Quando todos passarem, replicar em **Rail** (`AgendaTerapeutaPage.vue`) e **Clínica** (`AgendaClinicaPage.vue`).
|
- `STATUS_TO_EXCEPTION` mapping em `useAgendaFinanceiro.js`
|
||||||
|
- `getFinancialExceptionRule(tenantId, exceptionType)` retorna a regra
|
||||||
|
- `handleStatusChange` orquestra: agenda update + financial adjust
|
||||||
|
|
||||||
|
Após C10: C11 (status change pacote saldo — usar a infra do Usar/Revogar)
|
||||||
|
→ C12 (antecipar pagamento) → C13 (edit cobrada).
|
||||||
|
|
||||||
|
Quando todos passarem, replicar em **Rail** (`AgendaTerapeutaPage.vue`) e
|
||||||
|
**Clínica** (`AgendaClinicaPage.vue`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📦 O que foi feito em 20/05 madrugada (C9 + rowGroup financeiro + bubble cobranca-atualizada)
|
||||||
|
|
||||||
|
### Cenário 9 ✅ (Per-session — Michael Balint 12 × R$ 150)
|
||||||
|
Testado e passou. Criou-se 1 rule + 12 agenda_eventos materializadas + 12 financial_records pending. Sem billing_contract. Cada sessão com badge $ amber individual. **Sem nenhuma `linha de pacote`** no popover (não tem contract → não aparece). Conforme esperado.
|
||||||
|
|
||||||
|
### `/melissa/financeiro-lancamentos` agrupado por paciente
|
||||||
|
- DataTable com `rowGroupMode='subheader'` + `groupRowsBy='patient_id'`
|
||||||
|
- Default: todos os grupos da página expandidos (watcher popula `expandedGroups` com unique patient_ids quando `recordsGrouped` muda)
|
||||||
|
- Header de grupo: avatar pequeno + nome + badge "N lançamento(s)"
|
||||||
|
- Click no chevron contrai/expande (auto via PrimeVue `expandableRowGroups`)
|
||||||
|
- Sort estável: ordena outer por nome do paciente, preserva inner order (pai → filhos de multas/taxas)
|
||||||
|
|
||||||
|
### Bubble-up `@cobranca-atualizada`
|
||||||
|
Antes: `AgendaEventoFinanceiroPanel.@cobranca-atualizada` disparava só `loadOccFinancialRecord` (interno do dialog). O `_paymentStateMap` da agenda ficava stale → card no FC só atualizava ao trocar de view.
|
||||||
|
|
||||||
|
Agora: `AgendaEventDialog._onCobrancaAtualizada` faz duas coisas:
|
||||||
|
1. `loadOccFinancialRecord()` — refresca estado interno do dialog
|
||||||
|
2. `emit('cobranca-atualizada')` — bubble pra MelissaLayout
|
||||||
|
|
||||||
|
MelissaLayout escuta nos 2 dialogs (principal + occurrenceMode) e chama `onCobrancaAtualizada` que dispara `M.refetch() + refetchEventosHoje()`. Resultado: card na agenda passa pra borda verde imediatamente após marcar pago.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -282,7 +306,8 @@ User tentou rodar C5 e bateu em 3 problemas seguidos. Cada um virou um fix:
|
|||||||
| 6 | Recorrente sem pacote (Maria Magali / Anna Freud) | ✅ |
|
| 6 | Recorrente sem pacote (Maria Magali / Anna Freud) | ✅ |
|
||||||
| 7 | Pacote upfront (Ana Souza Ferreira 4 × R$ 200) | ✅ |
|
| 7 | Pacote upfront (Ana Souza Ferreira 4 × R$ 200) | ✅ |
|
||||||
| 8 | Pacote saldo (Otávio 12 × R$ 50) | ✅ |
|
| 8 | Pacote saldo (Otávio 12 × R$ 50) | ✅ |
|
||||||
| **9** | **1 por sessão (Michael Balint 12 × R$ 150)** | 🔴 **PRÓXIMO** |
|
| 9 | 1 por sessão (Michael Balint 12 × R$ 150) | ✅ |
|
||||||
|
| **10** | **Status change avulsa (realizado/faltou/cancelado)** | 🔴 **PRÓXIMO** |
|
||||||
| 10 | Status change avulsa (realizado/faltou/cancelado) | ⏳ |
|
| 10 | Status change avulsa (realizado/faltou/cancelado) | ⏳ |
|
||||||
| 11 | Status change pacote saldo | ⏳ |
|
| 11 | Status change pacote saldo | ⏳ |
|
||||||
| 12 | Antecipar pagamento (Carl Jung) | ⏳ |
|
| 12 | Antecipar pagamento (Carl Jung) | ⏳ |
|
||||||
|
|||||||
@@ -14,6 +14,38 @@ Chronological, append-only record of everything that's happened in this wiki.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## [2026-05-20 06:00] session | C9 OK + rowGroup por paciente + bubble cobranca-atualizada
|
||||||
|
Touched: none (codigo + HANDOFF)
|
||||||
|
Detalhes:
|
||||||
|
|
||||||
|
CENARIO 9 (per_session):
|
||||||
|
- Michael Balint 12 sessoes R$ 150 modo "1 por sessao"
|
||||||
|
- DB conforme esperado: 1 rule, 12 events materializadas, 0 contracts,
|
||||||
|
12 records pending (R$ 150 cada)
|
||||||
|
- Visual: 12 badges $ amber, todas pending. Sem linha de pacote no
|
||||||
|
popover (per_session nao usa contract).
|
||||||
|
|
||||||
|
ROWGROUP NO /melissa/financeiro-lancamentos:
|
||||||
|
- DataTable com rowGroupMode='subheader' + groupRowsBy='patient_id'
|
||||||
|
- Default todos expandidos (watcher recalcula a cada recordsGrouped)
|
||||||
|
- Header de grupo: avatar + nome + badge "N lançamento(s)"
|
||||||
|
- Sort outer por nome de paciente, preserva ordem interna pai→filhos
|
||||||
|
- Click no chevron contrai/expande
|
||||||
|
|
||||||
|
BUBBLE @cobranca-atualizada:
|
||||||
|
- Bug: card na agenda nao atualizava badge/borda apos marcar como
|
||||||
|
pago no dialog (so dava refresh ao trocar de view)
|
||||||
|
- Root cause: AgendaEventoFinanceiroPanel.@cobranca-atualizada
|
||||||
|
disparava so loadOccFinancialRecord (interno do dialog). O
|
||||||
|
_paymentStateMap da agenda ficava stale.
|
||||||
|
- Fix: AgendaEventDialog tem agora _onCobrancaAtualizada que faz
|
||||||
|
loadOccFinancialRecord + emit('cobranca-atualizada'). MelissaLayout
|
||||||
|
escuta nos 2 dialogs e chama M.refetch() + refetchEventosHoje().
|
||||||
|
Card no FC passa pra borda verde imediatamente.
|
||||||
|
|
||||||
|
PROXIMO: Cenario 10 (status change avulsa — realizado/faltou/cancelado
|
||||||
|
+ STATUS_TO_EXCEPTION em financial_exceptions).
|
||||||
|
|
||||||
## [2026-05-20 03:00] session | C8 OK + Usar/Revogar saldo + UI pacote + ajustes UX
|
## [2026-05-20 03:00] session | C8 OK + Usar/Revogar saldo + UI pacote + ajustes UX
|
||||||
Touched: none (sem nova wiki page; mudancas em codigo + HANDOFF)
|
Touched: none (sem nova wiki page; mudancas em codigo + HANDOFF)
|
||||||
Detalhes: noite longa cobrindo C8 (pacote saldo) e principalmente
|
Detalhes: noite longa cobrindo C8 (pacote saldo) e principalmente
|
||||||
|
|||||||
@@ -147,7 +147,16 @@ const props = defineProps({
|
|||||||
blockOverlapWarning: { type: Object, default: null }
|
blockOverlapWarning: { type: Object, default: null }
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['update:modelValue', 'save', 'delete', 'updateSeriesEvent', 'editSeriesOccurrence', 'updated', 'usar-sessao', 'revogar-sessao']);
|
const emit = defineEmits(['update:modelValue', 'save', 'delete', 'updateSeriesEvent', 'editSeriesOccurrence', 'updated', 'usar-sessao', 'revogar-sessao', 'cobranca-atualizada']);
|
||||||
|
|
||||||
|
// Helper: chamado pelo AgendaEventoFinanceiroPanel quando a cobrança
|
||||||
|
// muda (gerada, paga, cancelada). Refresha estado interno do dialog
|
||||||
|
// E bubble pra MelissaLayout disparar refetch da agenda (sem isso, o
|
||||||
|
// card do FC fica com paymentState stale até trocar de view).
|
||||||
|
function _onCobrancaAtualizada() {
|
||||||
|
loadOccFinancialRecord();
|
||||||
|
emit('cobranca-atualizada');
|
||||||
|
}
|
||||||
const confirm = useConfirm();
|
const confirm = useConfirm();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -1823,7 +1832,7 @@ onBeforeUnmount(() => {
|
|||||||
Para alterar tipo ou serviços, ajuste a cobrança no Financeiro abaixo.
|
Para alterar tipo ou serviços, ajuste a cobrança no Financeiro abaixo.
|
||||||
</div>
|
</div>
|
||||||
</Message>
|
</Message>
|
||||||
<AgendaEventoFinanceiroPanel v-if="!occFinancialRecord._synthesized" :evento="eventRow" class="m-3" @cobranca-atualizada="loadOccFinancialRecord" />
|
<AgendaEventoFinanceiroPanel v-if="!occFinancialRecord._synthesized" :evento="eventRow" class="m-3" @cobranca-atualizada="_onCobrancaAtualizada" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- LOADING -->
|
<!-- LOADING -->
|
||||||
@@ -2338,7 +2347,7 @@ onBeforeUnmount(() => {
|
|||||||
Para alterar tipo ou serviços, ajuste a cobrança no Financeiro abaixo.
|
Para alterar tipo ou serviços, ajuste a cobrança no Financeiro abaixo.
|
||||||
</div>
|
</div>
|
||||||
</Message>
|
</Message>
|
||||||
<AgendaEventoFinanceiroPanel v-if="!occFinancialRecord._synthesized && isEdit && eventRow?.id" :evento="eventRow" class="m-3" @cobranca-atualizada="loadOccFinancialRecord" />
|
<AgendaEventoFinanceiroPanel v-if="!occFinancialRecord._synthesized && isEdit && eventRow?.id" :evento="eventRow" class="m-3" @cobranca-atualizada="_onCobrancaAtualizada" />
|
||||||
</template>
|
</template>
|
||||||
<Transition v-else-if="!occFinancialLoading" name="aed-pay-expand">
|
<Transition v-else-if="!occFinancialLoading" name="aed-pay-expand">
|
||||||
<div class="field-card__body aed-pay-body">
|
<div class="field-card__body aed-pay-body">
|
||||||
@@ -2407,7 +2416,7 @@ onBeforeUnmount(() => {
|
|||||||
v-if="!occFinancialRecord && !occFinancialLoading && isEdit && eventRow?.id"
|
v-if="!occFinancialRecord && !occFinancialLoading && isEdit && eventRow?.id"
|
||||||
:evento="eventRow"
|
:evento="eventRow"
|
||||||
class="m-3"
|
class="m-3"
|
||||||
@cobranca-atualizada="loadOccFinancialRecord"
|
@cobranca-atualizada="_onCobrancaAtualizada"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Botão "Ver lançamentos" (2026-05-14): abre dialog
|
<!-- Botão "Ver lançamentos" (2026-05-14): abre dialog
|
||||||
|
|||||||
@@ -161,9 +161,37 @@ const recordsGrouped = computed(() => {
|
|||||||
out.push({ ...r, _isChild: idx > 0 && group.length > 1, _hasChildren: idx === 0 && group.length > 1 });
|
out.push({ ...r, _isChild: idx > 0 && group.length > 1, _hasChildren: idx === 0 && group.length > 1 });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// Ordena por paciente pra rowGroupMode='subheader' do PrimeVue agrupar
|
||||||
|
// corretamente. Sort estável preserva ordem interna (parent → children
|
||||||
|
// do mesmo agenda_evento_id; séries em ordem cronológica).
|
||||||
|
out.sort((a, b) => {
|
||||||
|
const aName = a.patients?.nome_completo || '~'; // sem paciente vai pro final
|
||||||
|
const bName = b.patients?.nome_completo || '~';
|
||||||
|
return aName.localeCompare(bName, 'pt-BR');
|
||||||
|
});
|
||||||
return out;
|
return out;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Grupos expandidos (default: todos os pacientes da página atual).
|
||||||
|
// Watcher recalcula sempre que recordsGrouped muda — quando user troca
|
||||||
|
// pagina/filtro, todos os grupos da nova lista entram expandidos.
|
||||||
|
const expandedGroups = ref([]);
|
||||||
|
watch(
|
||||||
|
recordsGrouped,
|
||||||
|
(list) => {
|
||||||
|
const ids = [...new Set((list || []).map((r) => r.patient_id).filter(Boolean))];
|
||||||
|
expandedGroups.value = ids;
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
// Conta lançamentos por paciente na lista atual — exibido no header
|
||||||
|
// de grupo. Inclui só "pais" (não conta filhos de cobranças extras pra
|
||||||
|
// não inflar o número).
|
||||||
|
function _countForPatient(pid) {
|
||||||
|
if (!pid) return 0;
|
||||||
|
return (recordsGrouped.value || []).filter((r) => r.patient_id === pid && !r._isChild).length;
|
||||||
|
}
|
||||||
|
|
||||||
// ── Paginação server-side ─────────────────────────────
|
// ── Paginação server-side ─────────────────────────────
|
||||||
const pageFirst = ref(0);
|
const pageFirst = ref(0);
|
||||||
const pageRows = ref(20);
|
const pageRows = ref(20);
|
||||||
@@ -588,8 +616,24 @@ onBeforeUnmount(() => {
|
|||||||
tableStyle="min-width: 880px"
|
tableStyle="min-width: 880px"
|
||||||
:rowClass="(r) => [r.status === 'overdue' ? 'mfl-row-overdue' : '', r._isChild ? 'mfl-row-child' : '', r._hasChildren ? 'mfl-row-parent' : ''].filter(Boolean).join(' ')"
|
:rowClass="(r) => [r.status === 'overdue' ? 'mfl-row-overdue' : '', r._isChild ? 'mfl-row-child' : '', r._hasChildren ? 'mfl-row-parent' : ''].filter(Boolean).join(' ')"
|
||||||
class="mfl-table"
|
class="mfl-table"
|
||||||
|
rowGroupMode="subheader"
|
||||||
|
groupRowsBy="patient_id"
|
||||||
|
:expandableRowGroups="true"
|
||||||
|
v-model:expandedRowGroups="expandedGroups"
|
||||||
@page="onPageChange"
|
@page="onPageChange"
|
||||||
>
|
>
|
||||||
|
<template #groupheader="{ data }">
|
||||||
|
<div class="mfl-group-header">
|
||||||
|
<span
|
||||||
|
class="mfl-row__avatar"
|
||||||
|
:style="data.patients?.identification_color ? { background: data.patients.identification_color } : null"
|
||||||
|
>
|
||||||
|
{{ data.patients?.nome_completo?.[0]?.toUpperCase() ?? '?' }}
|
||||||
|
</span>
|
||||||
|
<span class="mfl-group-header__name">{{ data.patients?.nome_completo ?? 'Sem paciente' }}</span>
|
||||||
|
<span class="mfl-group-header__count">{{ _countForPatient(data.patient_id) }} lançamento(s)</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<Column header="Paciente" style="min-width: 13rem">
|
<Column header="Paciente" style="min-width: 13rem">
|
||||||
<template #body="{ data }">
|
<template #body="{ data }">
|
||||||
<!-- Em records "filhos" (multa, taxa) do mesmo agenda_evento_id,
|
<!-- Em records "filhos" (multa, taxa) do mesmo agenda_evento_id,
|
||||||
@@ -1471,6 +1515,27 @@ onBeforeUnmount(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Row content */
|
/* Row content */
|
||||||
|
/* Group header — paciente como subheader da DataTable, com avatar
|
||||||
|
pequeno + nome + contagem. Click no chevron (auto via PrimeVue
|
||||||
|
expandableRowGroups) expande/contrai o bloco do paciente. */
|
||||||
|
.mfl-group-header {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.mfl-group-header__name {
|
||||||
|
color: var(--text-color);
|
||||||
|
font-size: 0.92rem;
|
||||||
|
}
|
||||||
|
.mfl-group-header__count {
|
||||||
|
font-size: 0.72rem;
|
||||||
|
color: var(--text-color-secondary);
|
||||||
|
font-weight: 500;
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: color-mix(in srgb, var(--surface-border), transparent 40%);
|
||||||
|
}
|
||||||
.mfl-row__patient {
|
.mfl-row__patient {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -1485,6 +1485,15 @@ async function onRevogarSessao(payload = null) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bubble up do AgendaEventoFinanceiroPanel via AgendaEventDialog.
|
||||||
|
// Disparado quando cobrança é gerada / paga / cancelada dentro do
|
||||||
|
// dialog. Re-roda o bulk-load do useMelissaAgenda pra que o FC
|
||||||
|
// atualize badge $ / borda verde sem precisar trocar de view.
|
||||||
|
function onCobrancaAtualizada() {
|
||||||
|
M.refetch();
|
||||||
|
refetchEventosHoje();
|
||||||
|
}
|
||||||
|
|
||||||
async function onWhatsapp() {
|
async function onWhatsapp() {
|
||||||
const ev = eventoSelecionado.value;
|
const ev = eventoSelecionado.value;
|
||||||
if (!ev?.patient_id) {
|
if (!ev?.patient_id) {
|
||||||
@@ -2932,6 +2941,7 @@ function onKeydown(e) {
|
|||||||
@editSeriesOccurrence="M.onEditSeriesOccurrence"
|
@editSeriesOccurrence="M.onEditSeriesOccurrence"
|
||||||
@usar-sessao="onUsarSessao"
|
@usar-sessao="onUsarSessao"
|
||||||
@revogar-sessao="onRevogarSessao"
|
@revogar-sessao="onRevogarSessao"
|
||||||
|
@cobranca-atualizada="onCobrancaAtualizada"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 2º AgendaEventDialog — empilhado por cima do principal pra editar
|
<!-- 2º AgendaEventDialog — empilhado por cima do principal pra editar
|
||||||
@@ -2962,6 +2972,7 @@ function onKeydown(e) {
|
|||||||
@updateSeriesEvent="M.onUpdateSeriesEvent"
|
@updateSeriesEvent="M.onUpdateSeriesEvent"
|
||||||
@usar-sessao="onUsarSessao"
|
@usar-sessao="onUsarSessao"
|
||||||
@revogar-sessao="onRevogarSessao"
|
@revogar-sessao="onRevogarSessao"
|
||||||
|
@cobranca-atualizada="onCobrancaAtualizada"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- BloqueioDialog — bloqueio de horário/período/dia/feriados.
|
<!-- BloqueioDialog — bloqueio de horário/período/dia/feriados.
|
||||||
|
|||||||
Reference in New Issue
Block a user