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 apontaAuthorization: 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;..."
}
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_ESTADO ≠ objCidade.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çapayload.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 deEntidade.fncRetornaOpcoesComissao(payload.COD_OPCOES_COMISSAO, ...).PRC_COMISSAO→ preenchido viaOpcoesComissao.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 é sempreDateTime.Now). - Regra de abrangência:
DSC_TERRITORIAL(comparaCOD_CIDADEpor substring para setarIND_DENTRO_ABRANGENCIA). - Capital:
NUM_SEGURADOS. - Não associado:
VAL_NAO_ASSOCIADO(apenas para decidir se aplica custo não associado; o valor aplicado vem defncRetornaOpcoesComissao).
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 comointno DTO, mas o service decide custo não associado viaVAL_NAO_ASSOCIADO+ retorno defncRetornaOpcoesComissao).DSC_TOKEN_LOJACORvsTOKEN_LOJACORR: o service usapayload.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 deDateTime.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_USUARIOestá declarado comopublic string IND_TIPO_USUARIO { get; internal set; }.
[A CONFIRMAR] se o model binder/JSON consegue popular esse campo (caso contrário, ele pode chegar semprenullno 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) emTB_STATUS_COTACAOos campos:NUM_COTACAO,DAT_STATUS,IND_STATUS,COD_RESPONSAVEL,NOM_ESTACAO,DAT_ULTIMA_ATUALIZACAO.NOM_ESTACAOvem deobjNegocios.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(...)retornaTrue), permitindo repetirIND_STATUSpara a mesma cotação.
Mapa de descrição (CotacaoStatus.FncDescricaoStatus()):
A→ AbertoE→ EnviadaC→ CanceladaX→ ExpiradaP→ AprovadaR→ Recusada
Operação de rollback de status:
CotacaoStatus.FncExcluirUltimoStatus(NUM_COTACAO, ...)remove o último registro (maiorDAT_STATUS) quando existir mais de um status e atualizaTB_COTACAO.DAT_STATUS_ATUAL/TB_COTACAO.IND_STATUS_ATUALpara 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_CAPITALvia:SELECT MAX(NUM_VERSAO_CAPITAL)+1 FROM TB_CAPITAL_COTACAO WHERE NUM_COTACAO = <NUM_COTACAO>- Se nulo → assume
1.
- Faz
INSERTemTB_CAPITAL_COTACAOcom (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 deNOM_ESTACAOeDAT_ULTIMA_ATUALIZACAO.
-
Pós-insert: se
COD_MODULOnã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_COTACAOpelos campos acima, filtrando porNUM_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 = Truee 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 momentoIndOperacaomuda deInclusaoparaAlteracao(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 setaindOperacao = "A"(alteração). - Se
parObjDados Is Nothing, criaobjDadoscom conexão própria, marcatransacao=TrueegeraLog=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 emTB_ADESAOpara(NUM_COTACAO, NUM_VERSAO_CAPITAL). - Filtra por
B.DAT_INCLUSAO <= DATEADD(hh,23,@DAT_ENTREGA_RECEPCAO)e porB.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 eB.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çãodbo.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(viafncGravar) copiando dados da versão original e depois copia coberturas viaCotacaoCobertura(iteradatCoberturase 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_COTACAOe depoisTB_CAPITAL_COTACAO. FncAtualizaTipoCustoSelecionado(parTipoCustoSelecionado, msg):- Atualiza
TB_CAPITAL_COTACAO.IND_CUSTO_SELECIONADO_WEBpara 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_COTACAONUM_VERSAO_CAPITAL = parCapitalCotacao.FncNUM_VERSAO_CAPITALIND_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_EMPRESADSC_IDENTIFICACAO_CLIENTE = NUM_IDENTIFICACAOCOD_ATIVIDADE_CLIENTE = COD_ATIVIDADE_RECEITA(se não nulo)DSC_ENDERECO_CLIENTE = DSC_ENDERECONOM_BAIRRO_CLIENTE = NOM_BAIRROCOD_CIDADE_CLIENTE = COD_CIDADENUM_CEP_CLIENTE = NUM_CEPDSC_ENDERECO_COBRANCA = DSC_ENDERECONOM_BAIRRO_COBRANCA = NOM_BAIRROCOD_CIDADE_COBRANCA = COD_CIDADENUM_CEP_COBRANCA = NUM_CEP-
IND_CLIENTE_ASSOCIADO_SINDICATO:- se não
FncCotacaoPME(COD_OPCOES_COMISSAO)→"S" - senão →
"N"
- se não
-
Corretor:
COD_CORRETOR_CORRETOR = COD_SOL_CORRETORIND_NAO_ENVIAR_CLIENTE = "N"-
COD_SEGURADORA_CORRETOR = 5142(hard-coded) -
Coberturas / faturamento:
COD_MODULO = parCapitalCotacao.FncCOD_MODULOCOD_MODULO_ADICIONAL = parCapitalCotacao.FncCOD_MODULO_ADICIONALVAL_CAPITAL_SEGURADO = parCapitalCotacao.FncVAL_COBERTURAVAL_CUSTO_SEGURADO = parCapitalCotacao.FncVAL_CUSTO_ASSOCIADONUM_SEGURADOS_ATIVOS = parCapitalCotacao.FncNUM_SEGURADOSVAL_FATURA_MIN = parCapitalCotacao.FncVAL_FATURA_MINIMA-
IND_CORRIGIR_CAPITAL = "E" -
Entidades / demais:
COD_ENTIDADE_PATRONAL = COD_ENTIDADE_PATRONALCOD_ENTIDADE_LABORAL = COD_ENTIDADE_LABORALIND_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_CIDADECOD_OPCOES_COMISSAO = parCapitalCotacao.FncCOD_OPCOES_COMISSAOIND_EMITIR_ETIQUETA="S",IND_ENVIAR_COBRANCA_PARA="E",NUM_DIA_VENCIMENTO=31NUM_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_ADESAOviaSELECT 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 comoCURRENT_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, criaAdesaoDocumento(NUM_ADESAO, COD_DOCUMENTO)setandoIND_OBRIGATORIOconforme a origem, e chamaObjAdesaoDocumentos.fncGravar(...).Registra status em histórico via
AdesaoStatus: gravaNUM_ADESAO,IND_STATUS = IND_STATUS_ATUALeDAT_STATUS = DAT_STATUS_ATUAL.Alteração (demais operações):
Executa
UPDATE TB_ADESAO SET ... WHERE NUM_ADESAO = @NUM_ADESAOatualizando o mesmo conjunto de colunas (incluiDAT_INCLUSAOvia 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,AdesaoDocumentoeAdesaoStatus; e o catálogo completo de valores possíveis deIND_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 oTB_ENTIDADE p(patronal) eTB_ENTIDADE l(laboral)TB_ATIVIDADE t,TB_GRUPO_CLIENTE gTB_ADESAO_DOCUMENTO_ANEXO d(porNUM_ADESAOeCOD_DOCUMENTO = 1)TB_ADESAO_CONTATO_CLIENTE AC(departamento 13),TB_ADESAO_CONTATO_CLIENTE AC2(departamento 20 — e-mail de fatura)TB_CAPITAL_COTACAO CCeTB_COTACAO CT(porNUM_COTACAO)- Subquery em
TB_CORRETOR_CONTATO OC(departamento 13) paraDSC_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 > 0→CC.NUM_VERSAO_CAPITAL = parVERSAO_CAPITAL. - Ordenação:
ORDER BY A.DAT_INCLUSAO DESC. - Retorno:
Truequando 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_COTACAOobrigatório.IND_TIPO_CAPITALobrigatório;VAL_COBERTURAobrigatório.- Se
IND_TIPO_CAPITAL = "U", entãoQTD_VAL_COBERTURA = Nothing; caso contrárioQTD_VAL_COBERTURAdeve ser inteiro positivo. VAL_FATURA_MINIMAobrigatório e > 0.NUM_SEGURADOSobrigatório e > 0.VAL_CUSTO_ASSOCIADOobrigatório e > 0.VAL_CUSTO_NAO_ASSOCIADOé validado quando informado (a mensagem indica “maior que zero”, mas a validação recebida éfncSetaPropriedadeDecimal).COD_MODULOeCOD_MODULO_ADICIONALvalidados; se informar módulo adicional sem módulo principal, retorna erro.COD_CORRETOR_COMISSAOvalidado como inteiro.PRC_COMISSAOvalidado como decimal positivo.COD_OPCOES_COMISSAOvalidado (no trecho recebido está como “decimal positivo”, embora a semântica aparente seja de código/inteiro) — [A CONFIRMAR].DSC_TOKEN_LOJACORvalidado quando informado.- Normalizações: define
NOM_ESTACAO = objNegocios.fncNomMaquinaeDAT_ULTIMA_ATUALIZACAO = dataAtual(viaSistema.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 helperfncSetaPropriedade*. - 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, retornaTrue. - Consulta:
TB_COTACAO(aliasA) INNER JOINTB_CAPITAL_COTACAO(aliasB)- filtros:
SELECT(com JOIN emTB_CAPITAL_COTACAO) emfncValidarChaveCotacaoExpress(...)para bloquear duplicidade quando há uma cotação ativa (status diferente de'X','P','R').A.NUM_IDENTIFICACAO = @NUM_IDENTIFICACAOA.COD_ENTIDADE_PATRONALeA.COD_ENTIDADE_LABORAL(comparação direta ouIS NULL, conforme o valor atual das propriedades)B.VAL_CUSTO_ASSOCIADO = @VAL_CUSTO_ASSOCIADOB.NUM_SEGURADOS = @NUM_SEGURADOSB.COD_CORRETOR_COMISSAO = @COD_CORRETOR_COMISSAOA.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_CORRETORnã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 queParObjMensagemrecebeu 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_COTACAOINSERT/UPDATEdentro deCotacao.fncGravarCotacaoExpress(...).TB_STATUS_COTACAO(viaCotacaoStatus.fncGravar(...))- Inserção do status atual da cotação (por exemplo
IND_STATUS_ATUAL = 'E'/'B'). TB_CAPITAL_COTACAO(viaCotacaoCapital.fncGravar(...))SELECT MAX(NUM_VERSAO_CAPITAL)+1 ... WHERE NUM_COTACAO = <NUM_COTACAO>para numerarNUM_VERSAO_CAPITAL.INSERT/UPDATEda versão de capital (campos de capital/custos/módulos/comissão/token etc.).SELECTpor chave (NUM_COTACAO,NUM_VERSAO_CAPITAL) no construtorCotacaoCapital.New(...)(consultaTB_CAPITAL_COTACAOcom lista fixa de colunas).TB_COBERTURA_COTACAO(viaCotacaoCapital.fncGravar(...))DELETEdas coberturas da versão (NUM_COTACAO+NUM_VERSAO_CAPITAL) quandoCOD_MODULOnão é nulo.TB_ADESAO(viaAdesao.fncGravar(...))SELECT MAX(NUM_ADESAO)+1 FROM TB_ADESAO (NOLOCK)para numerar a adesão.INSERT INTO TB_ADESAO (...) VALUES (...)(usaCURRENT_TIMESTAMPemDAT_INCLUSAO).UPDATE TB_ADESAO SET ... WHERE NUM_ADESAO=@NUM_ADESAO.
[A CONFIRMAR]: nomes exatos das tabelas/SQL utilizados por
DocumentoAdesao,AdesaoDocumentoeAdesaoStatus(cadastro de documentos e histórico de status da adesão), pois esses objetos são chamados dentro deAdesao.fncGravar(...)mas seusfncGravarnã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 descreverIND_TIPO_CAPITALem consultas auxiliares. -TB_CAPITAL_COTACAO.IND_CUSTO_SELECIONADO_WEB— atualizado viaFncAtualizaTipoCustoSelecionado.
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(...)eCidade.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/transacaodentro defncGravarCotacaoExpresseCotacaoCapital.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)+1com(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=...>emMensagem) 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"quandoFncCotacaoPME=true. - decide status
"E"quando corretor na whitelist (ou regra configurável). - decide status
"B"eBloqueio=truequando UF corretor ≠ UF cidade. - não permite
broker_iddiferente 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_COTACAOduplicado. - duas requisições simultâneas na mesma cotação não geram
NUM_VERSAO_CAPITALduplicado. - duas requisições simultâneas não geram
NUM_ADESAOduplicado. - adesão:
- cria registro em
TB_ADESAOe cria os vínculos de documentos (tabelas de adesão-documento). - grava histórico em
TB_STATUS_ADESAO(ou equivalente) comIND_STATUS_ATUALeDAT_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(...)+ DTOsPropostaNovoPayloadePropostaNovoViewModel[recebido]. - [ ]
RegrasNegocio.ListaRestricaoCliente(FncClienteEstaListaNegra) [PENDENTE] — preciso do código/tabelas/consultas. - [ ]
RegrasNegocio.ListaRestricaoCorretor(FncCorretorEstaListaNegra) [PENDENTE] — idem. - [ ] Significado/enum de
IND_STATUS_ATUALpara valores'X','P','R'usados na validação de duplicidade. - [ ] [A CONFIRMAR] ordem “validar duplicidade” vs “reusar cotação existente” e como
IndOperacaomuda 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,geraLogeindOperacao). - [x]
RegrasNegocio.CotacaoStatus(histórico de status emTB_STATUS_COTACAO). - [ ]
RegrasNegocio.Adesao: fncGravar(...)[recebido]- construtor +
FncValidarDados,FncvalidarDadosBDados(campos obrigatórios/validações). - onde/como são setados
IND_STATUS_ATUALeDAT_STATUS_ATUALantes dofncGravar. FncConsultarAdesao(...)[recebido]-
[x]
RegrasNegocio.Cotacao.fncGravaAdesaoCotacaoExpress(...)(builder/gravação de adesão; está emCotacao.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_ESTADOetc). - [ ]
RegrasNegocio.Cidade(como obtém UF deCOD_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_COTACAOeTB_COBERTURA_COTACAO(oCotacaoCapital.fncGravargera nova versão e apaga coberturas da versão). - [ ] Concorrência/numeração: confirmar se existe
SEQUENCE/IDENTITY/LOCK/SERIALIZABLEpara evitar colisão emMAX(NUM_ADESAO)+1(comNOLOCK) eMAX(NUM_VERSAO_CAPITAL)+1(sem lock). - [ ] Confirmar se há índices/constraints únicas cobrindo
(NUM_COTACAO, NUM_VERSAO_CAPITAL)eNUM_ADESAO(e como o sistema trata violação). - [ ] Esquema de
TB_STATUS_COTACAO(histórico porNUM_COTACAO+DAT_STATUS). - [ ] Esquema de
TB_ADESAOe tabelas relacionadas usadas nofncGravar: - 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 usaMAX(NUM_ADESAO)+1).TB_CAPITAL_COTACAO.(NUM_COTACAO, NUM_VERSAO_CAPITAL)(o código usaMAX(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(setterinternal) e do tokenTOKEN_LOJACORRvsDSC_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_EXPIRACAOusada para calcularDAT_VALIDADE. - [ ] Confirmar tipo correto de
COD_OPCOES_COMISSAOno 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 apareceFalsecom 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_USUARIOdo 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 emsqlColunasmas não foi visto noINSERT/UPDATE. - Confirmação de quais métodos de
CotacaoCapitalsão efetivamente acionados pelo endpoint/api/Proposta/Novo/Especiais(ex.: se usafncGravarCotacaoEspeciais).