agenda: dialog pacote saldo realizada — 2 sub-questions claras
Antes (UX confusa): bloco "Gerar cobranca no pacote?" tinha so um Select "Como cobrar?" com options mixadas: - "Enviar link de pagamento (Asaas)" - "Ja recebi - PIX" - "Ja recebi - Dinheiro" - etc User selecionou "Ja recebi - PIX" pensando que era "cobrar via PIX" durante teste C11/A com Andre Green. Resultado: fatura virou paid sem o user ter recebido de verdade. Ambiguidade entre "como cobrar" (header) e "ja recebi" (options). Refactor: espelhar o padrao da avulsa (showRegistrarPagto): 1. Sub-question "A sessao ja foi paga?" radio Sim/Nao (default Nao) 2. Se Nao -> Select "Como vai cobrar?" [Apenas registrar pendente | Enviar link de pagamento (Asaas)] 3. Se Sim -> Select "Como recebeu?" [PIX | Dinheiro | Deposito | Maquininha] (sem prefixo "Ja recebi" — header ja deixa claro) Defaults safer: markPaid=false em ambos contextos (avulsa e pacote) pra evitar marcar paid sem querer. paymentMethod='pending' inicial. Handler em useMelissaAgenda._applyStatusDecisions: pos-processamento agora usa decision.markPaid explicito no caso pacote saldo: - markPaid=true -> record vira paid + payment_method=X - markPaid=false + paymentMethod='link' -> pending + payment_method='asaas' - markPaid=false + paymentMethod='pending' -> pending sem metodo Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -72,8 +72,16 @@ watch(
|
||||
consumeSaldo.value = !!props.regraExcecao?.default_consume_on_miss;
|
||||
applyFine.value = _calcInitialFineApply();
|
||||
fineAmount.value = _calcInitialFineAmount();
|
||||
markPaid.value = true;
|
||||
paymentMethod.value = 'pix';
|
||||
// Default markPaid:
|
||||
// - Avulsa realizada (showRegistrarPagto): default false (manter pendente)
|
||||
// - Pacote saldo realizada (showCobrancaPacote): default false (gerar pendente)
|
||||
// Em ambos casos o user precisa selecionar ativamente "Sim, já recebi"
|
||||
// pra registrar paid — evita marcar paid sem querer.
|
||||
markPaid.value = false;
|
||||
// paymentMethod default depende do contexto. Inicia 'pending' (que cai
|
||||
// no select de "Como vai cobrar?" quando markPaid=false). Quando user
|
||||
// troca pra "Sim, já recebi", precisa escolher PIX/Dinheiro/etc.
|
||||
paymentMethod.value = 'pending';
|
||||
generatePackageCharge.value = true;
|
||||
}
|
||||
);
|
||||
@@ -138,12 +146,13 @@ const paymentMethodOptions = [
|
||||
{ value: 'deposito', label: 'Depósito' },
|
||||
{ value: 'cartao_maquininha', label: 'Cartão (maquininha)' }
|
||||
];
|
||||
const paymentMethodOptionsCobranca = [
|
||||
{ value: 'link', label: 'Enviar link de pagamento (Asaas)' },
|
||||
{ value: 'pix', label: 'Já recebi — PIX' },
|
||||
{ value: 'dinheiro', label: 'Já recebi — Dinheiro' },
|
||||
{ value: 'deposito', label: 'Já recebi — Depósito' },
|
||||
{ value: 'cartao_maquininha', label: 'Já recebi — Cartão (maquininha)' }
|
||||
// Opções pra "Como vai cobrar?" quando markPaid=false (sessão pendente
|
||||
// no pacote saldo). 'pending' = só registra como pendente, terapeuta
|
||||
// cobra depois pelo /financeiro. 'link' = gera link Asaas e marca
|
||||
// payment_method='asaas' no record (pós-confirm o handler updata).
|
||||
const paymentMethodOptionsPending = [
|
||||
{ value: 'pending', label: 'Apenas registrar como pendente' },
|
||||
{ value: 'link', label: 'Enviar link de pagamento (Asaas)' }
|
||||
];
|
||||
|
||||
const regraResumo = computed(() => {
|
||||
@@ -204,11 +213,16 @@ const fineDefaultReason = computed(() => {
|
||||
|
||||
// ─── Actions ───────────────────────────────────────────────────────────
|
||||
function onConfirm() {
|
||||
// markPaid agora é considerado em DOIS contextos:
|
||||
// 1. Avulsa pendente (showRegistrarPagto): paciente já pagou a cobrança?
|
||||
// 2. Pacote saldo realizado (showCobrancaPacote): já recebeu o valor da sessão?
|
||||
// Em ambos casos: markPaid=true → record vira paid; false → fica pending.
|
||||
const considerMarkPaid = showRegistrarPagto.value || (showCobrancaPacote.value && generatePackageCharge.value);
|
||||
emit('confirm', {
|
||||
consumeSaldo: showSaldoBlock.value ? consumeSaldo.value : false,
|
||||
applyFine: showFineBlock.value ? applyFine.value : false,
|
||||
fineAmount: showFineBlock.value && applyFine.value ? Number(fineAmount.value) || 0 : 0,
|
||||
markPaid: showRegistrarPagto.value ? markPaid.value : false,
|
||||
markPaid: considerMarkPaid ? markPaid.value : false,
|
||||
paymentMethod: paymentMethod.value,
|
||||
generatePackageCharge: showCobrancaPacote.value ? generatePackageCharge.value : false
|
||||
});
|
||||
@@ -338,11 +352,35 @@ function onCancel() {
|
||||
<Checkbox v-model="generatePackageCharge" inputId="asccd-gen-charge" binary />
|
||||
<label for="asccd-gen-charge" class="cursor-pointer">Gerar cobrança e consumir 1 sessão</label>
|
||||
</div>
|
||||
<div v-if="generatePackageCharge" class="asccd-method-row">
|
||||
<label class="asccd-method-label">Como cobrar?</label>
|
||||
<!-- Sub-question 1: a sessão já foi paga? (espelha o padrão da avulsa) -->
|
||||
<div v-if="generatePackageCharge" class="asccd-radio-group mt-2">
|
||||
<label class="asccd-radio">
|
||||
<input type="radio" :value="false" v-model="markPaid" />
|
||||
<span>Não, gerar como cobrança pendente</span>
|
||||
</label>
|
||||
<label class="asccd-radio">
|
||||
<input type="radio" :value="true" v-model="markPaid" />
|
||||
<span>Sim, já recebi</span>
|
||||
</label>
|
||||
</div>
|
||||
<!-- Sub-question 2a: se "Já recebi" → método de recebimento (sem prefixo) -->
|
||||
<div v-if="generatePackageCharge && markPaid" class="asccd-method-row">
|
||||
<label class="asccd-method-label">Como recebeu?</label>
|
||||
<Select
|
||||
v-model="paymentMethod"
|
||||
:options="paymentMethodOptionsCobranca"
|
||||
:options="paymentMethodOptions"
|
||||
optionLabel="label"
|
||||
optionValue="value"
|
||||
size="small"
|
||||
class="asccd-method-select"
|
||||
/>
|
||||
</div>
|
||||
<!-- Sub-question 2b: se "Pendente" → forma de cobrança (link Asaas vs registrar simples) -->
|
||||
<div v-if="generatePackageCharge && !markPaid" class="asccd-method-row">
|
||||
<label class="asccd-method-label">Como vai cobrar?</label>
|
||||
<Select
|
||||
v-model="paymentMethod"
|
||||
:options="paymentMethodOptionsPending"
|
||||
optionLabel="label"
|
||||
optionValue="value"
|
||||
size="small"
|
||||
|
||||
@@ -1567,22 +1567,12 @@ function _buildHandlers(deps) {
|
||||
toast.add({ severity: 'success', summary: 'Status atualizado', detail: 'Decisões aplicadas.', life: 2500 });
|
||||
}
|
||||
|
||||
// Pós: se gerou cobrança via link Asaas, marcar payment_method='asaas'
|
||||
if (decision.generatePackageCharge && decision.paymentMethod === 'link' && eventoId) {
|
||||
try {
|
||||
const { data: newRec } = await supabase
|
||||
.from('financial_records')
|
||||
.select('id')
|
||||
.eq('agenda_evento_id', eventoId)
|
||||
.order('created_at', { ascending: false })
|
||||
.limit(1)
|
||||
.single();
|
||||
if (newRec?.id) {
|
||||
await supabase.from('financial_records').update({ payment_method: 'asaas', updated_at: new Date().toISOString() }).eq('id', newRec.id);
|
||||
}
|
||||
} catch { /* silencioso */ }
|
||||
} else if (decision.generatePackageCharge && decision.paymentMethod !== 'link' && eventoId) {
|
||||
// Já recebi → marca como paid
|
||||
// Pós-processamento do record gerado pelo pacote saldo. Agora o
|
||||
// decision tem markPaid explícito:
|
||||
// - markPaid=true → vira paid + payment_method=PIX/dinheiro/etc
|
||||
// - markPaid=false + paymentMethod='link' → pending + payment_method='asaas'
|
||||
// - markPaid=false + paymentMethod='pending' → pending sem método (default)
|
||||
if (decision.generatePackageCharge && eventoId) {
|
||||
try {
|
||||
const { data: newRec } = await supabase
|
||||
.from('financial_records')
|
||||
@@ -1592,6 +1582,7 @@ function _buildHandlers(deps) {
|
||||
.limit(1)
|
||||
.single();
|
||||
if (newRec?.id) {
|
||||
if (decision.markPaid) {
|
||||
await supabase
|
||||
.from('financial_records')
|
||||
.update({
|
||||
@@ -1601,6 +1592,14 @@ function _buildHandlers(deps) {
|
||||
updated_at: new Date().toISOString()
|
||||
})
|
||||
.eq('id', newRec.id);
|
||||
} else if (decision.paymentMethod === 'link') {
|
||||
await supabase
|
||||
.from('financial_records')
|
||||
.update({ payment_method: 'asaas', updated_at: new Date().toISOString() })
|
||||
.eq('id', newRec.id);
|
||||
}
|
||||
// markPaid=false + paymentMethod='pending' → não faz nada
|
||||
// (record já criado como pending pelo RPC, sem payment_method)
|
||||
}
|
||||
} catch { /* silencioso */ }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user