SET ANSI_NULLS ON; GO SET QUOTED_IDENTIFIER ON; GO SET XACT_ABORT ON; GO /* Catálogos postales para el registro público. Este script NO elimina, vacía ni recrea las tablas pobladas. Solamente agrega columnas/índices faltantes y crea o actualiza el procedimiento almacenado de consulta. */ IF OBJECT_ID(N'dbo.Gral_SAT_CP', N'U') IS NULL THROW 51020, N'Falta la tabla poblada dbo.Gral_SAT_CP.', 1; IF OBJECT_ID(N'dbo.Gral_SAT_Municipio', N'U') IS NULL THROW 51021, N'Falta la tabla poblada dbo.Gral_SAT_Municipio.', 1; IF OBJECT_ID(N'dbo.Gral_SAT_Localidad', N'U') IS NULL THROW 51022, N'Falta la tabla poblada dbo.Gral_SAT_Localidad.', 1; IF OBJECT_ID(N'dbo.Gral_SAT_Colonia', N'U') IS NULL THROW 51023, N'Falta la tabla poblada dbo.Gral_SAT_Colonia.', 1; IF OBJECT_ID(N'dbo.Gral_SAT_Estado', N'U') IS NULL THROW 51024, N'Falta la tabla poblada dbo.Gral_SAT_Estado.', 1; IF OBJECT_ID(N'dbo.Gral_SAT_Pais', N'U') IS NULL THROW 51025, N'Falta la tabla poblada dbo.Gral_SAT_Pais.', 1; GO /* Borrado lógico incremental para los catálogos utilizados. */ DECLARE @Tablas TABLE ([Tabla] sysname NOT NULL PRIMARY KEY); INSERT INTO @Tablas ([Tabla]) VALUES (N'Gral_SAT_CP'), (N'Gral_SAT_Municipio'), (N'Gral_SAT_Localidad'), (N'Gral_SAT_Colonia'), (N'Gral_SAT_Estado'), (N'Gral_SAT_Pais'); DECLARE @Tabla sysname; DECLARE @Sql nvarchar(max); DECLARE Catalogos CURSOR LOCAL FAST_FORWARD FOR SELECT [Tabla] FROM @Tablas ORDER BY [Tabla]; OPEN Catalogos; FETCH NEXT FROM Catalogos INTO @Tabla; WHILE @@FETCH_STATUS = 0 BEGIN IF COL_LENGTH(N'dbo.' + @Tabla, N'Borrado') IS NULL BEGIN SET @Sql = N'ALTER TABLE [dbo].' + QUOTENAME(@Tabla) + N' ADD [Borrado] bit NOT NULL CONSTRAINT ' + QUOTENAME(N'DF_' + @Tabla + N'_Borrado') + N' DEFAULT ((0)) WITH VALUES;'; EXEC sys.sp_executesql @Sql; END; IF COL_LENGTH(N'dbo.' + @Tabla, N'FechaBorrado') IS NULL BEGIN SET @Sql = N'ALTER TABLE [dbo].' + QUOTENAME(@Tabla) + N' ADD [FechaBorrado] datetime2(0) NULL;'; EXEC sys.sp_executesql @Sql; END; IF NOT EXISTS ( SELECT 1 FROM sys.check_constraints WHERE [parent_object_id] = OBJECT_ID(N'dbo.' + @Tabla) AND [name] = N'CK_' + @Tabla + N'_BorradoLogico' ) BEGIN SET @Sql = N'ALTER TABLE [dbo].' + QUOTENAME(@Tabla) + N' ADD CONSTRAINT ' + QUOTENAME(N'CK_' + @Tabla + N'_BorradoLogico') + N' CHECK (([Borrado] = (0) AND [FechaBorrado] IS NULL)' + N' OR ([Borrado] = (1) AND [FechaBorrado] IS NOT NULL));'; EXEC sys.sp_executesql @Sql; END; FETCH NEXT FROM Catalogos INTO @Tabla; END; CLOSE Catalogos; DEALLOCATE Catalogos; GO IF NOT EXISTS ( SELECT 1 FROM sys.indexes WHERE [object_id] = OBJECT_ID(N'dbo.Gral_SAT_CP') AND [name] = N'IX_Gral_SAT_CP_BusquedaRegistro' ) CREATE NONCLUSTERED INDEX [IX_Gral_SAT_CP_BusquedaRegistro] ON [dbo].[Gral_SAT_CP] ([CP]) INCLUDE ([CveCP], [ClaveSATEstado], [ClaveSATMunicipio], [ClaveSATLocalidad]) WHERE [Borrado] = (0); GO IF NOT EXISTS ( SELECT 1 FROM sys.indexes WHERE [object_id] = OBJECT_ID(N'dbo.Gral_SAT_Colonia') AND [name] = N'IX_Gral_SAT_Colonia_CP_Vigente' ) CREATE NONCLUSTERED INDEX [IX_Gral_SAT_Colonia_CP_Vigente] ON [dbo].[Gral_SAT_Colonia] ([CP]) INCLUDE ([CveColonia], [ClaveSATColonia], [NombreAsentamiento]) WHERE [Borrado] = (0); GO IF NOT EXISTS ( SELECT 1 FROM sys.indexes WHERE [object_id] = OBJECT_ID(N'dbo.Gral_SAT_Municipio') AND [name] = N'IX_Gral_SAT_Municipio_Claves_Vigente' ) CREATE NONCLUSTERED INDEX [IX_Gral_SAT_Municipio_Claves_Vigente] ON [dbo].[Gral_SAT_Municipio] ([ClaveSATEstado], [ClaveSATMunicipio]) INCLUDE ([CveMunicipio], [Descripcion]) WHERE [Borrado] = (0); GO IF NOT EXISTS ( SELECT 1 FROM sys.indexes WHERE [object_id] = OBJECT_ID(N'dbo.Gral_SAT_Localidad') AND [name] = N'IX_Gral_SAT_Localidad_Claves_Vigente' ) CREATE NONCLUSTERED INDEX [IX_Gral_SAT_Localidad_Claves_Vigente] ON [dbo].[Gral_SAT_Localidad] ([ClaveSATEstado], [ClaveSATLocalidad]) INCLUDE ([CveLocalidad], [NombreLocalidad]) WHERE [Borrado] = (0); GO /* Claves normalizadas utilizadas por el registro. */ IF OBJECT_ID(N'dbo.Clientes', N'U') IS NULL THROW 51026, N'Falta la tabla dbo.Clientes.', 1; IF COL_LENGTH(N'dbo.Clientes', N'CveLocalidad') IS NULL ALTER TABLE [dbo].[Clientes] ADD [CveLocalidad] int NULL; GO IF OBJECT_ID(N'dbo.FK_Clientes_Gral_SAT_Pais', N'F') IS NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[Clientes] C LEFT JOIN [dbo].[Gral_SAT_Pais] P ON P.[CvePais]=C.[CvePais] WHERE C.[CvePais] IS NOT NULL AND P.[CvePais] IS NULL) ALTER TABLE [dbo].[Clientes] WITH CHECK ADD CONSTRAINT [FK_Clientes_Gral_SAT_Pais] FOREIGN KEY ([CvePais]) REFERENCES [dbo].[Gral_SAT_Pais] ([CvePais]); GO IF OBJECT_ID(N'dbo.FK_Clientes_Gral_SAT_Estado_Normalizado', N'F') IS NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[Clientes] C LEFT JOIN [dbo].[Gral_SAT_Estado] E ON E.[CveEstado]=C.[CveEstado] WHERE C.[CveEstado] IS NOT NULL AND E.[CveEstado] IS NULL) ALTER TABLE [dbo].[Clientes] WITH CHECK ADD CONSTRAINT [FK_Clientes_Gral_SAT_Estado_Normalizado] FOREIGN KEY ([CveEstado]) REFERENCES [dbo].[Gral_SAT_Estado] ([CveEstado]); GO IF OBJECT_ID(N'dbo.FK_Clientes_Gral_SAT_Municipio', N'F') IS NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[Clientes] C LEFT JOIN [dbo].[Gral_SAT_Municipio] M ON M.[CveMunicipio]=C.[CveMunicipio] WHERE C.[CveMunicipio] IS NOT NULL AND M.[CveMunicipio] IS NULL) ALTER TABLE [dbo].[Clientes] WITH CHECK ADD CONSTRAINT [FK_Clientes_Gral_SAT_Municipio] FOREIGN KEY ([CveMunicipio]) REFERENCES [dbo].[Gral_SAT_Municipio] ([CveMunicipio]); GO IF OBJECT_ID(N'dbo.FK_Clientes_Gral_SAT_Localidad', N'F') IS NULL ALTER TABLE [dbo].[Clientes] WITH CHECK ADD CONSTRAINT [FK_Clientes_Gral_SAT_Localidad] FOREIGN KEY ([CveLocalidad]) REFERENCES [dbo].[Gral_SAT_Localidad] ([CveLocalidad]); GO IF OBJECT_ID(N'dbo.FK_Clientes_Gral_SAT_Colonia', N'F') IS NULL AND NOT EXISTS (SELECT 1 FROM [dbo].[Clientes] C LEFT JOIN [dbo].[Gral_SAT_Colonia] CO ON CO.[CveColonia]=C.[CveColonia] WHERE C.[CveColonia] IS NOT NULL AND CO.[CveColonia] IS NULL) ALTER TABLE [dbo].[Clientes] WITH CHECK ADD CONSTRAINT [FK_Clientes_Gral_SAT_Colonia] FOREIGN KEY ([CveColonia]) REFERENCES [dbo].[Gral_SAT_Colonia] ([CveColonia]); GO CREATE OR ALTER PROCEDURE [dbo].[PA_Gral_CodigoPostalGet] @CP varchar(5), @CveUsuarioEjecuta int, @ErrorMostrar varchar(max) OUTPUT, @ErrorTipo int OUTPUT, @Return bit OUTPUT AS BEGIN SET NOCOUNT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; SET @CP = LTRIM(RTRIM(@CP)); BEGIN TRY IF LEN(@CP) <> 5 OR @CP LIKE '%[^0-9]%' BEGIN SET @ErrorMostrar = 'El código postal debe contener exactamente 5 dígitos.'; SET @ErrorTipo = 2; RETURN; END; DECLARE @CvePais int, @Pais varchar(100), @CveEstado int, @Estado varchar(50), @CveMunicipio int, @Municipio varchar(100), @CveLocalidad int, @Localidad varchar(100); SELECT TOP (1) @CvePais = P.[CvePais], @Pais = P.[Descripcion], @CveEstado = E.[CveEstado], @Estado = E.[NombreEstado], @CveMunicipio = M.[CveMunicipio], @Municipio = M.[Descripcion], @CveLocalidad = L.[CveLocalidad], @Localidad = L.[NombreLocalidad] FROM [dbo].[Gral_SAT_CP] AS CP INNER JOIN [dbo].[Gral_SAT_Estado] AS E ON E.[ClaveSATEstado] = CP.[ClaveSATEstado] AND E.[Borrado] = (0) INNER JOIN [dbo].[Gral_SAT_Pais] AS P ON P.[ClaveSATPais] = E.[ClaveSATPais] AND P.[Borrado] = (0) INNER JOIN [dbo].[Gral_SAT_Municipio] AS M ON M.[ClaveSATEstado] = CP.[ClaveSATEstado] AND M.[ClaveSATMunicipio] = CP.[ClaveSATMunicipio] AND M.[Borrado] = (0) LEFT JOIN [dbo].[Gral_SAT_Localidad] AS L ON L.[ClaveSATEstado] = CP.[ClaveSATEstado] AND L.[ClaveSATLocalidad] = CP.[ClaveSATLocalidad] AND L.[Borrado] = (0) WHERE CP.[CP] = @CP AND CP.[Borrado] = (0); IF @CvePais IS NULL OR @CveEstado IS NULL OR @CveMunicipio IS NULL BEGIN SET @ErrorMostrar = CONCAT( 'El código postal ', @CP, ' no existe o sus relaciones de país, estado y municipio están incompletas.'); SET @ErrorTipo = 2; RETURN; END; SELECT @CvePais AS [CvePais], @Pais AS [Pais], @CveEstado AS [CveEstado], @Estado AS [Estado], @CveMunicipio AS [CveMunicipio], @Municipio AS [Municipio], @CveLocalidad AS [CveLocalidad], @Localidad AS [Localidad], COALESCE(NULLIF(@Localidad, ''), @Municipio) AS [Ciudad]; SELECT C.[CveColonia], C.[NombreAsentamiento] FROM [dbo].[Gral_SAT_Colonia] AS C WHERE C.[CP] = @CP AND C.[Borrado] = (0) ORDER BY C.[NombreAsentamiento]; SET @Return = 1; END TRY BEGIN CATCH SET @ErrorMostrar = 'Ocurrió un error al consultar el código postal; favor de contactar a Sistemas.'; SET @ErrorTipo = 1; SET @Return = 0; DECLARE @E nvarchar(2048) = CONCAT( 'Número: ', ERROR_NUMBER(), '; Procedimiento: ', ERROR_PROCEDURE(), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR(N'%s', 10, 1, @E); END CATCH; END; GO CREATE OR ALTER PROCEDURE [dbo].[PA_Sis_RegistroClienteAdd] @NombreUsuario varchar(100), @HashContrasena varchar(500), @CorreoElectronico varchar(255), @RFC varchar(15), @RazonSocial varchar(200), @NombreComercial varchar(200) = NULL, @Direccion varchar(90), @NoExt varchar(20) = NULL, @NoInt varchar(50) = NULL, @Colonia varchar(100), @Ciudad varchar(100), @CveSATEstado int, @Pais varchar(100) = 'México', @CP varchar(5), @Telefono varchar(25) = NULL, @CvePais int, @CveMunicipio int, @CveLocalidad int = NULL, @CveColonia int, @HashToken char(64), @HorasExpiracion int = 24, @CveUsuarioEjecuta int, @ErrorMostrar varchar(max) OUTPUT, @ErrorTipo int OUTPUT, @Return bit OUTPUT AS BEGIN SET NOCOUNT ON; SET XACT_ABORT ON; SELECT @ErrorMostrar = NULL, @ErrorTipo = 0, @Return = 0; BEGIN TRY DECLARE @CveRolEmpresa int, @CveUsuario int, @CveCliente int; DECLARE @NombreEstado varchar(50), @PaisCatalogo varchar(100); DECLARE @CiudadCatalogo varchar(100), @ColoniaCatalogo varchar(100); SET @NombreUsuario = LTRIM(RTRIM(@NombreUsuario)); SET @CorreoElectronico = LOWER(LTRIM(RTRIM(@CorreoElectronico))); SET @RFC = UPPER(REPLACE(LTRIM(RTRIM(@RFC)), ' ', '')); SET @CP = LTRIM(RTRIM(@CP)); SELECT @CveRolEmpresa = [CveRol] FROM [dbo].[Sis_Roles] WHERE [NombreRol] = 'Empresa' AND [Activo] = (1) AND [Borrado] = (0); SELECT TOP (1) @NombreEstado = LEFT(E.[NombreEstado], 35), @PaisCatalogo = LEFT(P.[Descripcion], 50), @CiudadCatalogo = LEFT(COALESCE(NULLIF(L.[NombreLocalidad], ''), M.[Descripcion]), 50), @ColoniaCatalogo = LEFT(C.[NombreAsentamiento], 50) FROM [dbo].[Gral_SAT_CP] AS CP INNER JOIN [dbo].[Gral_SAT_Estado] AS E ON E.[ClaveSATEstado] = CP.[ClaveSATEstado] AND E.[CveEstado] = @CveSATEstado AND E.[Borrado] = (0) INNER JOIN [dbo].[Gral_SAT_Pais] AS P ON P.[ClaveSATPais] = E.[ClaveSATPais] AND P.[CvePais] = @CvePais AND P.[Borrado] = (0) INNER JOIN [dbo].[Gral_SAT_Municipio] AS M ON M.[ClaveSATEstado] = CP.[ClaveSATEstado] AND M.[ClaveSATMunicipio] = CP.[ClaveSATMunicipio] AND M.[CveMunicipio] = @CveMunicipio AND M.[Borrado] = (0) LEFT JOIN [dbo].[Gral_SAT_Localidad] AS L ON L.[ClaveSATEstado] = CP.[ClaveSATEstado] AND L.[ClaveSATLocalidad] = CP.[ClaveSATLocalidad] AND L.[Borrado] = (0) INNER JOIN [dbo].[Gral_SAT_Colonia] AS C ON C.[CP] = CP.[CP] AND C.[CveColonia] = @CveColonia AND C.[Borrado] = (0) WHERE CP.[CP] = @CP AND CP.[Borrado] = (0) AND (@CveLocalidad IS NULL OR L.[CveLocalidad] = @CveLocalidad); IF @CveRolEmpresa IS NULL BEGIN SELECT @ErrorMostrar = 'No fue posible determinar el rol Empresa.', @ErrorTipo = 1; RETURN; END; IF @NombreEstado IS NULL OR @PaisCatalogo IS NULL OR @CiudadCatalogo IS NULL OR @ColoniaCatalogo IS NULL BEGIN SELECT @ErrorMostrar = 'Los datos del código postal no coinciden con los catálogos vigentes. Actualiza el código postal.', @ErrorTipo = 2; RETURN; END; SELECT @Pais = @PaisCatalogo, @Ciudad = @CiudadCatalogo, @Colonia = @ColoniaCatalogo; IF EXISTS (SELECT 1 FROM [dbo].[Sis_Usuarios] WHERE [NombreUsuario] = @NombreUsuario) OR EXISTS (SELECT 1 FROM [dbo].[Sis_Usuarios] WHERE LOWER([CorreoElectronico]) = @CorreoElectronico) OR EXISTS (SELECT 1 FROM [dbo].[Clientes] WHERE UPPER(REPLACE(LTRIM(RTRIM([RFC])), ' ', '')) = @RFC) BEGIN SELECT @ErrorMostrar = 'Los datos ya fueron registrados por otra solicitud. Actualiza la página e inténtalo nuevamente.', @ErrorTipo = 2; RETURN; END; BEGIN TRANSACTION; INSERT INTO [dbo].[Sis_Usuarios] ([NombreUsuario], [HashContrasena], [CorreoElectronico], [CveRol], [Activo], [DebeCambiarContrasena], [CorreoVerificado]) VALUES (@NombreUsuario, @HashContrasena, @CorreoElectronico, @CveRolEmpresa, (0), (0), (0)); SET @CveUsuario = CONVERT(int, SCOPE_IDENTITY()); INSERT INTO [dbo].[Clientes] ([Nombre], [NombreComercial], [Direccion], [NoExt], [NoInt], [Colonia], [Ciudad], [Estado], [CveSATEstado], [Pais], [RFC], [CP], [Telefono], [Mail], [Estatus], [Fecha], [CveUsuario], [FechaIng], [CvePais], [CveEstado], [CveMunicipio], [CveLocalidad], [CveColonia]) VALUES (@RazonSocial, NULLIF(@NombreComercial, ''), @Direccion, NULLIF(@NoExt, ''), NULLIF(@NoInt, ''), @Colonia, @Ciudad, @NombreEstado, @CveSATEstado, @Pais, @RFC, @CP, NULLIF(@Telefono, ''), @CorreoElectronico, (0), CONVERT(date, GETDATE()), @CveUsuario, GETDATE(), @CvePais, @CveSATEstado, @CveMunicipio, @CveLocalidad, @CveColonia); SET @CveCliente = CONVERT(int, SCOPE_IDENTITY()); INSERT INTO [dbo].[Sis_UsuariosClientes] ([CveUsuario], [CveCliente], [Orden], [EsPrincipal], [Activo], [CveUsuarioRegistro]) VALUES (@CveUsuario, @CveCliente, (1), (1), (1), @CveUsuario); INSERT INTO [dbo].[Sis_UsuariosVerificacionesCorreo] ([CveUsuario], [CveClienteRegistro], [HashToken], [FechaExpiracion]) VALUES (@CveUsuario, @CveCliente, @HashToken, DATEADD(HOUR, @HorasExpiracion, SYSDATETIME())); COMMIT TRANSACTION; SELECT @CveUsuario AS [CveUsuario], @CveCliente AS [CveCliente]; SET @Return = 1; END TRY BEGIN CATCH IF XACT_STATE() <> 0 ROLLBACK TRANSACTION; SELECT @ErrorMostrar = 'Ocurrió un error al crear el registro; favor de contactar a Sistemas.', @ErrorTipo = 1, @Return = 0; DECLARE @E nvarchar(2048) = CONCAT('Número: ', ERROR_NUMBER(), '; Procedimiento: ', ERROR_PROCEDURE(), '; Línea: ', ERROR_LINE(), '; Detalle: ', ERROR_MESSAGE()); RAISERROR(N'%s', 10, 1, @E); END CATCH; END; GO /* Se registran para limpieza, pero la limpieza física queda deshabilitada. Habilitarla posteriormente requiere autorización expresa. */ IF OBJECT_ID(N'dbo.Sis_ConfigurarLimpieza', N'P') IS NOT NULL BEGIN EXEC [dbo].[Sis_ConfigurarLimpieza] @Esquema=N'dbo', @Tabla=N'Gral_SAT_CP', @DiasRetencion=365, @TamanoLote=500, @Habilitada=0; EXEC [dbo].[Sis_ConfigurarLimpieza] @Esquema=N'dbo', @Tabla=N'Gral_SAT_Municipio', @DiasRetencion=365, @TamanoLote=500, @Habilitada=0; EXEC [dbo].[Sis_ConfigurarLimpieza] @Esquema=N'dbo', @Tabla=N'Gral_SAT_Localidad', @DiasRetencion=365, @TamanoLote=500, @Habilitada=0; EXEC [dbo].[Sis_ConfigurarLimpieza] @Esquema=N'dbo', @Tabla=N'Gral_SAT_Colonia', @DiasRetencion=365, @TamanoLote=500, @Habilitada=0; EXEC [dbo].[Sis_ConfigurarLimpieza] @Esquema=N'dbo', @Tabla=N'Gral_SAT_Estado', @DiasRetencion=365, @TamanoLote=500, @Habilitada=0; EXEC [dbo].[Sis_ConfigurarLimpieza] @Esquema=N'dbo', @Tabla=N'Gral_SAT_Pais', @DiasRetencion=365, @TamanoLote=500, @Habilitada=0; END; GO