Guias

📘 GUIA DE IMPLEMENTAÇÃO - SISTEMA DE PROPOSTAS AGRSIS

📘 GUIA DE IMPLEMENTAÇÃO - SISTEMA DE PROPOSTAS AGRSIS

Status da Implementação

FASE 1-2: Backend API - 100% Concluído
FASE 3: Composables Frontend - 100% Concluído
📋 FASE 3: Adaptação de Páginas - Documentado (aguarda implementação manual)
FASE 4: Frontend Produtor - Pendente
FASE 5: Testes - Pendente


🎯 O Que Foi Implementado

Backend (Laravel 11) - ✅ COMPLETO

Database

  • ✅ Migration: proposals table com UUID e soft deletes
  • ✅ Migration: proposal_items table com auto-cálculo
  • ✅ Índices otimizados
  • ✅ Foreign keys com cascade

Models

  • Proposal.php (262 linhas) - Lógica completa de negócio
  • ProposalItem.php (161 linhas) - Auto-cálculo de totais
  • ✅ Relacionamentos atualizados em Order, Supplier, OrderItem

API

  • ProposalController.php (172 linhas) - 8 endpoints CRUD
  • ProposalResource.php - Transformação JSON
  • ProposalItemResource.php - Transformação JSON
  • ✅ Rotas registradas em api.php
  • ✅ Validações robustas
  • ✅ Transações de banco

Frontend (Nuxt 3) - ✅ COMPOSABLES COMPLETOS

Composables

  • useProposals.ts (299 linhas) - Gerenciamento completo
  • useToast.ts (192 linhas) - Sistema de notificações
  • ✅ Types TypeScript atualizados

📋 Próximos Passos (Implementação Manual)

1. Adaptar Página de Propostas

Arquivo: apps/supplier/pages/orders/[id]/proposal.vue

Mudanças necessárias:

  1. Adicionar imports:
import { watchDebounced } from '@vueuse/core'
import type { ProposalItemData } from '~/types/fornecedor'
const proposals = useProposals()
  1. Adicionar campo produto_id à interface PropostaForm
  2. Adicionar funções:
    • preencherFormularioComDraft() - Carrega draft existente
    • salvarRascunho() - Auto-save silencioso
  3. Modificar carregarDetalhes() para carregar draft
  4. Adicionar watcher com debounce para auto-save:
watchDebounced([propostas, observacoes], () => {
  if (licitacao.value && !isSubmitting.value) {
    salvarRascunho()
  }
}, { debounce: 2000, deep: true })
  1. Modificar enviarPropostas() para usar proposals.submitProposal()
  2. Adicionar indicador visual de auto-save no template

Ver detalhes completos no arquivo: IMPLEMENTATION_GUIDE.md (seção "Adaptação da Página")


🧪 Como Testar

Backend

# 1. Rodar migrations
cd apps/api
DB_HOST=127.0.0.1 DB_PORT=5433 php artisan migrate

# 2. Verificar tabelas criadas
psql -h 127.0.0.1 -p 5433 -U agrsis_user -d agrsis_db -c "\dt proposals*"

# 3. Testar endpoint de criação
curl -X POST http://localhost:8000/api/v1/orders/1/proposals \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "order_id": 1,
    "items": [{"order_item_id": 1, "product_id": 1, "unit_price": 10.5, "quantity": 100}]
  }'

Frontend

  1. Navegar para /orders/{id}/proposal
  2. Preencher preços
  3. Aguardar 2s → Ver "Salvando rascunho..."
  4. Recarregar página → Preços devem permanecer
  5. Preencher todos → Clicar "Enviar Proposta"
  6. Verificar redirecionamento e sucesso

📦 Arquivos Criados/Modificados

Backend

apps/api/
├── database/migrations/
│   ├── 2026_01_11_180044_create_proposals_table.php (NEW)
│   └── 2026_01_11_180044_create_proposal_items_table.php (NEW)
├── app/Models/
│   ├── Proposal.php (MODIFIED - 262 linhas)
│   ├── ProposalItem.php (NEW - 161 linhas)
│   ├── Order.php (MODIFIED - +proposals() relationship)
│   ├── Supplier.php (MODIFIED - +proposals() relationship)
│   └── OrderItem.php (MODIFIED - +proposalItems() relationship)
├── app/Http/Controllers/Api/
│   └── ProposalController.php (NEW - 172 linhas)
├── app/Http/Resources/
│   ├── ProposalResource.php (NEW - 44 linhas)
│   └── ProposalItemResource.php (NEW - 38 linhas)
└── routes/
    └── api.php (MODIFIED - +8 rotas)

Frontend

apps/supplier/
├── composables/
│   ├── useProposals.ts (NEW - 299 linhas)
│   └── useToast.ts (MODIFIED - 192 linhas)
└── types/
    └── fornecedor.ts (MODIFIED - +Proposal types)

💡 Conceitos Importantes

1. Draft Auto-Save

  • Salva automaticamente a cada 2 segundos
  • Não mostra toast (silencioso)
  • Permite retomar trabalho

2. Validação de Items

  • Item válido = unit_price > 0 OU justification não vazio
  • Suporta licitação aberta (justificativas)
  • Suporta licitação fechada (preços obrigatórios)

3. Fluxo de Status

draft → submitted → accepted|rejected|cancelled

4. Agrupamento

  • Todos os items de uma proposta são agrupados
  • Uma única proposta por fornecedor por licitação
  • Total calculado automaticamente

🚨 Atenções

  1. Não quebra produtor: Todo código é aditivo
  2. Testar após adaptação: Página precisa ser testada
  3. Auto-save: Watcher deve usar deep: true
  4. produto_id: Adicionar ao PropostaForm
  5. Migrations: Rodar em produção após testes

📞 Suporte

Consulte:

  1. Este guia
  2. Comentários no código
  3. Types em types/fornecedor.ts
  4. API docs (endpoints comentados no Controller)

Versão: 1.0
Data: 2026-01-11
Commit: a28afaa4

Copyright © 2026