Skip to content

POST api/Proposta/Novo — Criar nova proposta (cotação + versão de capital + adesão)

Cria (ou reaproveita) uma cotação e grava uma versão de capital; ao final, tenta criar/atualizar adesão vinculada à cotação.

Fonte de verdade (contrato): swagger.json (Swagger/OpenAPI do legado).
Fonte de verdade (regra de negócio): trechos de PropostaService.Novo, RegrasNegocio.Cotacao e métodos VB enviados neste chat.


1) Contrato (Legado)

Request

  • HTTP Method: POST
  • URL: {{base_url}}/api/Proposta/Novo
  • Autenticação: Bearer (Controller possui [Authorize] e Swagger aponta Authorization: Bearer {{token}}).

Headers

Header Obrigatório Descrição
Authorization Sim Bearer {{token}}
Content-Type Sim application/json
X-Correlation-Id Não No legado não aparece. Na API Nova será obrigatório via gateway (ver Matriz de Políticas).

Body — PropostaNovoPayload

Observação importante: o Swagger expõe muitos campos, mas o código atual sobrescreve/ignora vários deles (ver seção 2.4).

Campo Tipo Obrigatório Descrição
COD_USUARIO integer Sim Código do usuário (no legado vem do payload; na API Nova deve vir do token/claims).
COD_OPCOES_COMISSAO string [A CONFIRMAR] Código de opções de comissão.
COD_ENTIDADE_PATRONAL string [A CONFIRMAR] Código da entidade patronal.
NOM_EMPRESA string [A CONFIRMAR] Nome da empresa.
NUM_IDENTIFICACAO string [A CONFIRMAR] Número de identificação (CNPJ/CPF/etc conforme regra).
COD_CIDADE string [A CONFIRMAR] Código da cidade.
COD_ENTIDADE_LABORAL string [A CONFIRMAR] Código da entidade laboral.
DAT_SITUACAO_RECEITA string [A CONFIRMAR] Data da situação na receita (string no payload).
DSC_SITUACAO_RECEITA string [A CONFIRMAR] Descrição da situação na receita.
DSC_TERRITORIAL string [A CONFIRMAR] Descrição territorial usada para calcular IND_DENTRO_ABRANGENCIA no service.
IND_TIPO_CAPITAL string [A CONFIRMAR] Tipo de capital (no service é sobrescrito via fncRetornaOpcoesComissao).
QTD_VAL_COBERTURA string [A CONFIRMAR] Quantidade valor cobertura (sobrescrito via fncRetornaOpcoesComissao).
VAL_FATURA_MINIMA string [A CONFIRMAR] Valor de fatura mínima (sobrescrito via fncRetornaOpcoesComissao).
NUM_SEGURADOS string [A CONFIRMAR] Número de segurados (usado em CotacaoCapital.SubNUM_SEGURADOS).
COD_MODULO string [A CONFIRMAR] Código do módulo (sobrescrito via fncRetornaOpcoesComissao).
COD_MODULO_ADICIONAL string [A CONFIRMAR] Código do módulo adicional (sobrescrito via fncRetornaOpcoesComissao).
NUM_CEP string [A CONFIRMAR] CEP.
DSC_ENDERECO string [A CONFIRMAR] Endereço.
NOM_BAIRRO string [A CONFIRMAR] Bairro.
NOM_CONTATO_SOLICITANTE string [A CONFIRMAR] Nome do contato solicitante.
NUM_TELEFONE_SOLICITANTE string [A CONFIRMAR] Telefone do solicitante.
NOM_EMAIL_SOLICITANTE string [A CONFIRMAR] E-mail do solicitante.
NOM_RESPONSAVEL_DA_EMPRESA string [A CONFIRMAR] Nome do responsável da empresa.
DSC_EMAIL_RESPONSAVEL_DA_EMPRESA string [A CONFIRMAR] E-mail do responsável da empresa.
NUM_TELEFONE_RESPONSAVEL_DA_EMPRESA string [A CONFIRMAR] Telefone do responsável da empresa.
NUM_COTACAO string [A CONFIRMAR] Número da cotação (pode vir vazio; o legado pode gerar/reusar).
NUM_VERSAO_CAPITAL string [A CONFIRMAR] Número da versão de capital (pode vir vazio; o legado gera/reusa).
COD_SOL_CORRETOR integer [A CONFIRMAR] Código do solicitante corretor (no service é sobrescrito para payload.COD_USUARIO).
IND_TIPO_SOLICITANTE string [A CONFIRMAR] Tipo solicitante (no service é sobrescrito para "C").
IND_CONHECEU_PASI string [A CONFIRMAR] Indicador (no service é sobrescrito para "N").
COD_ATIVIDADE_RECEITA string [A CONFIRMAR] Código atividade receita.
IND_ACOMPANHAMENTO_SITUACAO string [A CONFIRMAR] Indicador (no service é sobrescrito para "P").
COD_RESPONSAVEL string [A CONFIRMAR] Responsável (no service é sobrescrito para "173").
IND_DENTRO_ABRANGENCIA string [A CONFIRMAR] Dentro da abrangência (no service é calculado; no DB pode ser forçado).
VAL_COBERTURA string [A CONFIRMAR] Valor de cobertura (sobrescrito via fncRetornaOpcoesComissao).
VAL_CUSTO_ASSOCIADO string [A CONFIRMAR] Custo associado (sobrescrito via fncRetornaOpcoesComissao).
VAL_CUSTO_NAO_ASSOCIADO integer [A CONFIRMAR] Custo não associado (não usado diretamente no service).
PRC_COMISSAO string [A CONFIRMAR] Percentual de comissão (no service usa objCondicao.FncVAL_PERCENTUAL_COMISSAO()).
COD_CORRETOR_COMISSAO string [A CONFIRMAR] Código do corretor comissão (no service usa payload.COD_USUARIO).
DSC_TOKEN_LOJACOR string [A CONFIRMAR] Token Lojacor (há também TOKEN_LOJACORR; confirmar qual é enviado).
COD_SITUACAO_RECEITA string [A CONFIRMAR] Código situação receita.
TOKEN_LOJACORR string [A CONFIRMAR] Token Lojacor utilizado no service (payload.TOKEN_LOJACORR).
VAL_NAO_ASSOCIADO integer | null [A CONFIRMAR] No service: se > 0, usa valor retornado por fncRetornaOpcoesComissao para custo não associado.
IND_TIPO_USUARIO string [A CONFIRMAR] No código: public string IND_TIPO_USUARIO { get; internal set; } — confirmar se o model binder popula este campo.
DSC_GEOLOCALIZACAO_ACEITE_CORRETOR string [A CONFIRMAR] Geolocalização do aceite do corretor (salva na cotação).
DSC_ENDERECO_IP_ACEITE_CORRETOR string [A CONFIRMAR] IP do aceite do corretor (salva na cotação).
DSC_EMAIL_ACEITE_CORRETOR string [A CONFIRMAR] E-mail do aceite do corretor (salva na cotação).
DAT_ACEITE_CORRETOR_DATETIME string [A CONFIRMAR] Não utilizado (service grava DateTime.Now).
COD_CONVENCAO_COLETIVA string [A CONFIRMAR] Código da convenção coletiva.
NUM_QTDE_AFASTADOS string [A CONFIRMAR] CotacaoEspeciais (não utilizado no Novo padrão).
NUM_QTDE_APOSENTADOS string [A CONFIRMAR] CotacaoEspeciais (não utilizado no Novo padrão).
IND_TIP_SEGURO string [A CONFIRMAR] CotacaoEspeciais (não utilizado no Novo padrão).
IND_GRUPO string [A CONFIRMAR] CotacaoEspeciais (não utilizado no Novo padrão).
CapitalCobertura string [A CONFIRMAR] CotacaoEspeciais (não utilizado no Novo padrão).
infAdicionais string [A CONFIRMAR] CotacaoEspeciais (não utilizado no Novo padrão).
COD_CONDICOES_COMERCIAIS string [A CONFIRMAR] Condições comerciais.
COD_PRODUTO string [A CONFIRMAR] Código do produto.

