Negócio

Propostas (Proposals)

Documentacao completa do modulo de propostas dos fornecedores na plataforma AgrSis.

Propostas (Proposals)

O que e uma proposta

Uma proposta (internamente Proposal) e a resposta de um fornecedor a uma cotacao publicada por um produtor. O fornecedor monta sua proposta item a item, podendo ajustar precos, quantidades e oferecer produtos similares quando o produtor permite.

Cada proposta recebe automaticamente um UUID e esta vinculada a uma unica cotacao (order_id) e um unico fornecedor (supplier_id).


Status da proposta

StatusLabel (Fornecedor)Label (Produtor)Descricao
draftRascunhoRascunhoProposta em montagem, nao visivel para o produtor
submittedEnviadaRecebidaProposta enviada, visivel para o produtor
awarded_pending_confirmationAguardando sua confirmacaoVencedora aguardando confirmacaoProdutor selecionou esta proposta como vencedora
acceptedVencedoraAceitaFornecedor confirmou a proposta vencedora
declined_after_awardRecusada por voceRecusada pelo vencedorFornecedor recusou a proposta apos ser selecionado
expired_after_awardPrazo de confirmacao expiradoConfirmacao expiradaFornecedor nao confirmou dentro do prazo
rejectedRejeitadaRejeitadaProdutor rejeitou a proposta
cancelledCanceladaCanceladaFornecedor cancelou a proposta enviada
lostPerdidaPerdidaOutra proposta foi aceita nesta cotacao
expiredExpiradaExpiradaPrazo da cotacao expirou sem acao

Fluxo de status

Fluxo principal (caminho feliz)

draft --> submitted --> awarded_pending_confirmation --> accepted
  1. Rascunho (draft): Fornecedor cria a proposta, adicionando precos por item.
  2. Enviada (submitted): Fornecedor submete a proposta. Produtor e notificado.
  3. Vencedora pendente (awarded_pending_confirmation): Produtor seleciona esta proposta. Fornecedor tem prazo para confirmar.
  4. Aceita (accepted): Fornecedor confirma. Cotacao finalizada. Demais propostas recebem status lost.

Fluxos alternativos

submitted --> rejected          (produtor rejeita)
submitted --> cancelled         (fornecedor cancela)
submitted --> lost              (outra proposta foi aceita)
submitted --> expired           (prazo da cotacao expirou)
draft --> expired               (prazo da cotacao expirou antes do envio)

awarded_pending_confirmation --> declined_after_award    (fornecedor recusa)
awarded_pending_confirmation --> expired_after_award     (fornecedor nao respondeu a tempo)

Quando o vencedor recusa ou expira:

  • A cotacao volta para in_analysis com prazo de analise estendido.
  • As demais propostas submitted continuam ativas para nova selecao.

Campos da proposta

Campos principais

CampoTipoDescricao
uuidstringIdentificador unico (gerado automaticamente)
order_idintegerCotacao associada
supplier_idintegerFornecedor que enviou
total_amountdecimal(2)Valor total calculado (subtotal - desconto + frete)
notesstringObservacoes gerais do fornecedor
validity_datedateData de validade da proposta

Desconto

O fornecedor pode aplicar desconto de duas formas (mutuamente exclusivas):

CampoTipoDescricao
discount_percentdecimal(2)Desconto percentual (0-100%)
discount_valuedecimal(2)Desconto em valor absoluto (R$)

Regras:

  • Se discount_value for informado e maior que zero, ele tem prioridade. O percentual e calculado automaticamente (discount_value / subtotal * 100).
  • O valor de desconto nao pode exceder o subtotal da proposta.

Frete

CampoTipoDescricao
freight_valuedecimal(2)Valor do frete (quando a cotacao e CIF)
freight_includedbooleanSe o frete esta incluso no preco

Regras:

  • Se a cotacao tem freight_type = cif (fornecedor entrega), o fornecedor deve informar o valor do frete ou indicar frete gratis.
  • Se a cotacao tem freight_type = fob (produtor retira), o frete e zerado automaticamente.
  • Quando is_free_shipping = true, o freight_value e definido como 0.

Calculo do total

subtotal = soma(item.unit_price * item.quantity) para cada item
desconto = discount_value OU (subtotal * discount_percent / 100)
total_amount = max(subtotal - desconto + freight_value, 0)

Itens da proposta (ProposalItem)

Cada proposta possui itens correspondentes aos itens da cotacao:

