Ajuste Convenios e Particular

This commit is contained in:
Leonardo
2026-03-13 21:09:34 -03:00
parent 06fb369beb
commit 587079e414
13 changed files with 971 additions and 277 deletions
@@ -950,7 +950,7 @@ async function loadMonthSearchRows () {
try {
const { data, error } = await supabase
.from('agenda_eventos')
.select('id, owner_id, tipo, status, titulo, inicio_em, fim_em, observacoes, modalidade, determined_commitment_id, insurance_plan_id, insurance_guide_number, insurance_value, patients!agenda_eventos_patient_id_fkey(nome_completo)')
.select('id, owner_id, tipo, status, titulo, inicio_em, fim_em, observacoes, modalidade, determined_commitment_id, insurance_plan_id, insurance_guide_number, insurance_value, insurance_plan_service_id, patients!agenda_eventos_patient_id_fkey(nome_completo)')
.eq('owner_id', uid)
.is('mirror_of_event_id', null)
.gte('inicio_em', start)
@@ -1575,9 +1575,10 @@ function onEventClick (info) {
titulo_custom: ep.titulo_custom ?? null,
extra_fields: ep.extra_fields ?? null,
price: ep.price != null ? Number(ep.price) : null,
insurance_plan_id: ep.insurance_plan_id ?? null,
insurance_guide_number: ep.insurance_guide_number ?? null,
insurance_value: ep.insurance_value != null ? Number(ep.insurance_value) : null,
insurance_plan_id: ep.insurance_plan_id ?? null,
insurance_guide_number: ep.insurance_guide_number ?? null,
insurance_value: ep.insurance_value != null ? Number(ep.insurance_value) : null,
insurance_plan_service_id: ep.insurance_plan_service_id ?? null,
// ── recorrência (nova arquitetura) ──────────────────────────
recurrence_id: ep.recurrence_id ?? ep.recurrenceId ?? ep.serie_id ?? null,
original_date: ep.original_date ?? ep.originalDate ?? ep.recurrence_date ?? null,
@@ -1672,6 +1673,7 @@ function pickDbFields (obj) {
'insurance_plan_id',
'insurance_guide_number',
'insurance_value',
'insurance_plan_service_id',
]
const out = {}
for (const k of allowed) {
@@ -1828,7 +1830,8 @@ async function onDialogSave (arg) {
}
// ── CASO C / C2: criação RECORRENTE (novo ou evento existente) ─────────
if (recorrencia?.tipo === 'recorrente') {
// Só cria nova regra se NÃO há série existente — se houver recurrenceId, cai para F/G/E
if (recorrencia?.tipo === 'recorrente' && !recurrenceId) {
const startDate = new Date(normalized.inicio_em)
const tipoFreq = recorrencia.tipoFreq ?? 'semanal'
const dow = recorrencia.diaSemana ?? startDate.getDay()
@@ -1867,6 +1870,10 @@ async function onDialogSave (arg) {
observacoes: normalized.observacoes ?? null,
extra_fields: normalized.extra_fields ?? null,
price: normalized.price ?? null,
insurance_plan_id: normalized.insurance_plan_id ?? null,
insurance_guide_number: normalized.insurance_guide_number ?? null,
insurance_value: normalized.insurance_value ?? null,
insurance_plan_service_id: normalized.insurance_plan_service_id ?? null,
status: 'ativo',
}
const createdRule = await createRule(rule)
@@ -1974,6 +1981,11 @@ async function onDialogSave (arg) {
modalidade: normalized.modalidade ?? 'presencial',
observacoes: normalized.observacoes ?? null,
extra_fields: normalized.extra_fields ?? null,
price: normalized.price ?? null,
insurance_plan_id: normalized.insurance_plan_id ?? null,
insurance_guide_number: normalized.insurance_guide_number ?? null,
insurance_value: normalized.insurance_value ?? null,
insurance_plan_service_id: normalized.insurance_plan_service_id ?? null,
})
eventId = mat.id
}
@@ -2002,6 +2014,11 @@ async function onDialogSave (arg) {
titulo_custom: normalized.titulo_custom ?? null,
observacoes: normalized.observacoes ?? null,
extra_fields: normalized.extra_fields ?? null,
price: normalized.price ?? null,
insurance_plan_id: normalized.insurance_plan_id ?? null,
insurance_guide_number: normalized.insurance_guide_number ?? null,
insurance_value: normalized.insurance_value ?? null,
insurance_plan_service_id: normalized.insurance_plan_service_id ?? null,
})
// Opção C — atualizar template e propagar para a nova sub-série
@@ -2030,8 +2047,29 @@ async function onDialogSave (arg) {
titulo_custom: normalized.titulo_custom ?? null,
observacoes: normalized.observacoes ?? null,
extra_fields: normalized.extra_fields ?? null,
price: normalized.price ?? null,
insurance_plan_id: normalized.insurance_plan_id ?? null,
insurance_guide_number: normalized.insurance_guide_number ?? null,
insurance_value: normalized.insurance_value ?? null,
insurance_plan_service_id: normalized.insurance_plan_service_id ?? null,
})
// Propaga campos não-serviço para sessões já materializadas da série
await supabase
.from('agenda_eventos')
.update({
modalidade: normalized.modalidade ?? 'presencial',
titulo_custom: normalized.titulo_custom ?? null,
observacoes: normalized.observacoes ?? null,
extra_fields: normalized.extra_fields ?? null,
price: normalized.price ?? null,
insurance_plan_id: normalized.insurance_plan_id ?? null,
insurance_guide_number: normalized.insurance_guide_number ?? null,
insurance_value: normalized.insurance_value ?? null,
insurance_plan_service_id: normalized.insurance_plan_service_id ?? null,
})
.eq('recurrence_id', recurrenceId)
// Opção C — atualizar template e propagar para toda a série
const serviceItemsF = arg.serviceItems
if (recurrenceId && serviceItemsF?.length) {
@@ -2058,8 +2096,30 @@ async function onDialogSave (arg) {
titulo_custom: normalized.titulo_custom ?? null,
observacoes: normalized.observacoes ?? null,
extra_fields: normalized.extra_fields ?? null,
price: normalized.price ?? null,
insurance_plan_id: normalized.insurance_plan_id ?? null,
insurance_guide_number: normalized.insurance_guide_number ?? null,
insurance_value: normalized.insurance_value ?? null,
insurance_plan_service_id: normalized.insurance_plan_service_id ?? null,
})
// Propaga TODOS os campos para TODAS as sessões materializadas (sem exceção)
await supabase
.from('agenda_eventos')
.update({
modalidade: normalized.modalidade ?? 'presencial',
titulo_custom: normalized.titulo_custom ?? null,
observacoes: normalized.observacoes ?? null,
extra_fields: normalized.extra_fields ?? null,
price: normalized.price ?? null,
insurance_plan_id: normalized.insurance_plan_id ?? null,
insurance_guide_number: normalized.insurance_guide_number ?? null,
insurance_value: normalized.insurance_value ?? null,
insurance_plan_service_id: normalized.insurance_plan_service_id ?? null,
services_customized: false,
})
.eq('recurrence_id', recurrenceId)
// Propaga para todos — incluindo services_customized=true — e reseta o flag
const serviceItemsG = arg.serviceItems
if (recurrenceId && serviceItemsG?.length) {
@@ -2067,12 +2127,6 @@ async function onDialogSave (arg) {
await propagateToSerie(recurrenceId, serviceItemsG, { ignoreCustomized: true })
}
// Reseta services_customized para false em todos os eventos da série
await supabase
.from('agenda_eventos')
.update({ services_customized: false })
.eq('recurrence_id', recurrenceId)
if (id) await arg.onSaved?.(id)
toast.add({ severity: 'success', summary: 'Salvo', detail: 'Todas as sessões da série foram atualizadas (sem exceção).', life: 2500 })
@@ -2099,6 +2153,17 @@ async function onDialogSave (arg) {
} catch (e) {
const msg = String(e?.message || '')
if (msg.includes('recurrence_rules_dates_chk') || (msg.includes('violates check constraint') && msg.includes('recurrence_rules'))) {
toast.add({
severity: 'warn',
summary: 'Não foi possível dividir a série',
detail: 'Esta é a primeira sessão da série. Para alterar todas as ocorrências, selecione "Todos" ou "Todos sem exceção".',
life: 6000
})
return
}
const isOverlap =
e?.code === '23P01' ||
msg.includes('agenda_eventos_sem_sobreposicao') ||