Exemplo de requisição (ilustrativo)

POST {{base_url}}/api/Proposta/Novo HTTP/1.1
Authorization: Bearer {{token}}
Content-Type: application/json

{
  "COD_USUARIO": 4635,
  "IND_TIPO_USUARIO": "O",
  "COD_OPCOES_COMISSAO": "3706",
  "COD_CONDICOES_COMERCIAIS": "123",
  "COD_PRODUTO": "45",
  "COD_CONVENCAO_COLETIVA": "6789",
  "COD_ENTIDADE_PATRONAL": "111",
  "COD_ENTIDADE_LABORAL": "222",
  "COD_ATIVIDADE_RECEITA": "0000-0/00",
  "DAT_SITUACAO_RECEITA": "2026-02-11",
  "DSC_SITUACAO_RECEITA": "ATIVA",
  "NUM_IDENTIFICACAO": "12345678000199",
  "NOM_EMPRESA": "Empresa Exemplo LTDA",
  "COD_CIDADE": "3106200",
  "NUM_CEP": "30110-000",
  "DSC_ENDERECO": "Rua Exemplo, 100",
  "NOM_BAIRRO": "Centro",
  "NOM_CONTATO_SOLICITANTE": "Fulano",
  "NOM_EMAIL_SOLICITANTE": "fulano@exemplo.com",
  "NUM_TELEFONE_SOLICITANTE": "31999999999",
  "NOM_RESPONSAVEL_DA_EMPRESA": "Beltrano",
  "DSC_EMAIL_RESPONSAVEL_DA_EMPRESA": "beltrano@exemplo.com",
  "NUM_TELEFONE_RESPONSAVEL_DA_EMPRESA": "31988888888",
  "NUM_SEGURADOS": "10",
  "VAL_NAO_ASSOCIADO": 0,
  "TOKEN_LOJACORR": "token-exemplo",
  "DSC_GEOLOCALIZACAO_ACEITE_CORRETOR": "-19.9,-43.9",
  "DSC_ENDERECO_IP_ACEITE_CORRETOR": "203.0.113.10",
  "DSC_EMAIL_ACEITE_CORRETOR": "corretor@exemplo.com",
  "DSC_TERRITORIAL": "3106200;..."
}
Validações (legado): regras detalhadas levantadas nos trechos recebidos em 2.7. Permanece pendente apenas a validação complementar FncvalidarDadosBDadosCotacaoExpress(...) [A CONFIRMAR] (trecho não recebido).

Response — PropostaNovoViewModel (HTTP 200 no Swagger)

{
  "NUM_COTACAO": "11026",
  "NUM_VERSAO_CAPITAL": "1",
  "Impressao": null,
  "Mensagem": "Cotação gerada com sucesso.",
  "Error": false,
  "Resultado": true,
  "Bloqueio": false,
  "NUM_ADESAO": "98765"
}
Campo Tipo Descrição
NUM_COTACAO string Número da cotação gerada ou reutilizada.
NUM_VERSAO_CAPITAL string Número da versão do capital da cotação.
Impressao string Conteúdo/URL de impressão. [A CONFIRMAR]
Mensagem string Mensagem de sucesso/erro para o consumidor.
Error boolean Indica falha lógica/tratada no serviço (mesmo que HTTP 200).
Resultado boolean Indica sucesso na gravação da cotação.
Bloqueio boolean True quando UF do corretor diverge da UF da cidade da cotação (status "B").
NUM_ADESAO string Número da adesão (se existir/foi localizada). Pode vir vazio.

Observação: o Swagger só explicita 200. No código, falhas são sinalizadas por Error=true e Mensagem (possivelmente ainda com HTTP 200). [A CONFIRMAR] se existe algum ExceptionFilter/middleware que mapeie exceções para 4xx/5xx.


2) Comportamento (Legado) — regras, validações e fluxo

2.1 Pré-condições

  • Requer token válido (controller [Authorize]).
  • payload.COD_USUARIO é usado como identificador do corretor/solicitante no fluxo atual (ver riscos em Segurança).

2.2 Decisão de status da cotação (IND_STATUS_ATUAL)

O service define o status antes de gravar:

1) Se objCotacao.FncCotacaoPME(payload.COD_OPCOES_COMISSAO) for true → status "E". 2) Senão, se payload.COD_USUARIO estiver na whitelist {50174, 4521, 1, 1563, 4764, 2812, 2434} → status "E". 3) Senão: - consulta dados do corretor (objCorretor.FncConsultarDadosCorretor(...)); - se DAT_CORRETOR.COD_ESTADOobjCidade.FncCOD_ESTADO() → status "B" e viewModel.Bloqueio=true; - caso contrário → status "E".

[A CONFIRMAR] significado formal dos status e como se relacionam com a lista (A/E/N/C/X/P/R/T) descrita em outros endpoints do controller.

2.3 Cálculo de abrangência (IND_DENTRO_ABRANGENCIA)

No service:
- calcula "S"/"N" verificando se payload.COD_CIDADE está contido em payload.DSC_TERRITORIAL (string contains).

No método VB fncGravarCotacaoExpress:
- no INSERT TB_COTACAO, força @IND_DENTRO_ABRANGENCIA = 'S' (comentário: “não é mais possível cotar fora da região de abrangência”).

➡️ Divergência interna do legado: o cálculo no service pode resultar "N", mas a persistência pode gravar "S".

2.4 Regras de consumo do payload (observado no código)

Campos do payload que são sobrescritos pelo service (o que o cliente enviar é ignorado)

  • IND_TIPO_SOLICITANTE → força "C".
  • COD_SOL_CORRETOR → força payload.COD_USUARIO.
  • IND_CONHECEU_PASI → força "N".
  • IND_ACOMPANHAMENTO_SITUACAO → força "P".
  • COD_RESPONSAVEL → força "173".
  • Campos de capital/custos/módulos:
  • IND_TIPO_CAPITAL, QTD_VAL_COBERTURA, VAL_COBERTURA, VAL_FATURA_MINIMA, COD_MODULO, COD_MODULO_ADICIONAL, VAL_CUSTO_ASSOCIADO
    → são preenchidos a partir de Entidade.fncRetornaOpcoesComissao(payload.COD_OPCOES_COMISSAO, ...).
  • PRC_COMISSAO → preenchido via OpcoesComissao.FncVAL_PERCENTUAL_COMISSAO().

Campos do payload consultados/consumidos no fluxo do PropostaService.Novo(...)

  • Identidade/escopo: COD_USUARIO, COD_OPCOES_COMISSAO, COD_CIDADE, COD_CONDICOES_COMERCIAIS, COD_PRODUTO, COD_CONVENCAO_COLETIVA.
  • Dados empresa/contato: NUM_IDENTIFICACAO, NOM_EMPRESA, NUM_CEP, DSC_ENDERECO, NOM_BAIRRO, NOM_CONTATO_SOLICITANTE, NOM_EMAIL_SOLICITANTE, NUM_TELEFONE_SOLICITANTE, NOM_RESPONSAVEL_DA_EMPRESA, DSC_EMAIL_RESPONSAVEL_DA_EMPRESA, NUM_TELEFONE_RESPONSAVEL_DA_EMPRESA.
  • Aceite do corretor: DSC_GEOLOCALIZACAO_ACEITE_CORRETOR, DSC_ENDERECO_IP_ACEITE_CORRETOR, DSC_EMAIL_ACEITE_CORRETOR (data do aceite é sempre DateTime.Now).
  • Regra de abrangência: DSC_TERRITORIAL (compara COD_CIDADE por substring para setar IND_DENTRO_ABRANGENCIA).
  • Capital: NUM_SEGURADOS.
  • Não associado: VAL_NAO_ASSOCIADO (apenas para decidir se aplica custo não associado; o valor aplicado vem de fncRetornaOpcoesComissao).