CampoTipoDescricao
order_item_idintegerItem da cotacao correspondente
product_idintegerProduto ofertado
unit_pricedecimalPreco unitario
quantitydecimal(2)Quantidade ofertada
total_pricedecimalPreco total do item (unit_price * quantity)
offers_similarbooleanSe oferece produto similar
similar_product_namestringNome do produto similar
similar_product_descriptionstringDescricao do produto similar
justificationstringJustificativa (quando nao oferta o produto original)
justification_typeenumTipo: unavailable, out_of_stock, logistics, other

Regras de quantidade:

  • A quantidade ofertada nao pode ultrapassar 5x a quantidade solicitada no item da cotacao.
  • Se o fornecedor nao informar quantidade, assume a mesma quantidade solicitada pelo produtor.
  • Todos os itens precisam ter quantidade valida maior que zero para envio.

Produto similar:

  • Somente permitido se o item da cotacao tem accepts_similar = true.
  • Quando offers_similar = false, o sistema forca o product_id do item original da cotacao, ignorando qualquer produto diferente informado.

Confirmacao da proposta vencedora

Quando o produtor seleciona uma proposta como vencedora, o fluxo de confirmacao e acionado via AwardWorkflowService.

Etapas da confirmacao

  1. Selecao pelo produtor: Somente durante o periodo de analise (in_analysis). Nao pode haver outro vencedor ativo.
  2. Prazo de confirmacao: Calculado em horas uteis (padrao: 2h uteis) via BusinessHoursService.
    • Horas uteis: 8h as 18h (configuravel).
    • Dias uteis: segunda a sexta (configuravel).
    • Exemplo: se a selecao ocorrer as 17h30 de sexta-feira, o prazo considera as proximas horas uteis (segunda-feira).
  3. Fornecedor confirma: A proposta vai para accepted, a cotacao para finished, e as demais propostas submitted recebem lost.
  4. Fornecedor recusa: Deve informar motivo (minimo 10 caracteres). A proposta vai para declined_after_award.
  5. Prazo expira: A proposta vai para expired_after_award.

O que acontece quando o fornecedor confirma

  • Proposta: status muda para accepted com confirmed_at preenchido.
  • Cotacao: status muda para finished com finished_at preenchido.
  • Demais propostas com status submitted recebem lost e lost_at.
  • Notificacoes enviadas para produtor, fornecedor vencedor e demais participantes.
  • Dados de contato ficam disponiveis para ambas as partes.

O que acontece quando o fornecedor recusa

  • Proposta: status muda para declined_after_award com declined_after_award_at e award_decline_reason preenchidos.
  • Cotacao: volta para in_analysis.
  • Prazo de analise: estendido em N horas (padrao: 24h, configuravel via analysis_extension_hours).
  • Notificacao enviada ao produtor informando a recusa e o novo prazo.
  • Demais fornecedores participantes sao notificados de que a cotacao reabriu para analise.
  • O fornecedor que recusou nao pode participar novamente desta cotacao.

O que acontece quando o prazo expira

  • Comportamento identico a recusa, exceto que o motivo e automatico (timeout).
  • Proposta: status muda para expired_after_award com award_confirmation_expired_at preenchido.
  • Cotacao: volta para in_analysis com prazo estendido.
  • Notificacoes enviadas a todos os envolvidos.

Extensao do prazo de analise

Sempre que um vencedor recusa ou nao confirma:

  1. A cotacao volta para in_analysis.
  2. O campo analysis_deadline e atualizado para now() + analysis_extension_hours (padrao: 24h).
  3. O produtor pode selecionar outro fornecedor durante o novo prazo.
  4. Os demais fornecedores participantes recebem notificacao de "Nova oportunidade".

Este ciclo pode se repetir ate que um fornecedor confirme ou o prazo de analise expire sem selecao.


Cancelamento de proposta pelo fornecedor

O fornecedor pode cancelar uma proposta ja enviada (submitted), sujeito as seguintes regras:

  • Limite de cancelamentos: Maximo 1 cancelamento por proposta (cancellation_count < 1).
  • Limite total por cotacao: Maximo 2 propostas canceladas por fornecedor na mesma cotacao.
  • Deve informar justificativa (minimo 10, maximo 1000 caracteres).
  • Apos cancelar, o produtor e notificado.

Cancelar e duplicar

