Pesquisar neste blog

quinta-feira, 16 de fevereiro de 2012

Rotina de validação de CNS e Número Provisório ORACLE (PL/SQL)


Segue abaixo os scripts para criação de 3 functions no ORACLE para validação de número CNS (Cartão Nacional de Saúde) definitivo e provisório a saber:

1. FCN_CNS_CHECAR_DEFINITIVO;

2. FCN_CNS_CHECAR_PROVISORIO;

3. FCN_CNS_CHECAR;




O único detalhe é que a function "FCN_CNS_CHECAR" deve ser criada por último, já que ela faz referência as outras duas functions.





create or replace function FCN_CNS_CHECAR_DEFINITIVO(P_NUM_CNS IN VARCHAR2) 
  return boolean is
/*******************************************************************************/
/* Objetivo.........: Checa se o número CNS definitivo é válido                */
/* Autor............: Flavio Barbosa                                           */
/* Parametros.......: P_NUM_CNS = Número do CNS a ser validado                 */
/* Retorno..........: True (1), se for válido; False (0), se for inválido      */        
/* Documento de Base: http://cartaonet.datasus.gov.br/downloadsNovo.asp        */
/* Visite também....: http://www.ciaware.com.br                                */
/*******************************************************************************/
  v_num_cns varchar2(16) := '';
  pis       varchar2(16) := '';
  resto     integer := 0;
  dv        integer := 0;
  soma      number := 0;
  resultado varchar2(16) := '';
  result    boolean := true;
begin

  v_num_cns := trim(P_num_cns);
  
  if ( length( v_num_cns )=15) then
    pis := substr( V_NUM_CNS,1,11);
    soma:=  ( ( to_number( substr( pis, 1, 1 ) ) ) * 15 ) +
            ( ( to_number( substr( pis, 2, 1 ) ) ) * 14 ) +
            ( ( to_number( substr( pis, 3, 1 ) ) ) * 13 ) +
            ( ( to_number( substr( pis, 4, 1 ) ) ) * 12 ) +
            ( ( to_number( substr( pis, 5, 1 ) ) ) * 11 ) +
            ( ( to_number( substr( pis, 6, 1 ) ) ) * 10 ) +
            ( ( to_number( substr( pis, 7, 1 ) ) ) * 9 ) +
            ( ( to_number( substr( pis, 8, 1 ) ) ) * 8 ) +
            ( ( to_number( substr( pis, 9, 1 ) ) ) * 7 ) +
            ( ( to_number( substr( pis, 10, 1 ) ) ) * 6 ) +
            ( ( to_number( substr( pis, 11, 1 ) ) ) * 5 );

    resto:= soma mod 11;
    dv     := 11 - resto;

    if dv = 11 then
       dv:= 0;
    end if;

    if dv = 10 then
      soma:=  ( ( to_number( substr( pis, 1, 1 ) ) ) * 15 ) +
              ( ( to_number( substr( pis, 2, 1 ) ) ) * 14 ) +
              ( ( to_number( substr( pis, 3, 1 ) ) ) * 13 ) +
              ( ( to_number( substr( pis, 4, 1 ) ) ) * 12 ) +
              ( ( to_number( substr( pis, 5, 1 ) ) ) * 11 ) +
              ( ( to_number( substr( pis, 6, 1 ) ) ) * 10 ) +
              ( ( to_number( substr( pis, 7, 1 ) ) ) * 9 ) +
              ( ( to_number( substr( pis, 8, 1 ) ) ) * 8 ) +
              ( ( to_number( substr( pis, 9, 1 ) ) ) * 7 ) +
              ( ( to_number( substr( pis, 10, 1 ) ) ) * 6 ) +
              ( ( to_number( substr( pis, 11, 1 ) ) ) * 5 ) + 2;
      resto:= soma mod 11;
      dv     := 11 - resto;
      resultado:= pis || '001' || to_char( dv );
    else
      resultado:= pis || '000' || to_char( dv );
    end if;
    result := (V_NUM_CNS = resultado);
  end if;
  
  return(Result);
end FCN_CNS_CHECAR_DEFINITIVO;
/

create or replace function FCN_CNS_CHECAR_PROVISORIO(P_NUM_CNS IN VARCHAR2) 
  return boolean is
/*******************************************************************************/
/* Objetivo.........: Checa se o número CNS provisório é válido                */     
/* Autor............: Flavio Barbosa                                           */          
/* Parametros.......: P_NUM_CNS = Número do CNS a ser validado                 */       
/* Retorno..........: True (1), se for válido; False (0), se for inválido      */          
/* Documento de Base: http://cartaonet.datasus.gov.br/downloadsNovo.asp        */          
/* Visite também....: http://www.ciaware.com.br                                */          
/*******************************************************************************/
  v_num_cns varchar2(16) := '';
  resto     integer := 0;
  soma      number := 0;
  result    boolean := false;
