Guias

šŸ“” API PROPOSALS - DOCUMENTAƇƃO COMPLETA

šŸ“” API PROPOSALS - DOCUMENTAƇƃO COMPLETA

Base URL

http://localhost:8000/api/v1

Autenticação

Todos os endpoints requerem autenticação via Laravel Sanctum:

Authorization: Bearer {token}

šŸ“‹ Endpoints

1. Listar Propostas do Fornecedor para uma Licitação

GET /orders/{order}/proposals

Lista todas as propostas que o fornecedor autenticado criou para uma licitação específica.

Parâmetros:

  • {order} (path) - UUID ou ID da licitação

Resposta 200:

[
  {
    "id": 1,
    "uuid": "550e8400-e29b-41d4-a716-446655440000",
    "order_id": 1,
    "supplier_id": 1,
    "total_amount": 1500.00,
    "notes": "Proposta com desconto especial",
    "validity_date": "2026-02-01",
    "status": "draft",
    "submitted_at": null,
    "accepted_at": null,
    "rejected_at": null,
    "cancelled_at": null,
    "rejection_reason": null,
    "created_at": "2026-01-11 10:00:00",
    "updated_at": "2026-01-11 10:05:00",
    "can_edit": true,
    "can_submit": true,
    "can_cancel": false,
    "is_draft": true,
    "is_submitted": false,
    "is_accepted": false,
    "is_rejected": false,
    "items": [
      {
        "id": 1,
        "proposal_id": 1,
        "order_item_id": 1,
        "product_id": 1,
        "unit_price": 10.50,
        "quantity": 100,
        "total_price": 1050.00,
        "offers_similar": false,
        "similar_product_name": null,
        "similar_product_description": null,
        "justification": null,
        "justification_type": null,
        "justification_label": null,
        "notes": null,
        "has_price": true,
        "has_justification": false,
        "is_valid": true,
        "created_at": "2026-01-11 10:00:00",
        "updated_at": "2026-01-11 10:00:00",
        "order_item": { ... },
        "product": { ... }
      }
    ]
  }
]

2. Criar ou Atualizar Proposta Draft

POST /orders/{order}/proposals

Cria uma nova proposta draft ou atualiza uma existente para o fornecedor autenticado.

Parâmetros:

  • {order} (path) - UUID ou ID da licitação

Body:

{
  "order_id": 1,
  "items": [
    {
      "order_item_id": 1,
      "product_id": 1,
      "unit_price": 10.50,
      "quantity": 100,
      "offers_similar": false,
      "similar_product_name": null,
      "similar_product_description": null,
      "justification": null,
      "justification_type": null,
      "notes": null
    }
  ],
  "notes": "ObservaƧƵes gerais da proposta",
  "validity_date": "2026-02-01"
}

ValidaƧƵes:

  • items (required, array) - Array de items
  • items.*.order_item_id (required, exists:order_items,id)
  • items.*.product_id (required, exists:products,id)
  • items.*.unit_price (nullable, numeric, min:0)
  • items.*.quantity (required, numeric, min:0)
  • items.*.offers_similar (boolean)
  • items.*.similar_product_name (nullable, string)
  • items.*.similar_product_description (nullable, string)
  • items.*.justification (nullable, string)
  • items.*.justification_type (nullable, in:unavailable,out_of_stock,logistics,other)
  • notes (nullable, string)
  • validity_date (nullable, date)

Resposta 200:

{
  "id": 1,
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  ...
}

Comportamento:

  • Se jĆ” existe proposta draft do fornecedor para essa licitação, atualiza
  • Se nĆ£o existe, cria nova
  • Limpa items existentes e recria com os novos dados
  • Calcula automaticamente total_price de cada item
  • Calcula automaticamente total_amount da proposta

3. Visualizar Proposta EspecĆ­fica

GET /proposals/{proposal}

Visualiza detalhes de uma proposta especĆ­fica.

Parâmetros:

  • {proposal} (path) - UUID da proposta

Resposta 200:

{
  "id": 1,
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "order_id": 1,
  "supplier_id": 1,
  "total_amount": 1500.00,
  ...
  "items": [ ... ],
  "order": { ... },
  "supplier": { ... }
}

4. Submeter Proposta

POST /proposals/{proposal}/submit

Submete uma proposta draft, mudando seu status para "submitted".

Parâmetros:

  • {proposal} (path) - UUID da proposta