Campos presentes no DTO, mas não usados diretamente nesse método

Exemplos (não-exaustivo, baseado somente no DTO enviado):

  • VAL_CUSTO_NAO_ASSOCIADO (existe como int no DTO, mas o service decide custo não associado via VAL_NAO_ASSOCIADO + retorno de fncRetornaOpcoesComissao).
  • DSC_TOKEN_LOJACOR vs TOKEN_LOJACORR: o service usa payload.TOKEN_LOJACORR. [A CONFIRMAR] qual campo o Front realmente envia e qual nome o Swagger expõe.
  • DAT_ACEITE_CORRETOR_DATETIME: não utilizado (data vem de DateTime.Now).
  • Bloco CotacaoEspeciais: NUM_QTDE_AFASTADOS, NUM_QTDE_APOSENTADOS, IND_TIP_SEGURO, IND_GRUPO, CapitalCobertura, infAdicionais.

Ponto de atenção de binding/serialização

  • IND_TIPO_USUARIO está declarado como public string IND_TIPO_USUARIO { get; internal set; }.
    [A CONFIRMAR] se o model binder/JSON consegue popular esse campo (caso contrário, ele pode chegar sempre null no service).

2.5 Reuso de cotação existente (idempotência parcial)

No VB fncGravarCotacaoExpress (inclusão): - busca cotação existente em TB_COTACAO com: - COD_SOL_CORRETOR = <corretor>, - NUM_IDENTIFICACAO = <identificação>, - COD_RESPONSAVEL = 173, - IND_STATUS_ATUAL = 'E', - e filtros adicionais: - não PME: patronal/laboral, - PME: COD_CONDICOES_COMERCIAIS. - se existir, reutiliza NUM_COTACAO e grava somente nova versão via CotacaoCapital.fncGravar(...).

Isso cria uma forma de “idempotência natural” para o mesmo corretor + identificação (com restrições), mas: - não protege contra concorrência, - não é baseado em um identificador externo explícito (ex.: external_reference).

2.5.1 Histórico de status da cotação (TB_STATUS_COTACAO) — RegrasNegocio.CotacaoStatus

Existe persistência do histórico em TB_STATUS_COTACAO (chave por NUM_COTACAO + DAT_STATUS), via classe CotacaoStatus:

  • CotacaoStatus.fncGravar(...) insere (ou atualiza) em TB_STATUS_COTACAO os campos:
  • NUM_COTACAO, DAT_STATUS, IND_STATUS, COD_RESPONSAVEL, NOM_ESTACAO, DAT_ULTIMA_ATUALIZACAO.
  • NOM_ESTACAO vem de objNegocios.fncNomMaquina.
  • DAT_ULTIMA_ATUALIZACAO é Sistema.fncDataAtual (data/hora atual).
  • A validação de duplicidade de status foi desabilitada (historicamente havia bloqueio de repetição; hoje fncValidarchave(...) retorna True), permitindo repetir IND_STATUS para a mesma cotação.

Mapa de descrição (CotacaoStatus.FncDescricaoStatus()):

  • A → Aberto
  • E → Enviada
  • C → Cancelada
  • X → Expirada
  • P → Aprovada
  • R → Recusada

Operação de rollback de status:

  • CotacaoStatus.FncExcluirUltimoStatus(NUM_COTACAO, ...) remove o último registro (maior DAT_STATUS) quando existir mais de um status e atualiza TB_COTACAO.DAT_STATUS_ATUAL/TB_COTACAO.IND_STATUS_ATUAL para o penúltimo status.

2.5.2 Gravação de capital (CotacaoCapital.fncGravar) — versionamento por cotação

O método RegrasNegocio.CotacaoCapital.fncGravar(...) (classe CotacaoCapital) executa a persistência de uma versão de capital vinculada à cotação:

  • Quando indOperacao = "I" (inclusão):
  • Determina NUM_VERSAO_CAPITAL via:
    • SELECT MAX(NUM_VERSAO_CAPITAL)+1 FROM TB_CAPITAL_COTACAO WHERE NUM_COTACAO = <NUM_COTACAO>
    • Se nulo → assume 1.
  • Faz INSERT em TB_CAPITAL_COTACAO com (principais colunas):
    • NUM_COTACAO, NUM_VERSAO_CAPITAL, IND_TIPO_CAPITAL, VAL_COBERTURA, QTD_VAL_COBERTURA, VAL_FATURA_MINIMA, NUM_SEGURADOS, VAL_CUSTO_ASSOCIADO, VAL_CUSTO_NAO_ASSOCIADO, COD_MODULO, COD_MODULO_ADICIONAL, COD_CORRETOR_COMISSAO, PRC_COMISSAO, COD_OPCOES_COMISSAO, DSC_TOKEN_LOJACOR, NUM_AFASTADO, NUM_APOSENTADO_INVALIDEZ, NUM_SOCIOS, além de NOM_ESTACAO e DAT_ULTIMA_ATUALIZACAO.
  • Pós-insert: se COD_MODULO não é nulo, executa:

    • DELETE FROM TB_COBERTURA_COTACAO WHERE NUM_COTACAO = <NUM_COTACAO> AND NUM_VERSAO_CAPITAL = <NUM_VERSAO_CAPITAL>
    • (isso sugere “reset” das coberturas da versão antes de regravar/repovoar em outra etapa).
  • Quando não é inclusão:

  • Faz UPDATE TB_CAPITAL_COTACAO pelos campos acima, filtrando por NUM_COTACAO + NUM_VERSAO_CAPITAL.

Observações técnicas relevantes:

  • O versionamento por MAX(...)+1 é suscetível a condição de corrida em cenários concorrentes (geração de versões simultâneas). [A CONFIRMAR] se existe constraint/lock/serialização no banco mitigando isso.
  • O método abre/fecha transação quando transacao = True e registra erro genérico "Ocorreu uma falha na operação..." em caso de exceção.

Atenção (potencial conflito com o reuso): além da busca por cotação existente em fncGravarCotacaoExpress, existe a validação de chave fncValidarChaveCotacaoExpress (chamada em FncvalidarDadosBDadosCotacaoExpress) que, quando IndOperacao = Operacao.Inclusao, bloqueia a criação se houver cotação com a mesma chave e IND_STATUS_ATUAL diferente de 'X', 'P' e 'R'.

  • [A CONFIRMAR] a ordem exata dessas etapas no fluxo (fncGravarCotacaoExpress/PropostaService.Novo): se a validação roda antes da busca de reuso; e em que momento IndOperacao muda de Inclusao para Alteracao (quando uma cotação existente é “recarregada” para gerar nova versão).

2.5.3 CotacaoCapital — construtor e modo de operação (indOperacao)

No trecho recebido, o construtor de RegrasNegocio.CotacaoCapital faz uma carga inicial de TB_CAPITAL_COTACAO quando recebe NUM_COTACAO e NUM_VERSAO_CAPITAL:

  • Executa: SELECT <sqlColunas> FROM TB_CAPITAL_COTACAO WHERE NUM_COTACAO=@NUM_COTACAO AND NUM_VERSAO_CAPITAL=@NUM_VERSAO_CAPITAL.
  • Se não encontrar registro, seta indOperacao = "I" (inclusão).
  • Se encontrar, faz SubAtribuiCampos(dat) e seta indOperacao = "A" (alteração).
  • Se parObjDados Is Nothing, cria objDados com conexão própria, marca transacao=True e geraLog=True (controle de transação e log dentro da classe).

2.5.4 CotacaoCapital — consultas auxiliares e regras de lista

