# Fluxos: Modulo Finance - Transacoes Operacionais

---

## 10.1 Upload de Boletos (Lote)

```
Usuario
  ↓
Finance → Pagamentos Operacionais → Custos/Despesas
  ↓
GET /finance/payments/operational/cost_expenses
  ↓
TransactionsController@index_cost_expenses
  ↓
View: pages/finance/payments/operational/cost_expenses
  ↓
Arrasta/seleciona PDFs de boletos
  ↓
POST /finance/transactions/get-info
  ↓
TransactionsController@getInfo
  ↓
Para CADA arquivo:
  BucketGoogleApiController::uploadToBucket (upload PDF)
  BucketGoogleApiController::read_pdf (OCR via Google Vision)
  OpenaiApiController::openia_boleto_code (extrai codigo)
  GeminiApiController::extrairCodigoBoletoGeminiGuzzle (fallback)
  AsaasApiController::asaasSimulateBillPayment (simula pagamento)
  OpenaiApiController::openia_boleto_due_date (extrai vencimento)
  ↓
  FinanceTransaction::create (status='draft', type='BOLETO')
  FinanceTransactionBill::create (codigo, due_date, beneficiario)
  ↓
JSON {results por arquivo}
```

**Tela inicial:** Custos e Despesas
**Acao do usuario:** Faz upload de 1+ PDFs/imagens de boletos
**Requisicao:** `POST /finance/transactions/get-info`
**Controller:** `TransactionsController@getInfo`
**Services:** GuzzleService
**Tabelas alteradas:**
- `finance_transactions` (INSERT, 1 por arquivo)
- `finance_transactions_bills` (INSERT, 1 por arquivo)
**APIs chamadas:**
- Google Cloud Storage (upload PDF)
- Google Cloud Vision (OCR)
- OpenAI GPT-4 / GPT-5.2 (extracao codigo boleto e vencimento)
- Google Gemini (fallback extracao)
- Asaas (simulacao de pagamento)
**Resultado esperado:** Boletos processados com dados extraidos automaticamente, status draft
**Possiveis erros:**
- Arquivo invalido → erro por arquivo (continua com proximos)
- OCR falha → dados parciais
- AI nao extrai codigo → boleto sem codigo (usuario completa manual)
- Boleto duplicado → alerta

---

## 10.2 Entrada Manual de Boleto

```
Usuario
  ↓
Tela Custos/Despesas → Campo codigo de barras
  ↓
POST /finance/transactions/barcode-info
  ↓
TransactionsController@barcodeGetInfo
  ↓
AsaasApiController::asaasSimulateBillPayment (simula com codigo)
OpenaiApiController::openia_boleto_due_date (vencimento)
  ↓
Se save=true:
  BucketGoogleApiController (upload arquivo opcional)
  FinanceTransaction::create (status='draft')
  FinanceTransactionBill::create
  ↓
JSON {items com dados simulados}
```

**Tela inicial:** Custos e Despesas
**Acao do usuario:** Digita ou escaneia codigo de barras
**Requisicao:** `POST /finance/transactions/barcode-info`
**Controller:** `TransactionsController@barcodeGetInfo`
**Tabelas alteradas:** `finance_transactions`, `finance_transactions_bills` (se save=true)
**APIs chamadas:** Asaas (simulacao), OpenAI (vencimento)

---

## 10.3 Criar Transferencia (TED/PIX)

```
Usuario
  ↓
Tela Custos/Despesas → Aba Transferencias → Formulario
  ↓
POST /finance/transactions/transfers/add
  ↓
TransactionsController@addTransfer
  ↓
Validacao: name, cpf_cnpj, payment_type (Custo/Despesa), category,
  description, value, transfer_type (ted/pix), scheduled_date
  Se TED: bank_code, branch, account, account_type
  Se PIX: pix_key, pix_type
  ↓
DB::beginTransaction
  ↓
FinanceTransferAccount::create/update (se saveBeneficiary)
FinanceTransaction::create (status='draft', type='TED'|'PIX')
FinanceTransactionTransfer::create (dados bancarios/PIX)
  ↓
DB::commit
  ↓
JSON {success}
```

**Tela inicial:** Custos e Despesas (aba transferencias)
**Acao do usuario:** Preenche dados do destinatario e valor
**Requisicao:** `POST /finance/transactions/transfers/add`
**Controller:** `TransactionsController@addTransfer`
**Tabelas alteradas:**
- `finance_transactions` (INSERT)
- `finance_transactions_transfers` (INSERT)
- `finance_transfer_accounts` (INSERT/UPDATE se salvar beneficiario)
**Resultado esperado:** Transferencia criada em draft
**Possiveis erros:**
- Validacao → 422
- Beneficiario nao salvo → confirmation_required

---

## 10.4 Upload de PIX QR Code (Lote)

```
Usuario
  ↓
Tela Custos/Despesas → Aba PIX QR Code → Upload imagens
  ↓
POST /finance/transactions/pix/get-info
  ↓
TransactionsController@getPixInfo
  ↓
Para CADA arquivo:
  BucketGoogleApiController::uploadToBucket
  BucketGoogleApiController::read_pdf (OCR)
  OpenaiApiController::openia_pix_payload (extrai payload)
  GeminiApiController::extrairPayloadPixGeminiGuzzle (fallback)
  AsaasApiController::asaasDecodePixQrCode (decodifica payload)
  ↓
  FinanceTransaction::create (status='draft', type='PIX_QRCODE')
  FinanceTransactionPixQrcode::create (payload, valores)
  ↓
JSON {items}
```