ValidaƧƵes:

  • Proposta deve estar em status "draft"
  • Deve ter pelo menos 1 item
  • Todos os items devem ser vĆ”lidos (ter preƧo OU justificativa)

Resposta 200:

{
  "id": 1,
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "status": "submitted",
  "submitted_at": "2026-01-11 10:30:00",
  "can_edit": false,
  "can_submit": false,
  ...
}

Erro 422:

{
  "error": "Proposta não pode ser enviada"
}

5. Deletar Proposta Draft

DELETE /proposals/{proposal}

Deleta uma proposta draft.

Parâmetros:

  • {proposal} (path) - UUID da proposta

ValidaƧƵes:

  • Apenas propostas em status "draft" podem ser deletadas

Resposta 200:

{
  "message": "Proposta excluĆ­da com sucesso"
}

Erro 422:

{
  "error": "Apenas rascunhos podem ser excluĆ­dos"
}

6. Listar Propostas Recebidas (Produtor)

GET /orders/{order}/proposals/received

Lista todas as propostas recebidas (não-draft) para uma licitação específica.

Parâmetros:

  • {order} (path) - UUID ou ID da licitação

Resposta 200:

[
  {
    "id": 1,
    "uuid": "550e8400-e29b-41d4-a716-446655440000",
    "order_id": 1,
    "supplier_id": 1,
    "total_amount": 1500.00,
    "status": "submitted",
    "submitted_at": "2026-01-11 10:30:00",
    ...
    "supplier": {
      "id": 1,
      "name": "Fornecedor ABC",
      "email": "fornecedor@example.com",
      ...
    },
    "items": [ ... ]
  }
]

7. Aceitar Proposta (Produtor)

POST /proposals/{proposal}/accept

Aceita uma proposta submetida.

Parâmetros:

  • {proposal} (path) - UUID da proposta

ValidaƧƵes:

  • Proposta deve estar em status "submitted"

Resposta 200:

{
  "id": 1,
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "status": "accepted",
  "accepted_at": "2026-01-11 11:00:00",
  "is_accepted": true,
  ...
}

Erro 500:

{
  "error": "Erro ao aceitar proposta"
}

8. Rejeitar Proposta (Produtor)

POST /proposals/{proposal}/reject

Rejeita uma proposta submetida.

Parâmetros:

  • {proposal} (path) - UUID da proposta

Body:

{
  "reason": "PreƧos acima do orƧamento"
}

ValidaƧƵes:

  • reason (nullable, string)
  • Proposta deve estar em status "submitted"

Resposta 200:

{
  "id": 1,
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "status": "rejected",
  "rejected_at": "2026-01-11 11:00:00",
  "rejection_reason": "PreƧos acima do orƧamento",
  "is_rejected": true,
  ...
}

šŸ”„ Fluxo de Estados

draft → submitted → accepted
                 → rejected
                 → cancelled

Status DisponĆ­veis:

  • draft: Rascunho (pode editar)
  • submitted: Enviada (aguardando avaliação)
  • accepted: Aceita pelo produtor
  • rejected: Rejeitada pelo produtor
  • cancelled: Cancelada pelo fornecedor

šŸ“Š Códigos de Resposta

  • 200 - Sucesso
  • 401 - NĆ£o autenticado
  • 403 - NĆ£o autorizado
  • 404 - NĆ£o encontrado
  • 422 - Validação falhou
  • 500 - Erro interno

šŸ’” Dicas de Uso

Auto-save no Frontend

// Usar composable useProposals
const proposals = useProposals()

// Carregar draft
await proposals.loadOrCreateDraftProposal(orderId)

// Salvar (auto-save)
await proposals.saveDraft(orderId, items, notes)

// Submeter
await proposals.submitProposal(proposalUuid)

Validação de Items

Um item Ʃ vƔlido se:

  • unit_price > 0 (tem preƧo) OU
  • justification nĆ£o vazio (tem justificativa)

Licitação Aberta vs Fechada

  • Fechada: Todos os items devem ter preƧo
  • Aberta: Items podem ter justificativa em vez de preƧo

🧪 Exemplos de Testes

cURL: Criar Draft

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.50,
        "quantity": 100
      }
    ],
    "notes": "Teste"
  }'

cURL: Submeter

curl -X POST http://localhost:8000/api/v1/proposals/{uuid}/submit \
  -H "Authorization: Bearer {token}"

cURL: Listar Recebidas

curl -X GET http://localhost:8000/api/v1/orders/1/proposals/received \
  -H "Authorization: Bearer {token}"

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

Copyright Ā© 2026