Foram observados métodos auxiliares que consultam versões/cotações e podem impactar o entendimento do ciclo de vida da cotação:

  • FncRetornaListaCotacaoVersao(parNum_identificacao, parDatEntregaRecepcao, dat, msg):
  • Retorna cotações pendentes (IND_STATUS_ATUAL in ('A','E')) e também expiradas (IND_STATUS_ATUAL='X') nos últimos 6 meses, desde que não exista adesão em TB_ADESAO para (NUM_COTACAO, NUM_VERSAO_CAPITAL).
  • Filtra por B.DAT_INCLUSAO <= DATEADD(hh,23,@DAT_ENTREGA_RECEPCAO) e por B.NUM_IDENTIFICACAO = '<parNum_identificacao>' (atenção: concatenação direta de string no SQL).
  • Campos retornados incluem: A.NUM_COTACAO, NUM_VERSAO_CAPITAL, VAL_COBERTURA, NUM_SEGURADOS, custos e B.COD_CONVENCAO_COLETIVA.
  • FncRetornaListaCotacaoVersao(parNumCotacao, dat, msg):
  • Retorna dados de capital e módulo para uma cotação, com LEFT JOIN TB_MODULO (principal e adicional) e uso da função dbo.FNC_Busca_Descricao_Tipo_Capital(IND_TIPO_CAPITAL).

2.5.5 CotacaoCapital — cópia, exclusão e ajustes “Web”

Outros comportamentos de persistência observados:

  • FncCopiarCotacaoVersao(parNumCotacaoDestino, msg):
  • Cria nova versão em TB_CAPITAL_COTACAO (via fncGravar) copiando dados da versão original e depois copia coberturas via CotacaoCobertura (itera datCoberturas e grava linha a linha).
  • FncExcluir(msg):
  • Antes de excluir, valida uso em TB_ADESAO (não permite excluir se houver adesão para a chave (NUM_COTACAO, NUM_VERSAO_CAPITAL)).
  • Exclui primeiro TB_COBERTURA_COTACAO e depois TB_CAPITAL_COTACAO.
  • FncAtualizaTipoCustoSelecionado(parTipoCustoSelecionado, msg):
  • Atualiza TB_CAPITAL_COTACAO.IND_CUSTO_SELECIONADO_WEB para a chave (NUM_COTACAO, NUM_VERSAO_CAPITAL).

Pontos de atenção (impacto na API Nova) - Há múltiplos trechos com SQL montado por concatenação (ex.: filtro por NUM_IDENTIFICACAO), o que merece revisão por risco de SQL Injection e por inconsistência de parâmetros. - sqlColunas inclui IND_CUSTO_SELECIONADO_WEB e DAT_INCLUSAO_CAPITAL, mas no trecho de fncGravar recebido a INSERT/UPDATE não inclui esses campos (o primeiro é atualizado por método específico; o segundo pode depender de default/trigger) — [A CONFIRMAR].

2.6 Criação/atualização de Adesão e tentativa de retorno de NUM_ADESAO

Após persistir a cotação (e suas versões), o fluxo tenta criar/atualizar uma adesão vinculada à cotação e, em seguida, consultá-la para preencher NUM_ADESAO no retorno da API.

2.6.1 Gravação de adesão (dentro de Cotacao.vb)

A rotina que monta os dados de adesão não está em Adesao.vb: ela é um método privado em Cotacao.vb:

  • Cotacao.fncGravaAdesaoCotacaoExpress(parCapitalCotacao, parNUM_ADESAO, ...)

Comportamento observado:

1) Instancia RegrasNegocio.Adesao: - se parNUM_ADESAO > 0 → carrega adesão existente (SELECT ... FROM TB_ADESAO WHERE NUM_ADESAO=@NUM_ADESAO). - senão → cria objeto em Inclusão (sem carregar registro).

2) Default de status quando não existe registro em TB_ADESAO: - IND_STATUS_ATUAL = "A" (padrão) exceto quando objNegocios.fncDsc_Funcionalidade = "MIP", que define "T". - DAT_STATUS_ATUAL é Sistema.fncDataAtualSemMilesimos.

3) Preenche campos (principais hard-codes e regras) e chama ObjADESAO.fncGravar(...):

  • Gerais:
  • DAT_ENTREGA_RECEPCAO = DAT_INCLUSAO (contexto da cotação)
  • DAT_VIGENCIA = ""
  • NUM_COTACAO = NUM_COTACAO
  • NUM_VERSAO_CAPITAL = parCapitalCotacao.FncNUM_VERSAO_CAPITAL
  • IND_MEIO_RECEBIMENTO = "W"
  • COD_USUARIO_RESPONSAVEL = 173 (hard-coded)
  • Flags: IND_ATUALIZAR_DADOS_CLIENTE="N", IND_DESMEBRAMENTO="N", IND_FORMA_FATURAMENTO="D", IND_TROCA_CORRETAGEM="N", IND_ATUALIZAR_DADOS_CORRETOR="N"

  • Cliente (endereço de cobrança espelha endereço principal):

  • NOM_CLIENTE = NOM_EMPRESA
  • DSC_IDENTIFICACAO_CLIENTE = NUM_IDENTIFICACAO
  • COD_ATIVIDADE_CLIENTE = COD_ATIVIDADE_RECEITA (se não nulo)
  • DSC_ENDERECO_CLIENTE = DSC_ENDERECO
  • NOM_BAIRRO_CLIENTE = NOM_BAIRRO
  • COD_CIDADE_CLIENTE = COD_CIDADE
  • NUM_CEP_CLIENTE = NUM_CEP
  • DSC_ENDERECO_COBRANCA = DSC_ENDERECO
  • NOM_BAIRRO_COBRANCA = NOM_BAIRRO
  • COD_CIDADE_COBRANCA = COD_CIDADE
  • NUM_CEP_COBRANCA = NUM_CEP
  • IND_CLIENTE_ASSOCIADO_SINDICATO:

    • se não FncCotacaoPME(COD_OPCOES_COMISSAO)"S"
    • senão → "N"
  • Corretor:

  • COD_CORRETOR_CORRETOR = COD_SOL_CORRETOR
  • IND_NAO_ENVIAR_CLIENTE = "N"
  • COD_SEGURADORA_CORRETOR = 5142 (hard-coded)

  • Coberturas / faturamento:

  • COD_MODULO = parCapitalCotacao.FncCOD_MODULO
  • COD_MODULO_ADICIONAL = parCapitalCotacao.FncCOD_MODULO_ADICIONAL
  • VAL_CAPITAL_SEGURADO = parCapitalCotacao.FncVAL_COBERTURA
  • VAL_CUSTO_SEGURADO = parCapitalCotacao.FncVAL_CUSTO_ASSOCIADO
  • NUM_SEGURADOS_ATIVOS = parCapitalCotacao.FncNUM_SEGURADOS
  • VAL_FATURA_MIN = parCapitalCotacao.FncVAL_FATURA_MINIMA
  • IND_CORRIGIR_CAPITAL = "E"

  • Entidades / demais:

  • COD_ENTIDADE_PATRONAL = COD_ENTIDADE_PATRONAL
  • COD_ENTIDADE_LABORAL = COD_ENTIDADE_LABORAL
  • IND_ENCAMPACAO="N", IND_MODALIDADE_CONTRATACAO="C", IND_TIPO_CAPITAL_SEGURADO="U", IND_SOCIOS_INCLUSOS="N"
  • IND_PENDENCIAS_MANUAIS="N", IND_ACEITA_AFASTADOS="N", IND_ACEITA_APOSENTADOS="N", IND_ACEITA_ADEQUACAO_CONTRATO="S"
  • COD_PRODUTO = (se nulo → 1; senão COD_PRODUTO)
  • COD_CIDADE_PRESTACAO_SERV = COD_CIDADE
  • COD_OPCOES_COMISSAO = parCapitalCotacao.FncCOD_OPCOES_COMISSAO
  • IND_EMITIR_ETIQUETA="S", IND_ENVIAR_COBRANCA_PARA="E", NUM_DIA_VENCIMENTO=31
  • NUM_MESES_PERMANENCIA=12, IND_TIPO_SEGURADO="F", IND_TIPO_LAYOUT_IMPORTACAO="P"