begin


  v_num_cns := trim(P_num_cns);
  
  if ( length( v_num_cns )=15) then




    soma:=  ( ( to_number( substr( V_NUM_CNS, 1, 1 ) ) ) * 15 ) +
            ( ( to_number( substr( V_NUM_CNS, 2, 1 ) ) ) * 14 ) +
            ( ( to_number( substr( V_NUM_CNS, 3, 1 ) ) ) * 13 ) +
            ( ( to_number( substr( V_NUM_CNS, 4, 1 ) ) ) * 12 ) +
            ( ( to_number( substr( V_NUM_CNS, 5, 1 ) ) ) * 11 ) +
            ( ( to_number( substr( V_NUM_CNS, 6, 1 ) ) ) * 10 ) +
            ( ( to_number( substr( V_NUM_CNS, 7, 1 ) ) ) * 9 ) +
            ( ( to_number( substr( V_NUM_CNS, 8, 1 ) ) ) * 8 ) +
            ( ( to_number( substr( V_NUM_CNS, 9, 1 ) ) ) * 7 ) +
            ( ( to_number( substr( V_NUM_CNS, 10, 1 ) ) ) * 6 ) +
            ( ( to_number( substr( V_NUM_CNS, 11, 1 ) ) ) * 5 ) +
            ( ( to_number( substr( V_NUM_CNS, 12, 1 ) ) ) * 4 ) +
            ( ( to_number( substr( V_NUM_CNS, 13, 1 ) ) ) * 3 ) +
            ( ( to_number( substr( V_NUM_CNS, 14, 1 ) ) ) * 2 ) +
            ( ( to_number( substr( V_NUM_CNS, 15, 1 ) ) ) * 1 );


    resto:= soma mod 11;


result := (resto=0);

  end if;
  
  return(Result);
end FCN_CNS_CHECAR_PROVISORIO;
/



CREATE OR REPLACE FUNCTION FCN_CNS_CHECAR (V_Num_Cns in Varchar2)
    Return Boolean
/*******************************************************************************/
/* Objetivo.......: Checa se o n. CNS é definitivo ou provisório e se é válido */
/* Autor..........: Flavio Barbosa                                             */
/* Parametros.....: P_NUM_CNS = Número do CNS a ser validado                   */
/* Retorno........: True (1), se for válido; False (0), se for inválido        */
/* Documento Base.: http://cartaonet.datasus.gov.br/downloadsNovo.asp          */
/* Visite também..: http://www.ciaware.com.br                                  */        /*******************************************************************************/
As
  Soma    number;
  Result  boolean := false;
Begin


  If ((Trim(V_Num_Cns) Is Not Null) And (Length(Trim(V_Num_Cns)) = 15)) Then
    IF (SUBSTR( TRIM(V_NUM_CNS), 1, 1) IN ( '8', '9' )) THEN
       Result := FCN_CNS_CHECAR_PROVISORIO( V_NUM_CNS );
    ELSE
       Result := FCN_CNS_CHECAR_DEFINITIVO( V_NUM_CNS );
    END IF;
  End If;


  Return( Result );
  
Exception When Others 
    Then Return (False);
End FCN_CNS_CHECAR;
/










Rotina de validação de CNS e Número Provisório C# (CSharp)

Segue abaixo a classe estática CartaoNacionalSUS para validação de número CNS (Cartão Nacional de Saúde) definitivo e provisório.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Inicio


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
/// A classe estática "CartaoNacionalSUS" foi criada por Flávio Barbosa 
/// Objetivo: Validar o número do Cartão Nacional de Saúde (CNS)
/// Documento base: http://cartaonet.datasus.gov.br/downloadsNovo.asp
/// Visite também: http://www.ciaware.com.br
/// </summary>
public static class CartaoNacionalSUS
{

    /// <summary>
    /// Verifica se o número CNS informado é definitivo ou provisório e se ele é válido [FB]
    /// </summary>
    /// <param name="cns">Número de CNS a ser checado</param>
    /// <returns>True, se o número é válido; False, se for inválido.</returns>
    public static bool chkNumeroCNS(string cns)
    {
        bool result = false;

        cns = cns.Trim();


        if ((cns.Substring(0, 1) == "8") || (cns.Substring(0, 1) == "9"))
        {
            result = CartaoNacionalSUS.chkNumeroProvisorio(cns);
        }
        else
        {
            result = CartaoNacionalSUS.chkNumeroDefinitivo(cns);
        }

        return result;
    }


