Tarefa: MB-476 — "[AppControl] Recebimento no Fluxo e Antecipação" Repositórios:
tickets-apiv2(backend NestJS),tickets-appprodutor(app Flutter),tickets-dashboard(admin Vue) Status: Viável, com alterações significativas nas três camadas (detalhes abaixo)
Permitir que o produtor anticipe vendas parceladas (cartão) com juros por período, escolhendo:
advanceTaxPct).Regra central definida pelo time de produto:
Por padrão, todos os eventos seguem o fluxo atual (recebimento automático via split PagarMe + retenção de 24h + saque pelo
availableBalance). Somente quando o evento NÃO estiver com a flag de recebimento/antecipação automática habilitada, o app apresenta o "fluxo de recebimento": produtor vê recebíveis (disponíveis + futuros), simula a antecipação e solicita saque com juros.
Recapitulação de produto: se o evento NÃO tiver recebimento automático, a retenção passa a incidir SOMENTE sobre PIX — não faz sentido reter cartão, pois ele será recebido pelo fluxo de antecipação.
PagarMeSplitConfig) entre recebedores:Seller (produtor), Taxes (impostos), além do recebedor da própria plataforma.src/modules/payment/payment-gateway-services/pagar-me/pagar-me.service.ts (getPagarMeRecipientConfig).closing-calculation.service.ts) monta o ClosingSummaryDto:totalSalesWithoutFees, totalPaymentFees, totalInstallmentFeeAmount, companyOwedAmount, availableBalance.salesByPaymentMethod[] — já discrimina por método (paymentType: Pix, Credit, Debit, ...) com total e totalFee. É a base para a retenção seletiva.event-balance.service.ts buildBalance) → ResponseEventBalanceDto:summary (com availableBalance), commercialConditions, financialUserId, retention {active, pct, amount}.GET /event-balance/:eventId.documentation/producer-withdrawal-rules.md):dateEndEvent ?? dateStartEvent, com ajuste -3h de timezone).retencao = totalSalesWithoutFees × retentionPct / 100; availableBalance -= retencao.dateStartEvent, retenção fica ativa permanentemente.producer-withdrawal.service.ts):pin == passwordWithdraw, permissão financeiro/admin e value <= availableBalance.pending → admin conclui (/complete) via MercadoPago, Sicoob ou Manual → webhook atualiza para paid.ProducerWithdrawalTypeEnum { normal, advanced } — advanced já existe no enum, mas NÃO é usado em lugar nenhum (nem no backend, nem no app, nem no dashboard).extract_page.dart mostra ExtractValues (total, disponível, utilizado) a partir de GET /event-balance/:eventId; fluxo de saque em cash_withdrawal/ (passos: valor → contato/PIX → PIN → sucesso).event-balance/EventBalancePage.vue mostra Saldo Total / Retido / Saques / Disponível; saques em WithdrawalList.vue.retentionPct, advanceTaxPct, advanceAllowValue, advanceTotalValue (UI em EventCommercialConditions.vue e ProducerCommercialConditions.vue).Reutilizar o mecanismo existente getEventFlag(event, flag, defaultValue) (src/common/utils/event-flags.ts), que lê event.flags (JSON):
// Proposta de nome — a definir com produto
const automaticReceipt = getEventFlag<boolean>(
event, 'antecipacao_habilitada', /* default: */ true,
);
true (padrão): fluxo atual (nada muda).false: fluxo de recebimento/antecipação ativo → API passa a retornar recebíveis e a retenção é calculada só sobre PIX.A flag precisa ser editável em dashboard admin (novo campo na tela de condições comerciais ou flags do evento) e propagada em event.flags via PATCH de evento (campo flags já existe no create-event.dto.ts / response-event.ts).
No event-balance.service.ts (buildBalance), quando o evento não tem recebimento automático:
// Base atual: retenção sobre o total (cartões + PIX + demais)
const base = sumary.totalSalesWithoutFees;
// Proposta (fluxo de recebimento): base = apenas PIX, líquido de taxas
const pixSales = closing.salesByPaymentMethod
.filter((m) => m.paymentType === PaymentMethodType.Pix)
.reduce((acc, m) => acc + (m.total - m.totalFee), 0);
const retentionBase = automaticReceipt ? sumary.totalSalesWithoutFees : pixSales;
retentionAmount = (retentionBase * commercialConditions.retentionPct) / 100;
sumary.availableBalance -= retentionAmount;
ClosingService.calculatejá retorna oEventClosingCalculationDtocomsalesByPaymentMethod— basta expor/consumir o array no serviço de saldo (hojebuildBalancesó usaclosing.summary).
Novo endpoint de leitura (ex.: GET /event-balance/:eventId/receivables ou extensão do DTO de saldo) retornando:
paid/available no PagarMe + PIX);waiting_funds), agrupadas por data;advanceTaxPct (taxa mensal configurada nas condições comerciais), respeitando advanceAllowValue (teto) e acumulando advanceTotalValue.Fonte de dados: PagarMe já está integrado via PagarmeApiClient com:
GET /payables → getPayables() (filtros por status paid|waiting_funds, payment_date_since/until, recipient_id, type credit|chargeback|refund);GET /balance/operations → getBalanceOperations() (status waiting_funds|available|transferred).Lacuna: o cliente atual NÃO possui chamada à API de antecipação do PagarMe (
POST /anticipations,POST /recipients/:id/anticipationsetc.). Precisa ser adicionada aoPagarmeApiClient+ service para: criar antecipação, listarGET /anticipationse receber status via webhook.
tickets-apiv2 (backend)| Área | Arquivo | Mudança |
|---|---|---|
| Flag | src/common/utils/event-flags.ts + event.entity.ts |
Criar/ler flag antecipacao_habilitada (campo flags já existe). |
| Retenção seletiva | src/modules/event/event-balance/event-balance.service.ts |
Quando sem recebimento automático, calcular retenção sobre PIX (salesByPaymentMethod). Precisa que ClosingService.calculate exponha o array (já retorna via EventClosingCalculationDto). |
| DTO saldo | src/modules/event/event-balance/dto/response-event-balance.dto.ts |
Adicionar bloco de recebíveis/antecipação quando flag ativa. |
| Recebíveis | pagarme-api.client.ts + pagar-me.service.ts |
Novo: método getAnticipations/createAnticipation (API de antecipação PagarMe) e consolidação de recebíveis por parcela. |
| Saque c/ juros | producer-withdrawal (service, DTOs, webhook) |
Passar a usar ProducerWithdrawalTypeEnum.advanced (já definido) e calcular juros (advanceTaxPct) no valor; validação contra recebíveis antecipáveis e não só availableBalance. |
| Webhook | producer-withdrawal.controller.ts |
Tratar status de antecipação do PagarMe (criada/efetivada). |
tickets-appprodutor (Flutter)| Área | Arquivo | Mudança |
|---|---|---|
| Model de saldo | extract/data/models/extract_event_balance_entity.dart |
Ler novo bloco de recebíveis/antecipação. |
| Extrato | extract/ui/extract_page.dart |
Se flag sem recebimento automático, apresentar "fluxo de recebimento": recebíveis disponíveis + futuros e simulação de antecipação (valor hoje × juros por período). |
| Saque | cash_withdrawal/ (value step / cubit) |
Novos passos: seleção de recebíveis/parcelas a antecipar e exibição de juros; tipo advanced. |
| Home/entradas | home/ui/... |
Badge/sinalização quando o evento usa fluxo de recebimento. |
tickets-dashboard (admin)| Área | Arquivo | Mudança |
|---|---|---|
| Condições comerciais | EventCommercialConditions.vue, ProducerCommercialConditions.vue |
Já existem Taxa de Antecipação (%), Adiantamento (R$), Valor Total do Advanced (R$). Faltam a flag de recebimento automático e a gestão de antecipações (visualizar pedidos de antecipação, status). |
| Financeiro | event-balance/EventBalancePage.vue, WithdrawalList.vue |
Lista de antecipações (tipo advanced já mapeado no enum do dashboard). |
You do not have permission to view attachment with id: 18304). As telas de referência do fluxo de recebimento não puderam ser validadas; documentação baseada na descrição do ticket.antecipacao_habilitada vs recebimento_automatico), default (true), escopo (evento e/ou produtor) e UI de edição.totalSalesWithoutFees) e se débito/crédito à vista entram no "fluxo" (cartão) ou no disponível.antecipacao_habilitada + retenção seletiva PIX (event-balance.service.ts) + exposição de salesByPaymentMethod via ClosingService.getPayables p/ futuros, createAnticipation), DTO de recebíveis, uso do tipo advanced no saque e webhook.event-balance.service.spec.ts (retensão PIX vs total), testes de fechamento e novos testes de antecipação.