Detalhes observados em RegrasNegocio.Adesao.fncGravar(...):

  • Inclusão (IndOperacao = Operacao.Inclusao):
  • Gera NUM_ADESAO via SELECT MAX(NUM_ADESAO)+1 FROM TB_ADESAO (NOLOCK) (se nulo → 1).
  • Executa INSERT INTO TB_ADESAO (...) VALUES (...) com um conjunto grande de colunas (cliente, corretor, cobrança, produto, custos, aceites, flags etc.).
    • DAT_INCLUSAO é gravado como CURRENT_TIMESTAMP (não vem do parâmetro).
  • Após inserir, cadastra documentos obrigatórios da adesão:
    • Lista documentos ativos (DocumentoAdesao.FncListaAtivos) e, para cada documento, cria AdesaoDocumento(NUM_ADESAO, COD_DOCUMENTO) setando IND_OBRIGATORIO conforme a origem, e chama ObjAdesaoDocumentos.fncGravar(...).
  • Registra status em histórico via AdesaoStatus: grava NUM_ADESAO, IND_STATUS = IND_STATUS_ATUAL e DAT_STATUS = DAT_STATUS_ATUAL.

  • Alteração (demais operações):

  • Executa UPDATE TB_ADESAO SET ... WHERE NUM_ADESAO = @NUM_ADESAO atualizando o mesmo conjunto de colunas (inclui DAT_INCLUSAO via parâmetro).

  • Controle de transação depende do flag transacao (AbreTransacao/FechaTransacao), e mensagens de erro retornam texto genérico para o usuário.

[A CONFIRMAR]: nomes exatos das tabelas/SQL usados por DocumentoAdesao, AdesaoDocumento e AdesaoStatus; e o catálogo completo de valores possíveis de IND_STATUS_ATUAL/transições de status.

2.6.2 Consulta de adesão (Adesao.FncConsultarAdesao)

Após a gravação, há uma tentativa de consulta para preencher NUM_ADESAO:

  • Adesao.FncConsultarAdesao(parCOD_CORRETOR, parCOD_CLIENTE, parNUM_ADESAO, parIND_STATUS_ATUAL, parNUM_COTACAO, dat, msg, parVERSAO_CAPITAL:=0)

Características da consulta:

  • Fonte principal: TB_ADESAO a (NOLOCK).
  • Joins relevantes:
  • TB_CIDADE c (cidade cobrança), TB_CIDADE I (cidade corretor), TB_CIDADE CP (cidade prestação serviço)
  • TB_CORRETOR o
  • TB_ENTIDADE p (patronal) e TB_ENTIDADE l (laboral)
  • TB_ATIVIDADE t, TB_GRUPO_CLIENTE g
  • TB_ADESAO_DOCUMENTO_ANEXO d (por NUM_ADESAO e COD_DOCUMENTO = 1)
  • TB_ADESAO_CONTATO_CLIENTE AC (departamento 13), TB_ADESAO_CONTATO_CLIENTE AC2 (departamento 20 — e-mail de fatura)
  • TB_CAPITAL_COTACAO CC e TB_COTACAO CT (por NUM_COTACAO)
  • Subquery em TB_CORRETOR_CONTATO OC (departamento 13) para DSC_EMAIL_CONTATO_CORRETOR.
  • Filtros são adicionados dinamicamente quando parâmetros não são nulos:
  • A.COD_CORRETOR_CORRETOR, A.COD_CLIENTE_ATUALIZAR, A.NUM_ADESAO, A.IND_STATUS_ATUAL, A.NUM_COTACAO.
  • Se parVERSAO_CAPITAL > 0CC.NUM_VERSAO_CAPITAL = parVERSAO_CAPITAL.
  • Ordenação: ORDER BY A.DAT_INCLUSAO DESC.
  • Retorno: True quando há linhas; caso contrário devolve mensagem "Nenhuma Adesão Encontrada.".

2.7 Validações de campos (VB) — FncValidarDadosCotacaoExpress e CotacaoCapital.FncValidarDados

Objetivo: registrar o que é validado/normalizado no legado para orientar o contrato e as validações server-side da API Nova, sem depender do front.

2.7.1 Cotacao.FncValidarDadosCotacaoExpress (regras observadas)

Regras gerais - Se não for PME (Not FncCotacaoPME(COD_OPCOES_COMISSAO)): - COD_ENTIDADE_PATRONAL obrigatório e válido (decimal). - COD_ENTIDADE_LABORAL obrigatório e válido (decimal). - COD_RESPONSAVEL obrigatório (decimal). - IND_TIPO_SOLICITANTE obrigatório (string). - IND_CANAL_VENDA é forçado para "P" (normalização). - COD_OPCOES_COMISSAO é validado (há validação como string no início e novamente como inteiro mais ao fim — ver pendência em 8)).

Regras por IND_TIPO_SOLICITANTE (normalização de campos) - "S" (Sucursal): obrigatórios COD_SOL_SEGURADORA_SUCURSAL, COD_SOL_SUCURSAL; zera COD_SOL_CORRETOR, COD_SOL_AGENTE, COD_SOL_FUNCIONARIO, COD_SOL_ENTIDADE, NOM_SOLICITANTE. - "C" (Corretor): obrigatório COD_SOL_CORRETOR; zera COD_SOL_SEGURADORA_SUCURSAL, COD_SOL_SUCURSAL, COD_SOL_AGENTE, COD_SOL_FUNCIONARIO, COD_SOL_ENTIDADE, NOM_SOLICITANTE. - "A" (Agente): obrigatório COD_SOL_AGENTE; zera COD_SOL_SEGURADORA_SUCURSAL, COD_SOL_SUCURSAL, COD_SOL_CORRETOR, COD_SOL_FUNCIONARIO, COD_SOL_ENTIDADE, NOM_SOLICITANTE. - "B" (Contabilidade): obrigatório NOM_SOLICITANTE; zera COD_SOL_SEGURADORA_SUCURSAL, COD_SOL_SUCURSAL, COD_SOL_CORRETOR, COD_SOL_FUNCIONARIO, COD_SOL_ENTIDADE, COD_SOL_AGENTE. - "E" (Empresa): obrigatório NOM_SOLICITANTE; zera COD_SOL_SEGURADORA_SUCURSAL, COD_SOL_SUCURSAL, COD_SOL_CORRETOR, COD_SOL_FUNCIONARIO, COD_SOL_ENTIDADE, COD_SOL_AGENTE. - "F" (Interno/Funcionário): obrigatório COD_SOL_FUNCIONARIO; zera COD_SOL_SEGURADORA_SUCURSAL, COD_SOL_SUCURSAL, COD_SOL_CORRETOR, COD_SOL_ENTIDADE, COD_SOL_AGENTE, NOM_SOLICITANTE. - "T" (Entidade): obrigatório COD_SOL_ENTIDADE; zera COD_SOL_SEGURADORA_SUCURSAL, COD_SOL_SUCURSAL, COD_SOL_CORRETOR, COD_SOL_FUNCIONARIO, COD_SOL_AGENTE, NOM_SOLICITANTE.

Parâmetros de negociação (via parCapitalCotacao) - PRC_COMISSAO, NUM_SEGURADOS, VAL_COBERTURA, VAL_CUSTO_ASSOCIADO: obrigatórios e > 0. - VAL_CUSTO_NAO_ASSOCIADO: validado quando informado.

