CREATE PROCEDURE SP_CALCULA_RFC
@NOMBRES_AUX VARCHAR(100),
@APATERNO_AUX VARCHAR(100),
@AMATERNO_AUX VARCHAR(100),
@FECHANACIMIENTO DATETIME,
@RFC_OUT CHAR(16) OUT
AS
--DECLARACION DE VARIABLES
DECLARE @NOMBRES VARCHAR(100)
DECLARE @APATERNO VARCHAR(100)
DECLARE @AMATERNO VARCHAR(100)
DECLARE @T_NOMTOT CHAR(52)
DECLARE @NOMBRE1 VARCHAR(100) --PRIMER NOMBRE
DECLARE @NOMBRE2 VARCHAR(100) --DEMAS NOMBRES
DECLARE @NOMBRES_LONGITUD INT --LONGITUD DE TODOS @NOMBRES
DECLARE @NOMBRE1_LONGITUD INT --LONGITUD DEL PRIMER NOMBRE(MAS UNO,EL QUE SOBRA ES UN ESPACIO EN BLANCO)
DECLARE @APATERNO1 VARCHAR(100) --PRIMER NOMBRE
DECLARE @APATERNO2 VARCHAR(100) --DEMAS NOMBRES
DECLARE @APATERNO_LONGITUD INT --LONGITUD DE TODOS @NOMBRES
DECLARE @APATERNO1_LONGITUD INT --LONGITUD DEL PRIMER NOMBRE(MAS UNO,EL QUE SOBRA ES UN ESPACIO EN BLANCO)
DECLARE @AMATERNO1 VARCHAR(100) --PRIMER NOMBRE
DECLARE @AMATERNO2 VARCHAR(100) --DEMAS NOMBRES
DECLARE @AMATERNO_LONGITUD INT --LONGITUD DE TODOS @NOMBRES
DECLARE @AMATERNO1_LONGITUD INT --LONGITUD DEL PRIMER NOMBRE(MAS UNO,EL QUE SOBRA ES UN ESPACIO EN BLANCO)
DECLARE @VARLOOPS INT --VARIABLE PARA LOS LOOPS, SE INICIALIZA AL INICIR UN LOOP
DECLARE @RFC CHAR(16)
DECLARE @T_NOMNUM CHAR(102) --Nombre numerico
DECLARE @T_SUMA INT
DECLARE @T_DIVID INT -- Dividendo
DECLARE @T_MOD INT -- MOD de la division
DECLARE @T_HOMOCLV CHAR(3) -- Homoclave
DECLARE @T_NUMERO INT -- Numero ASC asignado a un caracter
DECLARE @T_PARCIAL INT -- Acumulado de la suma de los caracteres del RFC
--INICIALZA VARIABLES
SET @NOMBRES = LTRIM(RTRIM(@NOMBRES_AUX))
SET @APATERNO = LTRIM(RTRIM(@APATERNO_AUX))
SET @AMATERNO = LTRIM(RTRIM(@AMATERNO_AUX))
SET @T_NOMTOT =@APATERNO+' '+@AMATERNO+' '+@NOMBRES
--PROCESAR NOMBRES DE PILA
SET @VARLOOPS = 0
WHILE @VARLOOPS <> 1
BEGIN
SET @NOMBRES_LONGITUD = LEN(@NOMBRES)
SET @NOMBRE1_LONGITUD = PATINDEX('% %',@NOMBRES)
IF @NOMBRE1_LONGITUD = 0
SET @NOMBRE1_LONGITUD = @NOMBRES_LONGITUD
SET @NOMBRE1 = RTRIM(LEFT(@NOMBRES,@NOMBRE1_LONGITUD))
SET @NOMBRE2 = LTRIM(RIGHT(@NOMBRES,@NOMBRES_LONGITUD - @NOMBRE1_LONGITUD))
--SE QUINTAN LOS NOMBRES DE JOSE, MARIA,MA,MA.
IF @NOMBRE1 IN ('JOSE','MARIA','MA.','MA','DE','LA','LAS','MC','VON','DEL','LOS','Y','MAC','VAN') AND @NOMBRE2 <> ''
BEGIN
SET @NOMBRES = @NOMBRE2
END
ELSE
BEGIN
SET @VARLOOPS = 1
END
END
--PROCESAMOS APELLIDOS, PATERNO EN UN LOOP
SET @VARLOOPS = 0
WHILE @VARLOOPS <> 1
BEGIN
SET @APATERNO_LONGITUD = LEN(@APATERNO)
SET @APATERNO1_LONGITUD = PATINDEX('% %',@APATERNO)
IF @APATERNO1_LONGITUD = 0
SET @APATERNO1_LONGITUD = @APATERNO_LONGITUD
SET @APATERNO1 = RTRIM(LEFT(@APATERNO,@APATERNO1_LONGITUD))
SET @APATERNO2 = LTRIM(RIGHT(@APATERNO,@APATERNO_LONGITUD - @APATERNO1_LONGITUD))
--SE QUINTAN LOS SUFIJOS
IF @APATERNO1 IN ('DE','LA','LAS','MC','VON','DEL','LOS','Y','MAC','VAN') AND @APATERNO2 <> ''
BEGIN
SET @APATERNO = @APATERNO2
END
ELSE
BEGIN
SET @VARLOOPS = 1
END
END
--PROCESAMOS APELLIDOS, MATERNO EN UN LOOP
SET @VARLOOPS = 0
WHILE @VARLOOPS <> 1
BEGIN
SET @AMATERNO_LONGITUD = LEN(@AMATERNO)
SET @AMATERNO1_LONGITUD = PATINDEX('% %',@AMATERNO)
IF @AMATERNO1_LONGITUD = 0
SET @AMATERNO1_LONGITUD = @AMATERNO_LONGITUD
SET @AMATERNO1 = RTRIM(LEFT(@AMATERNO,@AMATERNO1_LONGITUD))
SET @AMATERNO2 = LTRIM(RIGHT(@AMATERNO,@AMATERNO_LONGITUD - @AMATERNO1_LONGITUD))
--SE QUINTAN LOS SUFIJOS
IF @AMATERNO1 IN ('DE','LA','LAS','MC','VON','DEL','LOS','Y','MAC','VAN') AND @AMATERNO2 <> ''
BEGIN
SET @AMATERNO = @AMATERNO2
END
ELSE
BEGIN
SET @VARLOOPS = 1
END
END
--SE OBTIENE DEL PRIMER APELLIDO LA PRIMER LETRA Y LA PRIMER VOCAL INTERNA
SET @RFC = LEFT(@APATERNO1,1)
SET @APATERNO1_LONGITUD= LEN(@APATERNO1)
SET @VARLOOPS = 1 --EMPIEZA EN UNO POR LA PRIMERA LETRA SE LA VA A SALTAR
WHILE @APATERNO1_LONGITUD > @VARLOOPS
BEGIN
SET @VARLOOPS = @VARLOOPS + 1
IF SUBSTRING(@APATERNO1,@VARLOOPS,1) IN ('A','E','I','O','U')
BEGIN
SET @RFC = RTRIM(@RFC)+CONVERT(CHAR(1),SUBSTRING(@APATERNO1,@VARLOOPS,1))
SET @VARLOOPS = @APATERNO1_LONGITUD
END
END
--SE OBTIENE LA PRIMER LETRA DEL APELLIDO MATERNO SI NO TIENE APELLIDO MATERNO SE PONE UNA X
--DICE QUE SI NO TIENE APELLIDO MATERNO LE PONGAS LA PRIMER LETRA DEL APELLIDO PATERNO EN EL RFX
IF ISNULL(@AMATERNO1,'') = ''
BEGIN
SET @RFC = RTRIM(@RFC)+CONVERT(CHAR(1),SUBSTRING(@APATERNO1,1,1))
END
ELSE
BEGIN
SET @RFC = RTRIM(@RFC)+CONVERT(CHAR(1),SUBSTRING(@AMATERNO1,1,1))
END
--SE LE AGREGA LA PRIMER LETRA DEL NOMBRE
SET @RFC = RTRIM(@RFC)+CONVERT(CHAR(1),SUBSTRING(@NOMBRE1,1,1))
--CHEAS QUE NO SEA UNA PALARA INCONVENIENTE
/*
IF EXISTS ( SELECT INC_PALINC FROM NINCO WHERE INC_PALINC = @RFC )
BEGIN
SELECT @RFC = LTRIM(RTRIM (SUBSTRING (@RFC , 1 , 3))) + 'X'
END
*/
--SE LE AGREGA LA FECHA DE NACIMIENTO
SET @RFC = RTRIM(@RFC) + CONVERT(CHAR,@FECHANACIMIENTO,12)
--HOMOCLAVE
SET @T_NOMNUM = '0'
--SACA NOMBRE NUMERICO
SET @VARLOOPS = 1
WHILE @VARLOOPS <= 52
BEGIN
SET @T_NOMNUM = LTRIM(RTRIM (@T_NOMNUM)) +
CASE
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS, 1) = 'A' THEN '11'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'B' THEN '12'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'C' THEN '13'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'D' THEN '14'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'E' THEN '15'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'F' THEN '16'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'G' THEN '17'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'H' THEN '18'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'I' THEN '19'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'J' THEN '21'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'K' THEN '22'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'L' THEN '23'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'M' THEN '24'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'N' THEN '25'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'O' THEN '26'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'P' THEN '27'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'Q' THEN '28'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'R' THEN '29'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'S' THEN '32'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'T' THEN '33'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'U' THEN '34'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'V' THEN '35'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'W' THEN '36'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'X' THEN '37'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'Y' THEN '38'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) = 'Z' THEN '39'
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) >= '0' AND
SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) <= '9' THEN CONVERT(VARCHAR,CONVERT(INT, SUBSTRING (@T_NOMTOT , @VARLOOPS , 1)) , 2)
WHEN SUBSTRING (@T_NOMTOT , @VARLOOPS , 1) IN ('&','Ñ') THEN '10'
ELSE '00'
END
SET @VARLOOPS = @VARLOOPS + 1
END
set @VARLOOPS = 1
SET @T_SUMA = 0
while @VARLOOPS <= 99
begin
SET @T_SUMA = @T_SUMA + ((CONVERT(INT,SUBSTRING (@T_NOMNUM , @VARLOOPS , 1))*10) + CONVERT(INT,SUBSTRING (@T_NOMNUM , @VARLOOPS+1 , 1))) * CONVERT(INT,SUBSTRING (@T_NOMNUM , @VARLOOPS+1 , 1))
SET @VARLOOPS = @VARLOOPS + 1
end
-- Obtener HOMOCLAVE
SELECT @T_DIVID = @T_SUMA%1000 -- Obtener residuo de los ultimos 3 digitos
SELECT @T_MOD = @T_DIVID%34 -- Obtener el residuo de los ultimos 3 digitos-- entre 34
SELECT @T_DIVID = (@T_DIVID - @T_MOD) / 34 -- Obtener el Cociente entero
--select @T_DIVID,@T_MOD
-- Checar Cociente y residuo
SET @VARLOOPS = 0
WHILE @VARLOOPS <= 1
BEGIN
SET @T_HOMOCLV =
CASE CASE @VARLOOPS WHEN 0 THEN @T_DIVID ELSE @T_MOD END
WHEN 0 THEN '1'
WHEN 1 THEN '2'
WHEN 2 THEN '3'
WHEN 3 THEN '4'
WHEN 4 THEN '5'
WHEN 5 THEN '6'
WHEN 6 THEN '7'
WHEN 7 THEN '8'
WHEN 8 THEN '9'
WHEN 9 THEN 'A'
WHEN 10 THEN 'B'
WHEN 11 THEN 'C'
WHEN 12 THEN 'D'
WHEN 13 THEN 'E'
WHEN 14 THEN 'F'
WHEN 15 THEN 'G'
WHEN 16 THEN 'H'
WHEN 17 THEN 'I'
WHEN 18 THEN 'J'
WHEN 19 THEN 'K'
WHEN 20 THEN 'L'
WHEN 21 THEN 'M'
WHEN 22 THEN 'N'
WHEN 23 THEN 'P'
WHEN 24 THEN 'Q'
WHEN 25 THEN 'R'
WHEN 26 THEN 'S'
WHEN 27 THEN 'T'
WHEN 28 THEN 'U'
WHEN 29 THEN 'V'
WHEN 30 THEN 'W'
WHEN 31 THEN 'X'
WHEN 32 THEN 'Y'
ELSE 'Z'
END
SET @VARLOOPS = @VARLOOPS + 1
-- Incluir la parte de la homoclave
SET @RFC = LTRIM(RTRIM (@RFC)) + LTRIM(RTRIM (@T_HOMOCLV))
END