    /// <summary>
    /// Verifica se um número CNS provisório é válido [FB]
    /// </summary>
    /// <param name="cns">Número de CNS a ser checado</param>
    /// <returns>True, se o número é válido; False, se for inválido.</returns>
    public static bool chkNumeroProvisorio(string cns)
    {
        bool result = false;

        try
        {
            cns = cns.Trim();

            if (cns.Trim().Length == 15)
            {



                float resto, soma;

                soma=  ( ( Convert.ToInt64( cns.Substring(0, 1 ) ) ) * 15 ) +
                        ((Convert.ToInt64(cns.Substring(1, 1))) * 14) +
                        ((Convert.ToInt64(cns.Substring(2, 1))) * 13) +
                        ((Convert.ToInt64(cns.Substring(3, 1))) * 12) +
                        ((Convert.ToInt64(cns.Substring(4, 1))) * 11) +
                        ((Convert.ToInt64(cns.Substring(5, 1))) * 10) +
                        ((Convert.ToInt64(cns.Substring(6, 1))) * 9) +
                        ((Convert.ToInt64(cns.Substring(7, 1))) * 8) +
                        ((Convert.ToInt64(cns.Substring(8, 1))) * 7) +
                        ((Convert.ToInt64(cns.Substring(9, 1))) * 6) +
                        ((Convert.ToInt64(cns.Substring(10, 1))) * 5) +
                        ((Convert.ToInt64(cns.Substring(11, 1))) * 4) +
                        ((Convert.ToInt64(cns.Substring(12, 1))) * 3) +
                        ((Convert.ToInt64(cns.Substring(13, 1))) * 2) +
                        ((Convert.ToInt64(cns.Substring(14, 1))) * 1);

                resto = soma % 11;

                result = (resto == 0);
            }

        }
        catch (Exception)
        {
            result = false;
        }


        return result;
    }


    /// <summary>
    /// Verifica se um número CNS definitivo é válido [FB]
    /// </summary>
    /// <param name="cns">Número de CNS a ser checado</param>
    /// <returns>True, se o número é válido; False, se for inválido.</returns>
    public static bool chkNumeroDefinitivo(string cns)
    {
        bool result = false;

        try
        {
            if (cns.Trim().Length == 15)
            {

                float resto, soma, dv;

                string pis = string.Empty;
                string resultado = string.Empty;

                pis = cns.Substring(0, 11);

                soma = ((Convert.ToInt64(pis.Substring(0, 1))) * 15) +
                        ((Convert.ToInt64(pis.Substring(1, 1))) * 14) +
                        ((Convert.ToInt64(pis.Substring(2, 1))) * 13) +
                        ((Convert.ToInt64(pis.Substring(3, 1))) * 12) +
                        ((Convert.ToInt64(pis.Substring(4, 1))) * 11) +
                        ((Convert.ToInt64(pis.Substring(5, 1))) * 10) +
                        ((Convert.ToInt64(pis.Substring(6, 1))) * 9) +
                        ((Convert.ToInt64(pis.Substring(7, 1))) * 8) +
                        ((Convert.ToInt64(pis.Substring(8, 1))) * 7) +
                        ((Convert.ToInt64(pis.Substring(9, 1))) * 6) +
                        ((Convert.ToInt64(pis.Substring(10, 1))) * 5);


                resto = soma % 11;
                dv = 11 - resto;

                if (dv == 11)
                {
                    dv = 0;
                }

                if (dv == 10)
                {
                    soma = ((Convert.ToInt64(pis.Substring(0, 1))) * 15) +
                            ((Convert.ToInt64(pis.Substring(1, 1))) * 14) +
                            ((Convert.ToInt64(pis.Substring(2, 1))) * 13) +
                            ((Convert.ToInt64(pis.Substring(3, 1))) * 12) +
                            ((Convert.ToInt64(pis.Substring(4, 1))) * 11) +
                            ((Convert.ToInt64(pis.Substring(5, 1))) * 10) +
                            ((Convert.ToInt64(pis.Substring(6, 1))) * 9) +
                            ((Convert.ToInt64(pis.Substring(7, 1))) * 8) +
                            ((Convert.ToInt64(pis.Substring(8, 1))) * 7) +
                            ((Convert.ToInt64(pis.Substring(9, 1))) * 6) +
                            ((Convert.ToInt64(pis.Substring(10, 1))) * 5) + 2;

                    resto = soma % 11;
                    dv = 11 - resto;
                    resultado = pis + "001" + Convert.ToString(Convert.ToInt16(dv)).Trim();
                }
                else
                {
                    resultado = pis + "000" + Convert.ToString(Convert.ToInt16(dv)).Trim();
                }


                result = cns.Equals(resultado);

            }
        }
        catch (Exception)
        {
            result = false;
        }


        return result;
    }

 

}

/// Fim

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////