**Tabelas alteradas:**
- `finance_transactions` (INSERT)
- `finance_transactions_pix_qrcode` (INSERT)
**APIs chamadas:** Google Cloud (upload+OCR), OpenAI, Gemini, Asaas (decode PIX)

---

## 10.5 Consultar Chave PIX (DICT)

```
Usuario
  ↓
Formulario Transferencia → Busca chave PIX
  ↓
POST /finance/transactions/transfers/pix-key/lookup
  ↓
TransactionsController@lookupPixKey
  ↓
AsaasApiController::asaasGetPixKey
  ↓
JSON {owner, institution, type, key}
```

**APIs chamadas:** Asaas (consulta DICT)
**Resultado esperado:** Dados do titular da chave PIX

---

## 10.6 Validar e Processar Lote

```
Usuario
  ↓
Tela Custos/Despesas → Botao "Processar Pagamentos"
  ↓
POST /finance/transactions/validate-batch
  ↓
TransactionsController@validateBatch
  [middleware: CanProcessPayments]
  ↓
FinanceTransaction::where(status='draft') (bills, transfers, pix)
  ↓
Validacao por tipo:
  Bills: codigo, valor, tipo, descricao, categoria, beneficiario, vencimento
  Transfers: tipo transferencia, dados bancarios, valor, data agendamento
  PIX: payload, valor, tipo, descricao, categoria, beneficiario
  ↓
Se scheduled_date <= hoje: status='pending' + ProcessPaymentJob::dispatch
Se scheduled_date > hoje: status='scheduled'
  ↓
JSON {success, invalid_expenses[], invalid_transfers[], invalid_pix[]}
```

**Tela inicial:** Custos e Despesas
**Acao do usuario:** Revisa transacoes em draft e clica "Processar"
**Requisicao:** `POST /finance/transactions/validate-batch`
**Controller:** `TransactionsController@validateBatch`
**Tabelas alteradas:** `finance_transactions` (UPDATE status: draft → pending/scheduled)
**Jobs disparados:** `ProcessPaymentJob` para cada transacao pending
**Resultado esperado:** Transacoes validadas e enviadas para processamento
**Possiveis erros:**
- Transacoes invalidas retornadas em arrays separados (nao bloqueiam as validas)
- Middleware CanProcessPayments bloqueia se sem permissao

---

## 10.7 Processar Pagamento (Job)

```
ProcessPaymentJob::dispatch(transaction)
  ↓
PaymentServiceFactory → AsaasPaymentService ou IuguPaymentService
  ↓
Provider executa:
  Boleto: asaas payBill / iugu payBill
  TED: asaas transfer / iugu transfer
  PIX: asaas pixTransfer
  PIX QR: asaas payPixQrCode
  ↓
FinanceTransaction::update(status: processing/paid/error)
  ↓
Webhook Asaas retorna status final
```

---

## 10.8 Transferencia Mesma Titularidade

```
Usuario
  ↓
Finance → Pagamentos Operacionais → Mesma Titularidade
  ↓
POST /finance/transactions/same-ownership/add
  ↓
TransactionsController@addSameOwnershipTransfer
  ↓
FinanceTransaction::create (payment_type='Movimentacao entre Contas')
FinanceTransactionTransfer::create
  ↓
Se scheduled_date <= hoje: status='pending' + ProcessPaymentJob::dispatch
Se futuro: status='scheduled'
  ↓
JSON {success}
```

**Tabelas alteradas:** `finance_transactions`, `finance_transactions_transfers`
**Jobs disparados:** `ProcessPaymentJob` (se hoje)

---

## 10.9 Pagamento Manual de Colaborador

```
Usuario
  ↓
Finance → Pagamentos → Manual → Formulario
  ↓
POST /finance/transactions/collaborator-manual/add
  [middleware: CanProcessPayments]
  ↓
TransactionsController@addCollaboratorManualTransfer
  ↓
FinanceTransaction::create (origin_type='Colaborador Manual')
FinanceTransactionTransfer::create
FinancePaymentCollabSnapshotItem::create (se snapshot_id fornecido)
  ↓
ProcessPaymentJob::dispatch (se pending)
  ↓
JSON {success, redirect_url}
```

**Tabelas alteradas:**
- `finance_transactions` (INSERT)
- `finance_transactions_transfers` (INSERT)
- `finance_payment_collab_snapshot_items` (INSERT, se vinculado a snapshot)
**Jobs disparados:** `ProcessPaymentJob`

---

## 10.10 Retry de Transacao com Erro

```
Usuario
  ↓
Relatorios → Transacao com erro/rejeitada → Botao Retry
  ↓
POST /finance/transactions/retry/{id}
  ↓
TransactionsController@retryTransaction
  ↓
FinanceTransaction::update(status='pending', limpa campos de pagamento)
FinancePaymentCollabSnapshotItem::update(status='execution') se vinculado
  ↓
ProcessPaymentJob::dispatch
  ↓
JSON {success}
```

**Tabelas alteradas:** `finance_transactions` (status='pending'), `finance_payment_collab_snapshot_items`
**Jobs disparados:** `ProcessPaymentJob`

---

## 10.11 Excluir Transacao

```
POST /finance/transactions/delete/{id}
  ↓
Validacao: status deve ser 'rejected' ou 'error'
  ↓
FinanceTransaction::delete
  ↓
JSON {success}
```

---

## 10.12 Teste de Transferencia (R$ 1,00)

```
POST /finance/transactions/test-transfer
  ↓
TransactionsController@testTransfer
  ↓
FinanceTransaction::create (valor=1.00, origin='Teste')
FinanceTransactionTransfer::create
ProcessPaymentJob::dispatch
  ↓
JSON {success, transaction_id, status}
```

**Resultado esperado:** Transferencia de R$ 1,00 para validar dados bancarios