Contato / responsável - NOM_CONTATO_SOLICITANTE, NOM_EMAIL_SOLICITANTE, NUM_TELEFONE_SOLICITANTE são validados com mensagens de obrigatoriedade. - NOM_RESPONSAVEL_DA_EMPRESA, DSC_EMAIL_RESPONSAVEL_DA_EMPRESA, NUM_TELEFONE_RESPONSAVEL_DA_EMPRESA são validados com mensagens de obrigatoriedade. - NUM_FAX_SOLICITANTE é validado quando informado.

Conheceu o PASI - Se IND_CONHECEU_PASI = "O", então DSC_CONHECEU_PASI torna-se obrigatório.

Empresa - NUM_IDENTIFICACAO obrigatório (string numérica); valida CNPJ (14) ou CPF (11) quando o tamanho corresponde. - NOM_EMPRESA, NUM_CEP, DSC_ENDERECO, NOM_BAIRRO, COD_CIDADE, NOM_CONTATO são validados com mensagens de obrigatoriedade.

Tipo de associado - IND_TIPO_ASSOCIADO validado; pode ser sobrescrito conforme entidade (regional/nacional/sindical): 15→"C", 1078→"F", 3927→"J". - Se IND_TIPO_ASSOCIADO = "O", DSC_TIPO_ASSOCIADO torna-se obrigatório.

Datas e status (normalização) - DAT_INCLUSAO = dataAtual. - DAT_VALIDADE = dataAtual + DIAS_EXPIRACAO. - DAT_STATUS_ATUAL = dataAtual. - NOM_ESTACAO = objNegocios.fncNomMaquina. - DAT_ULTIMA_ATUALIZACAO = DAT_INCLUSAO. - IND_ACOMPANHAMENTO_SITUACAO validado; se "F", IND_MOTIVO torna-se obrigatório.

Arquivos - Se NOM_ARQUIVO_ORIGINAL informado, NOM_ARQUIVO_SERVIDOR torna-se obrigatório.

2.7.2 CotacaoCapital.FncValidarDados (regras observadas)

No trecho recebido, a validação de capital (CotacaoCapital) aplica regras de obrigatoriedade e consistência:

  • NUM_COTACAO obrigatório.
  • IND_TIPO_CAPITAL obrigatório; VAL_COBERTURA obrigatório.
  • Se IND_TIPO_CAPITAL = "U", então QTD_VAL_COBERTURA = Nothing; caso contrário QTD_VAL_COBERTURA deve ser inteiro positivo.
  • VAL_FATURA_MINIMA obrigatório e > 0.
  • NUM_SEGURADOS obrigatório e > 0.
  • VAL_CUSTO_ASSOCIADO obrigatório e > 0.
  • VAL_CUSTO_NAO_ASSOCIADO é validado quando informado (a mensagem indica “maior que zero”, mas a validação recebida é fncSetaPropriedadeDecimal).
  • COD_MODULO e COD_MODULO_ADICIONAL validados; se informar módulo adicional sem módulo principal, retorna erro.
  • COD_CORRETOR_COMISSAO validado como inteiro.
  • PRC_COMISSAO validado como decimal positivo.
  • COD_OPCOES_COMISSAO validado (no trecho recebido está como “decimal positivo”, embora a semântica aparente seja de código/inteiro) — [A CONFIRMAR].
  • DSC_TOKEN_LOJACOR validado quando informado.
  • Normalizações: define NOM_ESTACAO = objNegocios.fncNomMaquina e DAT_ULTIMA_ATUALIZACAO = dataAtual (via Sistema.fncDataAtual).

2.7.2.1 CotacaoCapital.FncValidarDadosCotacaoEspeciais (diferenças)

Existe uma validação paralela para o fluxo “Especiais”:

  • A estrutura é muito similar à validação padrão, porém no trecho recebido alguns campos aparecem com flag False (ex.: VAL_COBERTURA, VAL_FATURA_MINIMA, VAL_CUSTO_ASSOCIADO) — [A CONFIRMAR] se isso significa “não obrigatório” no fluxo especial ou se é apenas uso diferente do helper fncSetaPropriedade*.
  • Indício: esse caminho tende a ser usado em conjunto com fncGravarCotacaoEspeciais (método de gravação específico).

2.7.3 Cotacao.FncvalidarDadosBDadosCotacaoExpress (validações no BD)

Essa etapa valida regras que dependem de consulta ao banco antes de gravar:

1) fncValidarChaveCotacaoExpress(parCapitalCotacao, ParObjDados, ParObjMensagem)
2) fncPertenceListaNegra(ParObjDados, ParObjMensagem)

Retorna True somente se ambas passarem.

2.7.3.1 fncValidarChaveCotacaoExpress — bloqueio de duplicidade “Cotação Express”
  • Só executa quando IndOperacao = Operacao.Inclusao. Caso contrário, retorna True.
  • Consulta:
  • TB_COTACAO (alias A) INNER JOIN TB_CAPITAL_COTACAO (alias B)
  • filtros:
  • SELECT (com JOIN em TB_CAPITAL_COTACAO) em fncValidarChaveCotacaoExpress(...) para bloquear duplicidade quando há uma cotação ativa (status diferente de 'X', 'P', 'R').
    • A.NUM_IDENTIFICACAO = @NUM_IDENTIFICACAO
    • A.COD_ENTIDADE_PATRONAL e A.COD_ENTIDADE_LABORAL (comparação direta ou IS NULL, conforme o valor atual das propriedades)
    • B.VAL_CUSTO_ASSOCIADO = @VAL_CUSTO_ASSOCIADO
    • B.NUM_SEGURADOS = @NUM_SEGURADOS
    • B.COD_CORRETOR_COMISSAO = @COD_CORRETOR_COMISSAO
    • A.IND_STATUS_ATUAL <> 'X', <> 'P', <> 'R'
  • Se não encontrar registro, a validação passa.
  • Se encontrar, bloqueia e monta uma mensagem com link HTML para o portal:
  • "Já existe outra cotação com os dados informados. Número da Cotação: <a href="https://corretor.portalpasi.com.br/propostasPendentes"> ... </a>."

Pontos de atenção - COD_ENTIDADE_PATRONAL/COD_ENTIDADE_LABORAL entram na SQL por concatenação (não parametrizado) quando não são Nothing. - A mensagem contém HTML; confirmar como isso é serializado/consumido no canal Web/API.

2.7.3.2 fncPertenceListaNegra — restrição de cliente/corretor
  • Verifica cliente:
  • ListaRestricaoCliente.FncClienteEstaListaNegra(NUM_IDENTIFICACAO, estaNaLista, ParObjMensagem)
  • se estaNaLista = True, bloqueia com mensagem: "O Cliente não pode realizar cotações. Consulte a Central PASI" (tipo Erro).
  • Verifica corretor (quando COD_SOL_CORRETOR não é Nothing):
  • carrega corretor (RegrasNegocio.Corretor) e exige que exista CPF ou CNPJ.
  • ListaRestricaoCorretor.FncCorretorEstaListaNegra(identificacaoCorretor, estaNaLista, ParObjMensagem)
  • se estaNaLista = True, a função encerra (bloqueia o fluxo); o texto exibido depende do que ParObjMensagem recebeu no processo.

Ponto de atenção - Em Catch, há MsgBox(...) (comportamento típico de cliente Windows). Confirmar como isso se comporta no fluxo Web/API.

2.7.4 Observação sobre a biblioteca de validação [A CONFIRMAR]

Os métodos fncSetaPropriedade* recebem um parâmetro booleano que aparenta indicar “obrigatório”. Em diversos campos o código passa False, mas a mensagem emitida diz “obrigatório”. Sem a implementação do validador, esta ficha registra o comportamento/mensagem observado e deixa a semântica exata como pendência em 8).

3) Persistência — tabelas, queries e SPs

3.1 Tabelas tocadas diretamente (SQL explícito nos trechos enviados)