O fornecedor pode usar o recurso de "cancelar e duplicar" para corrigir uma proposta:

  1. A proposta atual e cancelada.
  2. Uma nova proposta e criada em draft com os mesmos itens e valores.
  3. O fornecedor pode editar e reenviar.
  4. Se ja existir um rascunho, o sistema pergunta se deseja substituir.
  5. Esse recurso so pode ser usado 1 vez por cotacao (alem do cancelamento direto).

Favoritos

O produtor pode marcar propostas como favoritas para facilitar a analise:

  • Somente propostas com status submitted podem ser favoritadas.
  • Campos: favorited_at e favorited_by.
  • Toggle: favoritar/desfavoritar.

Visualizacao

O produtor pode marcar propostas como visualizadas:

  • Campo viewed_at e preenchido na primeira visualizacao.
  • O sistema rastreia contagem de propostas nao visualizadas (countUnviewed).

Permissoes por acao

AcaoQuem pode executarRestricoes
Criar proposta (draft)FornecedorCotacao publicada e dentro do prazo; sem outra proposta ativa
Editar propostaFornecedor donoSomente em draft e dentro do prazo da cotacao
Enviar proposta (submit)Fornecedor donoSomente draft com itens; cotacao deve aceitar propostas; max 2 cancelamentos anteriores
Cancelar propostaFornecedor donoSomente submitted; max 1 cancelamento; requer justificativa
Cancelar e duplicarFornecedor donosubmitted ou cancelled; max 1 uso por cotacao
Excluir propostaFornecedor donoSomente draft
Selecionar vencedora (accept)Produtor dono da cotacaoCotacao em in_analysis; proposta submitted; sem outro vencedor ativo
Confirmar propostaFornecedor vencedorStatus awarded_pending_confirmation; dentro do prazo
Recusar propostaFornecedor vencedorStatus awarded_pending_confirmation; requer motivo
Rejeitar propostaProdutor dono da cotacaoProposta submitted; motivo opcional
Favoritar propostaProdutor dono da cotacaoProposta submitted

Notificacoes

EventoDestinatarioTipo
Proposta enviadaProdutorPROPOSAL_RECEIVED
Proposta canceladaProdutorPROPOSAL_CANCELLED
Proposta selecionada como vencedoraFornecedor vencedor + produtor + demaisAWARD_PENDING_CONFIRMATION
Fornecedor confirmaProdutor + fornecedor + demaisAWARD_CONFIRMED
Fornecedor recusaProdutor + fornecedor + demaisAWARD_DECLINED
Prazo de confirmacao expirouProdutor + fornecedor + demaisAWARD_CONFIRMATION_EXPIRED
Prazo de analise estendidoDemais fornecedoresANALYSIS_DEADLINE_EXTENDED
Proposta aceita (pelo produtor)Fornecedor vencedorYOUR_PROPOSAL_ACCEPTED
Proposta perdidaFornecedores nao selecionadosYOUR_PROPOSAL_LOST
Proposta rejeitadaFornecedorYOUR_PROPOSAL_REJECTED

Endpoints da API

MetodoRotaAcao
GET/api/proposalsListar propostas do fornecedor
GET/api/orders/{uuid}/proposalsPropostas do fornecedor para uma cotacao
GET/api/orders/{uuid}/proposals/receivedPropostas recebidas pelo produtor
POST/api/orders/{uuid}/proposalsCriar/atualizar rascunho de proposta
GET/api/proposals/{uuid}Detalhes da proposta
DELETE/api/proposals/{uuid}Excluir rascunho
POST/api/proposals/{uuid}/submitEnviar proposta
POST/api/proposals/{uuid}/cancelCancelar proposta
POST/api/proposals/{uuid}/cancel-duplicateCancelar e duplicar
POST/api/proposals/{uuid}/acceptSelecionar como vencedora (produtor)
POST/api/proposals/{uuid}/confirm-awardConfirmar proposta vencedora (fornecedor)
POST/api/proposals/{uuid}/decline-awardRecusar proposta vencedora (fornecedor)
POST/api/proposals/{uuid}/rejectRejeitar proposta (produtor)
POST/api/proposals/{uuid}/favoriteFavoritar/desfavoritar (produtor)
POST/api/proposals/{uuid}/viewedMarcar como visualizada (produtor)
GET/api/proposals/{uuid}/itemsItens detalhados da proposta
GET/api/proposals/unviewed/countContagem de propostas nao visualizadas
GET/api/proposals/unviewedListar propostas nao visualizadas
Copyright © 2026