Abaixo, somente o que aparece explicitamente nos trechos recebidos (SQL visível):

  • TB_COTACAO
  • INSERT/UPDATE dentro de Cotacao.fncGravarCotacaoExpress(...).
  • TB_STATUS_COTACAO (via CotacaoStatus.fncGravar(...))
  • Inserção do status atual da cotação (por exemplo IND_STATUS_ATUAL = 'E'/'B').
  • TB_CAPITAL_COTACAO (via CotacaoCapital.fncGravar(...))
  • SELECT MAX(NUM_VERSAO_CAPITAL)+1 ... WHERE NUM_COTACAO = <NUM_COTACAO> para numerar NUM_VERSAO_CAPITAL.
  • INSERT/UPDATE da versão de capital (campos de capital/custos/módulos/comissão/token etc.).
  • SELECT por chave (NUM_COTACAO, NUM_VERSAO_CAPITAL) no construtor CotacaoCapital.New(...) (consulta TB_CAPITAL_COTACAO com lista fixa de colunas).
  • TB_COBERTURA_COTACAO (via CotacaoCapital.fncGravar(...))
  • DELETE das coberturas da versão (NUM_COTACAO + NUM_VERSAO_CAPITAL) quando COD_MODULO não é nulo.
  • TB_ADESAO (via Adesao.fncGravar(...))
  • SELECT MAX(NUM_ADESAO)+1 FROM TB_ADESAO (NOLOCK) para numerar a adesão.
  • INSERT INTO TB_ADESAO (...) VALUES (...) (usa CURRENT_TIMESTAMP em DAT_INCLUSAO).
  • UPDATE TB_ADESAO SET ... WHERE NUM_ADESAO=@NUM_ADESAO.

[A CONFIRMAR]: nomes exatos das tabelas/SQL utilizados por DocumentoAdesao, AdesaoDocumento e AdesaoStatus (cadastro de documentos e histórico de status da adesão), pois esses objetos são chamados dentro de Adesao.fncGravar(...) mas seus fncGravar não foram fornecidos. - TB_MODULO — usado para retornar nome de módulo principal/adicional em consultas auxiliares de capital. - dbo.FNC_Busca_Descricao_Tipo_Capital — função SQL usada para descrever IND_TIPO_CAPITAL em consultas auxiliares. - TB_CAPITAL_COTACAO.IND_CUSTO_SELECIONADO_WEB — atualizado via FncAtualizaTipoCustoSelecionado.

3.2 Tabelas/SPs tocadas indiretamente (não vieram nos trechos)

  • TB_OPCOES_COMISSAO + TB_CONDICOES_COMERCIAIS
  • Lógica de PME em Cotacao.FncCotacaoPME(...).
  • Dados de corretor e cidade
  • Corretor.FncConsultarDadosCorretor(...) e Cidade.FncCOD_ESTADO().
  • Definição de parâmetros de capital por opção de comissão
  • Entidade.fncRetornaOpcoesComissao(...).
  • Documentos e status de adesão (chamados dentro de Adesao.fncGravar(...))
  • DocumentoAdesao.FncListaAtivos(...)
  • AdesaoDocumento.fncGravar(...)
  • AdesaoStatus.fncGravar(...)
  • [A CONFIRMAR] tabelas/SQL envolvidos nessas gravações.

3.3 Efeitos colaterais

  • Cotação e versão de capital podem ser gravadas em uma mesma transação (dependendo do uso de objDados/transacao dentro de fncGravarCotacaoExpress e CotacaoCapital.fncGravar).
  • O versionamento de capital usa MAX(NUM_VERSAO_CAPITAL)+1, o que pode colidir sob concorrência. [A CONFIRMAR] se há mitigação no banco.
  • A criação da adesão usa MAX(NUM_ADESAO)+1 com (NOLOCK) e também pode colidir sob concorrência.
  • Ao criar a adesão, o legado ainda:
  • vincula automaticamente documentos ativos (obrigatórios ou não, conforme origem);
  • grava histórico de status (IND_STATUS_ATUAL/DAT_STATUS_ATUAL).

4) Segurança (Legado) e como deve ficar na API Nova

4.1 Problema crítico do legado: spoofing de identidade

O endpoint é autenticado, mas: - payload.COD_USUARIO é usado como corretor “logado” e também como COD_SOL_CORRETOR.

➡️ Isso permite trocar o corretor apenas alterando o body, se não houver validação adicional baseada em claims.

4.2 Requisito (API Nova) — scopes + vínculo (ownership)

Baseado na Matriz de Políticas (guardrails decididos): - Autenticação ≠ autorização. - Antes de executar: 1) validar scope exigido, 2) validar ownership/vínculo do recurso.

Proposta para este endpoint (API Nova): - Scope sugerido: propostas:write [A CONFIRMAR] nomenclatura final de scopes. - Ownership (canais próprios): - derivar user_id/broker_id do token (não do body), - validar que a cotação/proposta criada pertence ao corretor do token, - validar permissões do corretor sobre entidade/cidade/UF [A CONFIRMAR] regra formal. - Ownership (se algum dia exposto a parceiros): - carregar partner_id na cotação/proposta/adesão e exigir match com partner_id do token (MVP).

4.3 Hardening adicional

  • remover listas “whitelist” hard-coded do código (migrar para regra configurável).
  • tratar concorrência no gerador de NUM_COTACAO (sequence/identity + unique constraint).
  • não engolir exceções silenciosamente (catch vazio) em pontos de integridade do fluxo.
  • padronizar mensagens de validação para não retornar HTML (ex.: <a href=...> em Mensagem) e evitar comportamento de UI (MsgBox) em rotas Web/API.

5) Observabilidade (API Nova) — audit + errors + correlation

Baseado na Matriz de Políticas: - X-Correlation-Id obrigatório (gateway gera se ausente) e deve ser propagado. - Logs e auditoria no SQL Server com retenção 60 dias.

5.1 Eventos mínimos de auditoria (sugestão)

Gravar em audit_events (ou equivalente): - proposta_novo_requested - cotacao_reused (quando encontra cotação existente) - cotacao_created - capital_version_created - adesao_upserted [A CONFIRMAR] quando aplicável - proposta_novo_denied (falha de scope/ownership)

Campos recomendados: - correlation_id, actor_type (broker/partner/system), actor_id, - resource_type (cotacao/proposta/adesao), resource_id, - status (success/failure) e failure_reason padronizado.

5.2 Erros

Gravar em app_errors (ou equivalente): - exceções não tratadas (5xx), - falhas de regra/validação (4xx) com código de erro.


6) Idempotência (API Nova)

Matriz de Políticas: - Sem Idempotency-Key. - operações críticas devem ser naturalmente idempotentes via contrato + constraint no banco.

6.1 MVP Parceiros

Quando/Se este fluxo existir em /v1/partners/*: - Idempotência natural via unicidade em (partner_id, external_reference).

6.2 Para canais próprios (corretor/cliente)

[A CONFIRMAR] estratégia de idempotência desejada: - opção A: manter reuso por (broker_id, num_identificacao, ... ) + status, - opção B: aceitar external_reference também para corretor (UI gera) e aplicar unicidade equivalente.


7) Testes mínimos (API Nova)

7.1 Unitários (domínio/policies)

  • decide status "E" quando FncCotacaoPME=true.
  • decide status "E" quando corretor na whitelist (ou regra configurável).
  • decide status "B" e Bloqueio=true quando UF corretor ≠ UF cidade.
  • não permite broker_id diferente do token (ownership).

7.2 Integração (DB)

  • cria cotação nova → verifica insert em TB_COTACAO (ou tabelas novas).
  • cria nova versão quando cotação existente → verifica que não cria nova cotação, apenas nova versão em TB_CAPITAL_COTACAO.
  • concorrência (ideração “MAX+1”):
  • duas requisições simultâneas não geram NUM_COTACAO duplicado.
  • duas requisições simultâneas na mesma cotação não geram NUM_VERSAO_CAPITAL duplicado.
  • duas requisições simultâneas não geram NUM_ADESAO duplicado.
  • adesão:
  • cria registro em TB_ADESAO e cria os vínculos de documentos (tabelas de adesão-documento).
  • grava histórico em TB_STATUS_ADESAO (ou equivalente) com IND_STATUS_ATUAL e DAT_STATUS_ATUAL.
  • consulta FncConsultarAdesao(..., "A", NUM_COTACAO, ...) encontra a adesão retornada no fluxo.

8) Checklist de pendências (para fechar o mapeamento)

Artefatos de código

  • [x] PropostaService.Novo(...) + DTOs PropostaNovoPayload e PropostaNovoViewModel [recebido].
  • [ ] RegrasNegocio.ListaRestricaoCliente (FncClienteEstaListaNegra) [PENDENTE] — preciso do código/tabelas/consultas.
  • [ ] RegrasNegocio.ListaRestricaoCorretor (FncCorretorEstaListaNegra) [PENDENTE] — idem.
  • [ ] Significado/enum de IND_STATUS_ATUAL para valores 'X', 'P', 'R' usados na validação de duplicidade.
  • [ ] [A CONFIRMAR] ordem “validar duplicidade” vs “reusar cotação existente” e como IndOperacao muda ao longo do fluxo.
  • [ ] RegrasNegocio.CotacaoCapital:
  • fncGravar(...) [recebido]
  • FncValidarDados(...) [recebido] (ver 2.7)
  • construtor New(parNUM_COTACAO, parNUM_VERSAO_CAPITAL, Consultar) [recebido — parcial]
  • pendente: demais métodos/trechos (ex.: setters/getters completos, gravação/alteração de capital, e pontos que definem transacao, geraLog e indOperacao).
  • [x] RegrasNegocio.CotacaoStatus (histórico de status em TB_STATUS_COTACAO).
  • [ ] RegrasNegocio.Adesao:
  • fncGravar(...) [recebido]
  • construtor + FncValidarDados, FncvalidarDadosBDados (campos obrigatórios/validações).
  • onde/como são setados IND_STATUS_ATUAL e DAT_STATUS_ATUAL antes do fncGravar.
  • FncConsultarAdesao(...) [recebido]
  • [x] RegrasNegocio.Cotacao.fncGravaAdesaoCotacaoExpress(...) (builder/gravação de adesão; está em Cotacao.vb).

  • [ ] Classes chamadas dentro de Adesao.fncGravar(...):

  • RegrasNegocio.DocumentoAdesao.FncListaAtivos(...) (fonte dos documentos obrigatórios).
  • RegrasNegocio.AdesaoDocumento.fncGravar(...) (vínculo adesão × documento).
  • RegrasNegocio.AdesaoStatus.fncGravar(...) (histórico/status da adesão).
  • [ ] RegrasNegocio.Corretor.FncConsultarDadosCorretor(...) (SQL/SP) e layout esperado (COD_ESTADO etc).
  • [ ] RegrasNegocio.Cidade (como obtém UF de COD_CIDADE).
  • [ ] RegrasNegocio.Entidade.fncRetornaOpcoesComissao(...) + fncRetornaPercentualComissao(...) (insumos e retorno).
  • [ ] RegrasNegocio.CondicoesComerciais.FncConsultarCodConvencaoColetiva(...).
  • [x] FncValidarDadosCotacaoExpress(...) — recebido e analisado (ver 2.7).
  • [x] CotacaoCapital.FncValidarDados(...) — recebido e analisado (ver 2.7).
  • [x] FncvalidarDadosBDadosCotacaoExpress(...) — recebido e analisado (ver 2.7.3).
  • [ ] Mecanismo de tratamento de exceções HTTP (filters/middleware) do projeto.

Banco de dados

  • [ ] Esquema de TB_COTACAO (colunas, PKs, índices, constraints).
  • [ ] Esquema de TB_CAPITAL_COTACAO e TB_COBERTURA_COTACAO (o CotacaoCapital.fncGravar gera nova versão e apaga coberturas da versão).
  • [ ] Concorrência/numeração: confirmar se existe SEQUENCE/IDENTITY/LOCK/SERIALIZABLE para evitar colisão em MAX(NUM_ADESAO)+1 (com NOLOCK) e MAX(NUM_VERSAO_CAPITAL)+1 (sem lock).
  • [ ] Confirmar se há índices/constraints únicas cobrindo (NUM_COTACAO, NUM_VERSAO_CAPITAL) e NUM_ADESAO (e como o sistema trata violação).
  • [ ] Esquema de TB_STATUS_COTACAO (histórico por NUM_COTACAO + DAT_STATUS).
  • [ ] Esquema de TB_ADESAO e tabelas relacionadas usadas no fncGravar:
  • tabela(s) de documento (ex.: TB_DOCUMENTO_ADESAO, TB_ADESAO_DOCUMENTO[A CONFIRMAR] nomes reais).
  • tabela(s) de status (ex.: TB_STATUS_ADESAO[A CONFIRMAR] nome real).
  • [ ] Esquema de TB_OPCOES_COMISSAO, TB_CONDICOES_COMERCIAIS.
  • [ ] Definição das funções dbo.FNC_Busca_Descricao_* usadas nos SELECTs.
  • [ ] Constraints/índices que evitam duplicidade em:
  • TB_ADESAO.NUM_ADESAO (o código usa MAX(NUM_ADESAO)+1).
  • TB_CAPITAL_COTACAO.(NUM_COTACAO, NUM_VERSAO_CAPITAL) (o código usa MAX(NUM_VERSAO_CAPITAL)+1).

Contrato

  • [ ] Confirmar campos realmente aceitos/ignorados (eventual “DTO novo” na API Nova).
  • [ ] Confirmar status codes (4xx/5xx) esperados e padrões de erro.
  • [ ] Confirmar serialização/binding de IND_TIPO_USUARIO (setter internal) e do token TOKEN_LOJACORR vs DSC_TOKEN_LOJACOR.

  • [ ] Confirmar enums e significados (legado → API Nova): IND_TIPO_SOLICITANTE (S/C/A/B/E/F/T), IND_CONHECEU_PASI (inclui "O"), IND_TIPO_ASSOCIADO (inclui "O"), IND_ACOMPANHAMENTO_SITUACAO (inclui "F"), IND_MOTIVO, IND_TIPO_CAPITAL (inclui "U").

  • [ ] Confirmar IND_CANAL_VENDA (validador força "P") e se isso é regra de negócio ou convenção do Web.
  • [ ] Confirmar constante/configuração DIAS_EXPIRACAO usada para calcular DAT_VALIDADE.
  • [ ] Confirmar tipo correto de COD_OPCOES_COMISSAO no contrato (no validador há validações como string e como inteiro).
  • [ ] Confirmar semântica do parâmetro booleano dos validadores fncSetaPropriedade* (em vários campos aparece False com mensagem de “obrigatório”).
  • [ ] Confirmar regra final para NUM_IDENTIFICACAO: aceitar somente 11/14 (CPF/CNPJ) ou permitir outros comprimentos.

Segurança / API Nova

  • [ ] Derivar COD_USUARIO do token/claims (evitar spoofing) e validar vínculo/ownership antes de gravar.
  • [ ] Definir área/público da API Nova para este caso (ex.: corretor vs parceiro).
  • [ ] Definir scopes finais e mapeamento de ownership/vínculo (broker_id/partner_id).

  • Valores e significado de IND_CUSTO_SELECIONADO_WEB (enum/valores aceitos) e em quais telas/fluxos ele é escrito/lido.

  • Origem e regra de preenchimento de DAT_INCLUSAO_CAPITAL (default/trigger/código), já que aparece em sqlColunas mas não foi visto no INSERT/UPDATE.
  • Confirmação de quais métodos de CotacaoCapital são efetivamente acionados pelo endpoint /api/Proposta/Novo/Especiais (ex.: se usa fncGravarCotacaoEspeciais).