
--
-- Table structure for table `tb_tdocumento`
--

CREATE TABLE `tb_tdocumento` (
  `nombre` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_spanish_ci NOT NULL,
  `numero` int NOT NULL DEFAULT '0',
  `item` int NOT NULL AUTO_INCREMENT,
  `nombre_forma` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_spanish_ci NOT NULL,
  PRIMARY KEY (`item`)
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_spanish_ci;

--
-- Dumping data for table `tb_tdocumento`
--

INSERT INTO `tb_tdocumento` VALUES ('01001tb_f_mproyecto',0,1,''),('01001tb_f_msupervisor',8,2,''),('01001tb_f_mgrupo',10,4,''),('01001tb_f_mforma_pago',7,5,''),('01001tb_f_mfrecuencia',3,6,''),('01001tb_f_mrole',10,7,''),('0100125tb_f_mcliente',15,8,''),('0100125tb_f_mpersonal',608,9,''),('0100125tb_f_mplantilla',16,10,''),('0100125tb_f_otimesheet',1213,11,''),('01001tb_f_mindicencia_nivel',0,12,''),('01001tb_f_mincidencia',0,13,''),('0100125tb_f_oincidencia',0,14,''),('01001tb_b_mconcepto',15,15,''),('0100125tb_b_oadelanto',9,16,''),('0100125tb_b_omovimiento',67,17,''),('tb_musuario',32,18,''),('tb_musuario_grupo',11,19,''),('01001tb_b_menviado',1,20,''),('0100125tb_b_opago',840,21,''),('0100125tb_f_mdias_festivos',3,22,''),('01001tb_f_mcustomers_group',1,23,'');

--
-- Dumping routines for database 'db_bob'
--
/*!50003 DROP PROCEDURE IF EXISTS `sp_cbusqueda` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cbusqueda`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _tabla varchar(100), 
	in _campos varchar(500), 
	in _ordenado varchar(50), 
	in _bCampos varchar(500), 
	in _operador varchar(5), 
	in _valor varchar(100), 
	in _pagina int, 
	in _regpp int, 
	in _adicional varchar(5000), 
	in _tipo_estado varchar(3),
	in _estado int,
    in _usuario varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2024.12.16, 2024.12.27, 2025.01.24, 2025-05-06
		Autor: 
	---------------------------------------------------------------------------------------------------- */
	
	-- Validación de parámetros
    if (_codemp is not null) OR (_sucursal is not null) or (_tabla is not null) or (_bcampos is not null) or (_operador is not null) then
		set @bCampos = trim(_bCampos) ;
		set @tablaBA = coalesce(_tabla) ;
		set @jointb = '';
		set @camposB = '' ;
		set @cSentencia = '' ;
		set @estado = coalesce(_estado, 0) ;
		
		-- ----------------------------------------------------------------------------------------------------
		-- crea el cursor que validará los números que solo aplican para la búsqueda de los presupuestos.
		call str_cadena(_codemp, _sucursal, _tabla, @tablaBA, @jointb, _campos, @camposB, _ordenado, _bCampos, _operador, _valor, _pagina, _regpp, _adicional, _tipo_estado, @estado, '', '', 0, @cSentencia) ;
		
		-- ----------------------------------------------------------------------------------------------------
		select 	sentencia.*, 
				coalesce(cfg_mestado.nombre, '') as nestado,
				coalesce(cfg_mestado.clase_css, '') as nestado_clase_css,
				coalesce(cfg_mestado.img_icon, '') as nestado_img_icon,
				@iPagina as PagAct, 
				@iPaginaUltima as PagUltima, 
				@iNumeroFila as Filas 
			from sentencia
				left join cfg_mestado 
					on sentencia.estado = cfg_mestado.codigo 
						and cfg_mestado.tipo = rtrim(_tipo_estado) 
			order by sentencia.RegFila ;
	else
		select -1 ;
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cbusqueda_basico` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cbusqueda_basico`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _tabla varchar(100), 
	in _campos varchar(500), 
	in _ordenado varchar(50), 
	in _bCampos varchar(500), 
	in _operador varchar(5), 
	in _valor varchar(100), 
	in _pagina int, 
	in _regpp int, 
	in _adicional varchar(5000), 
	in _tipo_estado varchar(3),
	in _estado int,
    in _usuario varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2024.12.16, 2024.12.26, 2025.01.24, 2025-05-06
		Autor: 
	---------------------------------------------------------------------------------------------------- */
	
	-- Validación de parámetros
    if (_codemp is not null) OR (_sucursal is not null) or (_tabla is not null) or (_bcampos is not null)  or (_operador is not null) then
		set @bCampos = trim(_bCampos) ;
		set @tablaBA = coalesce(_tabla) ;
		set @jointb = '';
		set @camposB = '' ;
		set @cSentencia = '' ;
		set @estado = coalesce(_estado, 0) ;
		
		-- ----------------------------------------------------------------------------------------------------
		-- crea el cursor que validará los números que solo aplican para la búsqueda de los presupuestos.
		call str_cadena(_codemp, _sucursal, _tabla, @tablaBA, @jointb, _campos, @camposB, _ordenado, _bCampos, _operador, _valor, _pagina, _regpp, _adicional, _tipo_estado, @estado, '', '', 0, @cSentencia) ;
		
		-- ----------------------------------------------------------------------------------------------------
		select 	sentencia.*, 
				coalesce(cfg_mestado.nombre, '') as nestado,
				coalesce(cfg_mestado.clase_css, '') as nestado_clase_css,
				coalesce(cfg_mestado.img_icon, '') as nestado_img_icon,
				@iPagina as PagAct, 
				@iPaginaUltima as PagUltima, 
				@iNumeroFila as Filas 
			from sentencia
				left join cfg_mestado 
					on sentencia.estado = cfg_mestado.codigo 
						and cfg_mestado.tipo = rtrim(_tipo_estado) 
			order by RegFila ;
	else
		select -1 ;
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cbusqueda_basico_fecha` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cbusqueda_basico_fecha`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _tabla varchar(25), 
	in _campos varchar(500), 
	in _ordenado varchar(50), 
	in _bCampos varchar(500), 
	in _operador varchar(5), 
	in _valor varchar(100), 
	in _pagina int, 
	in _regpp int, 
	in _adicional varchar(5000), 
	in _tipo_estado varchar(3),
	in _estado varchar(3),
	in _desde varchar(10),
	in _hasta varchar(10),
	in _valor1 varchar(15),
	in _valor2 varchar(15),
    in _usuario varchar(10)
)
BEGIN
	/* ----------------------------------------------------------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 2025-08-29
		Actualizado: 2025-08-29
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
	-- Validación de parámetros
    if (_codemp is not null) OR (_sucursal is not null) or (_tabla is not null) or (_bcampos is not null)  or (_operador is not null) then
		set @bCampos = trim(_bCampos) ;
		set @tablaBA = coalesce(_tabla) ;
		set @jointb = '';
		set @camposB = '' ;
		set @cSentencia = '' ;
        set @valor1 = '' ;
        set @valor2 = '' ;
		set @estado = coalesce(_estado, 0) ;
        set @adicional = _adicional ;
		set @adicional = concat(@adicional, @valor1, @valor2) ;
        
		-- ----------------------------------------------------------------------------------------------------
		-- crea el cursor que validará los números que solo aplican para la búsqueda de los presupuestos.
		call str_cadena(_codemp, _sucursal, _tabla, @tablaBA, @jointb, _campos, @camposB, _ordenado, _bCampos, _operador, _valor, _pagina, _regpp, @adicional, _tipo_estado, @estado, _desde, _hasta, 1, @cSentencia) ;
		
		-- ----------------------------------------------------------------------------------------------------
		
        select 	sentencia.*, 
				coalesce(cfg_mestado.nombre, '') as nestado,
				coalesce(cfg_mestado.clase_css, '') as nestado_clase_css,
				coalesce(cfg_mestado.img_icon, '') as nestado_img_icon,
				@iPagina as PagAct, 
				@iPaginaUltima as PagUltima, 
				@iNumeroFila as Filas 
			from sentencia
				left join cfg_mestado 
					on sentencia.estado = cfg_mestado.codigo 
						and cfg_mestado.tipo = rtrim(_tipo_estado)
			order by sentencia.RegFila ;
		
	else
		select -1 ;
	end if ;
END ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cbusqueda_cfg_mempresa` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cbusqueda_cfg_mempresa`(	
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _tabla varchar(25), 
	in _campos varchar(500), 
	in _ordenado varchar(50), 
	in _bCampos varchar(500), 
	in _operador varchar(5), 
	in _valor varchar(100), 
	in _pagina int, 
	in _regpp int, 
	in _adicional varchar(5000), 
	in _tipo_estado varchar(3),
	in _estado int,
    in _usuario varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2024.12.16, 2025.01.24, 2025-05-06
		Autor: 
	---------------------------------------------------------------------------------------------------- */
	
	-- Validación de parámetros
    if (_codemp is not null) OR (_sucursal is not null) or (_tabla is not null) or (_bcampos is not null)  or (_operador is not null) then
		set @bCampos = trim(_bCampos) ;
		set @tablaBA = coalesce(_tabla) ;
		set @jointb = '';
		set @camposB = '' ;
		set @cSentencia = '' ;
		set @estado = coalesce(_estado, 0) ;
		
		-- ----------------------------------------------------------------------------------------------------
		-- crea el cursor que validará los números que solo aplican para la búsqueda de los presupuestos.
		call str_cadena_codigo(_codemp, _sucursal, _tabla, @tablaBA, @jointb, _campos, @camposB, _ordenado, _bCampos, _operador, _valor, _pagina, _regpp, _adicional, _tipo_estado, @estado, '', '', 0, @cSentencia) ;
		   
		-- ----------------------------------------------------------------------------------------------------
		select sentencia.*,
				coalesce(tb_g_mdivisa_b.nombre, '') as ndivisa,
				coalesce(tb_g_mdivisa_c.nombre, '') as nmoneda,
				coalesce(cfg_mestado.nombre, '') as nestado,
				coalesce(cfg_mestado.clase_css, '') as nestado_clase_css,
				coalesce(cfg_mestado.img_icon, '') as nestado_img_icon,
				@iPagina as PagAct, 
				@iPaginaUltima as PagUltima, 
				@iNumeroFila as Filas 
			from sentencia 
				left join tb_g_mdivisa as tb_g_mdivisa_b 
					on sentencia.codigo = tb_g_mdivisa_b.codemp
						and sentencia.divisa = tb_g_mdivisa_b.codigo
				left join tb_g_mdivisa as tb_g_mdivisa_c 
					on sentencia.codigo = tb_g_mdivisa_c.codemp
						and sentencia.moneda = tb_g_mdivisa_c.codigo
				left join cfg_mestado 
					on sentencia.estado = cfg_mestado.codigo 
						and cfg_mestado.tipo = trim(_tipo_estado) 
			order by sentencia.Regfila ;
	else
		select -1 ;
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cbusqueda_c_opurchase_orders` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cbusqueda_c_opurchase_orders`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _tabla varchar(25), 
	in _campos varchar(500), 
	in _ordenado varchar(50), 
	in _bCampos varchar(500), 
	in _operador varchar(5), 
	in _valor varchar(100), 
	in _pagina int, 
	in _regpp int, 
	in _adicional varchar(5000), 
	in _tipo_estado varchar(3),
	in _estado varchar(3),
	in _desde varchar(10),
	in _hasta varchar(10),
    in _usuario varchar(10)
	-- in _valor1 varchar(15),
	-- in _valor2 varchar(15)
)
BEGIN
	/* ----------------------------------------------------------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 2025-08-29
		Actualizado: 2025-09-07
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
	-- Validación de parámetros
    if (_codemp is not null) OR (_sucursal is not null) or (_tabla is not null) or (_bcampos is not null)  or (_operador is not null) then
		set @usuario = coalesce(_usuario) ;
		select	coalesce(u218, '') into @cliente
			from tb_musuario
			where u201 = @usuario ;
		
		set @bCampos = trim(_bCampos) ;
		set @tablaBA = coalesce(_tabla) ;
		set @jointb = '';
		set @camposB = '' ;
		set @cSentencia = '' ;
        set @valor1 = case when @cliente = '' then '' else concat('cliente = "', @cliente, '"') end ;
        set @valor2 = '' ;
		set @estado = coalesce(_estado, 0) ;
        set @adicional = _adicional ;
		set @adicional = concat(@adicional, @valor1, @valor2) ;
        
		-- ----------------------------------------------------------------------------------------------------
		-- crea el cursor que validará los números que solo aplican para la búsqueda de los presupuestos.
		call str_cadena(_codemp, _sucursal, _tabla, @tablaBA, @jointb, _campos, @camposB, _ordenado, _bCampos, _operador, _valor, _pagina, _regpp, @adicional, _tipo_estado, @estado, _desde, _hasta, 1, @cSentencia) ;
		
		-- ----------------------------------------------------------------------------------------------------
		
        select 	sentencia.*, 
                coalesce(tb_c_mvendors.nombre, '') as nvendor,
				coalesce(tb_f_mcustomers.nombre, '') as ncustomer,
				coalesce(cfg_mestado.nombre, '') as nestado,
				coalesce(cfg_mestado.clase_css, '') as nestado_clase_css,
				coalesce(cfg_mestado.img_icon, '') as nestado_img_icon,
				@iPagina as PagAct, 
				@iPaginaUltima as PagUltima, 
				@iNumeroFila as Filas 
			from sentencia
				left join tb_c_mvendors
					on sentencia.codemp = tb_c_mvendors.codemp
						and sentencia.sucursal = tb_c_mvendors.sucursal
                        and sentencia.proveedor = tb_c_mvendors.codigo
				left join tb_f_mcustomers
					on sentencia.codemp = tb_f_mcustomers.codemp
						and sentencia.sucursal = tb_f_mcustomers.sucursal
                        and sentencia.cliente = tb_f_mcustomers.codigo
				left join cfg_mestado 
					on sentencia.estado = cfg_mestado.codigo 
						and cfg_mestado.tipo = rtrim(_tipo_estado)
			order by sentencia.RegFila ;
		
	else
		select -1 ;
	end if ;
END ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cbusqueda_f_sales_orders` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cbusqueda_f_sales_orders`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _tabla varchar(25), 
	in _campos varchar(500), 
	in _ordenado varchar(50), 
	in _bCampos varchar(500), 
	in _operador varchar(5), 
	in _valor varchar(100), 
	in _pagina int, 
	in _regpp int, 
	in _adicional varchar(5000), 
	in _tipo_estado varchar(3),
	in _estado varchar(3),
	in _desde varchar(10),
	in _hasta varchar(10),
    in _usuario varchar(10)
)
BEGIN
	/* ----------------------------------------------------------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 2025-08-29
		Actualizado: 2025-09-27
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
	-- Validación de parámetros
    if (_codemp is not null) OR (_sucursal is not null) or (_tabla is not null) or (_bcampos is not null)  or (_operador is not null) then
		set @usuario = coalesce(_usuario) ;
		select	coalesce(u218, '') into @grupo
			from tb_musuario
			where u201 = @usuario ;
        
        set @bCampos = trim(_bCampos) ;
		set @tablaBA = trim(coalesce(_tabla, '')) ;
        if coalesce(@grupo, '') <> '' then
			set @jointb = ' inner join tb_f_mcustomers_group_d';
			set @jointb = concat(@jointb, ' on ', @tablaBA, '.codemp = tb_f_mcustomers_group_d.codemp') ;
			set @jointb = concat(@jointb, ' and ', @tablaBA, '.sucursal = tb_f_mcustomers_group_d.sucursal') ;
			set @jointb = concat(@jointb, ' and ', @tablaBA, '.cliente = tb_f_mcustomers_group_d.cliente') ;
            set @jointb = concat(@jointb, ' and tb_f_mcustomers_group_d.codigo = ', @grupo) ;
		else
			set @jointb = '';
		end if ;
        
		set @camposB = '' ;
		set @cSentencia = '' ;
		set @bCampos = trim(_bCampos) ;
		set @camposB = '' ;
		set @cSentencia = '' ;
        set @valor1 = '' ; 	-- case when @cliente = '' then '' else concat(' and cliente = "', @cliente, '"') end ;
        set @valor2 = '' ;
		set @estado = coalesce(_estado, 0) ;
        set @adicional = _adicional ;
		set @adicional = concat(@adicional, @valor1, @valor2) ;
        
		-- ----------------------------------------------------------------------------------------------------
		-- crea el cursor que validará los números que solo aplican para la búsqueda de los presupuestos.
		call str_cadena(_codemp, _sucursal, _tabla, @tablaBA, @jointb, _campos, @camposB, _ordenado, _bCampos, _operador, _valor, _pagina, _regpp, @adicional, _tipo_estado, @estado, _desde, _hasta, 1, @cSentencia) ;
		
		-- ----------------------------------------------------------------------------------------------------
		
        select 	sentencia.*, 
				coalesce(tb_f_mcustomers.nombre, '') as ncustomer,
				coalesce(cfg_mestado.nombre, '') as nestado,
				coalesce(cfg_mestado.clase_css, '') as nestado_clase_css,
				coalesce(cfg_mestado.img_icon, '') as nestado_img_icon,
				@iPagina as PagAct, 
				@iPaginaUltima as PagUltima, 
				@iNumeroFila as Filas 
			from sentencia
				left join tb_f_mcustomers
					on sentencia.codemp = tb_f_mcustomers.codemp
						and sentencia.sucursal = tb_f_mcustomers.sucursal
                        and sentencia.cliente = tb_f_mcustomers.codigo
				left join cfg_mestado 
					on sentencia.estado = cfg_mestado.codigo 
						and cfg_mestado.tipo = rtrim(_tipo_estado)
			order by sentencia.RegFila ;
		
	else
		select -1 ;
	end if ;
END ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cbusqueda_maestros` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cbusqueda_maestros`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _tabla varchar(100), 
	in _campos varchar(500), 
	in _ordenado varchar(50), 
	in _bCampos varchar(500), 
	in _operador varchar(5), 
	in _valor varchar(100), 
	in _pagina int, 
	in _regpp int, 
	in _adicional varchar(5000), 
	in _tipo_estado varchar(3),
	in _estado int,
    in _usuario varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 2025-08-28
		Actualizado: 2025-08-28
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
	-- Validación de parámetros
    if (_codemp is not null) OR (_sucursal is not null) or (_tabla is not null) or (_bcampos is not null)  or (_operador is not null) then
		set @bCampos = trim(_bCampos) ;
		set @tablaBA = coalesce(_tabla) ;
		set @jointb = '';
		set @camposB = '' ;
		set @cSentencia = '' ;
		set @estado = coalesce(_estado, 0) ;
		
		-- ----------------------------------------------------------------------------------------------------
		-- crea el cursor que validará los números que solo aplican para la búsqueda de los presupuestos.
		call str_cadena(_codemp, _sucursal, _tabla, @tablaBA, @jointb, _campos, @camposB, _ordenado, _bCampos, _operador, _valor, _pagina, _regpp, _adicional, _tipo_estado, @estado, '', '', 0, @cSentencia) ;
		   
		-- ----------------------------------------------------------------------------------------------------
		select 	sentencia.*, 
				coalesce(tb_g_mpais.nombre, '') as npais,
				concat(trim(coalesce(tb_g_mestado_ciudad.nombre, '')), ' [', sentencia.pais, ']') as nestado_ciudad,
                coalesce(tb_g_mciudad.nombre, '') as nciudad,
				coalesce(cfg_mestado.nombre, '') as nestado,
				coalesce(cfg_mestado.clase_css, '') as nestado_clase_css,
				coalesce(cfg_mestado.img_icon, '') as nestado_img_icon,
				@iPagina as PagAct, 
				@iPaginaUltima as PagUltima, 
				@iNumeroFila as Filas 
			from sentencia
				left join tb_g_mpais
					on sentencia.pais = tb_g_mpais.codigo
				left join tb_g_mestado_ciudad
					on sentencia.pais = tb_g_mestado_ciudad.pais
						and sentencia.estado_ciudad = tb_g_mestado_ciudad.codigo
				left join tb_g_mciudad
					on sentencia.pais = tb_g_mciudad.pais
						and sentencia.estado_ciudad = tb_g_mciudad.estado_ciudad
                        and sentencia.ciudad = tb_g_mciudad.codigo
				left join cfg_mestado 
					on sentencia.estado = cfg_mestado.codigo 
						and cfg_mestado.tipo = trim(_tipo_estado) 
			order by sentencia.RegFila ;
	else
		select -1 ; 
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cbusqueda_musuario` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cbusqueda_musuario`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _tabla varchar(25), 
	in _campos varchar(500), 
	in _ordenado varchar(50), 
	in _bCampos varchar(500), 
	in _operador varchar(5), 
	in _valor varchar(100), 
	in _pagina int, 
	in _regpp int, 
	in _adicional varchar(5000), 
	in _tipo_estado varchar(3),
	in _estado int,
    in _usuario varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2025-09-28
		Autor: Iluminado
	---------------------------------------------------------------------------------------------------- */
    
	-- Validación de parámetros
    if (_codemp is not null) OR (_sucursal is not null) or (_tabla is not null) or (_bcampos is not null)  or (_operador is not null) then
		set @usuario = coalesce(_usuario) ;
		select	coalesce(u218, ''), coalesce(u230, 0) into @grupo, @nivel
			from tb_musuario
			where u201 = @usuario ;
        
		set @iLimite = _regpp ;
		set @iPagina = _pagina ;
		set @cCampos = _campos ;
		set @iLimiteInicio = ((@iPagina - 1) * @iLimite) ;
		set @Fila = 0 ;
		set @cadena = '' ;
		
        set @cadena = concat(' where u230 between 1 and ', @nivel) ;
		if trim(coalesce(_valor, '')) <> '' then
			if _operador='LIKE' then
				set @cadena = concat(@cadena, ' and ', trim(_bCampos), ' LIKE ', '''','%',trim(_valor), '%','''');
			else
				set @cadena = concat(@cadena, ' and ', trim(_bCampos), trim(_operador), '''',trim(_valor), '''');
			end if ;
		end if ;
		
		if coalesce(_adicional, '') <> '' then
			if trim(coalesce(@cadena, '')) = '' then
				set @cadena = concat(@cadena, ' and ', trim(_adicional)) ;
			else
				set @cadena = concat(@cadena, ' and ', _adicional) ;
			end if;
		end if;
		
		drop temporary table if exists sentencia ;
		set @cSentencia = concat('CREATE TEMPORARY TABLE sentencia SELECT SQL_CALC_FOUND_ROWS ',@cCampos,', (@fila:= @fila + 1) as RegFila', ' FROM ', trim(_tabla), @cadena, ' ORDER BY ', rtrim(_ordenado), ' LIMIT ', @iLimiteInicio, ', ',  @iLimite);
		PREPARE sentencia from @cSentencia ;
		EXECUTE sentencia ;
		DEALLOCATE PREPARE sentencia ;
		
		set @iNumeroFila = FOUND_ROWS() ;
		set @iPaginaUltima =  round((@iNumeroFila/@iLimite), 0) ;
		if coalesce(@iPaginaUltima, 0) = 0 then
			set @iPaginaUltima = 1 ;
		end if ;
		
        -- ----------------------------------------------------------------------------------------------------
		select sentencia.*,
				'' as ngrupo, 
				'' as nsupervisor, 
                '' as nplantilla,
                coalesce(cfg_mlenguaje.nombre, '') nlenguaje,
                coalesce(cfg_timezones.nombre, '') as ntimezones,
				coalesce(cfg_mestado.nombre, '') as nestado,
				coalesce(cfg_mestado.clase_css, '') as nestado_clase_css,
				coalesce(cfg_mestado.img_icon, '') as nestado_img_icon,
				@iPagina as PagAct, 
				@iPaginaUltima as PagUltima, 
				@iNumeroFila as Filas 
			from sentencia 
				left join tb_musuario_grupo 
					on sentencia.u206 = tb_musuario_grupo.u201 
				left join cfg_mlenguaje
					on sentencia.u212 = cfg_mlenguaje.codigo
				left join cfg_timezones
					on cfg_timezones.codemp = _codemp
						and sentencia.u217 = cfg_timezones.codigo
				left join cfg_mestado 
					on sentencia.estado = cfg_mestado.codigo 
						and cfg_mestado.tipo = rtrim(_tipo_estado) 
			order by sentencia.RegFila ;
	else
		select -1 ;
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cbusqueda_musuario_grupo` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cbusqueda_musuario_grupo`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _tabla varchar(25), 
	in _campos varchar(500), 
	in _ordenado varchar(50), 
	in _bcampos varchar(500), 
	in _operador varchar(5), 
	in _valor varchar(100), 
	in _pagina int, 
	in _regpp int, 
	in _adicional varchar(5000), 
	in _tipo_estado varchar(3),
	in _estado int,
    in _usuario varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 05/05/2014
		Actualizado: 2024.04.13, 07/08/2014, 2024.12.27, 2025-05-06
		Autor: 
	---------------------------------------------------------------------------------------------------- */
    
	if (_codemp is not null) OR (_sucursal is not null) or (_bcampos is not null)  or (_operador is not null) then
		set @usuario = coalesce(_usuario) ;
		select	coalesce(u218, ''), coalesce(u230, 0) into @grupo, @nivel
			from tb_musuario
			where u201 = @usuario ;
            
		set @iLimite = _regpp ;
		set @iPagina = _pagina ;
		set @cCampos = _campos ;
		set @iLimiteInicio = ((@iPagina - 1) * @iLimite) ;
		set @Fila = 0 ;
		set @cadena = '' ;
		
        set @cadena = concat(' where u230 between 1 and ', @nivel) ;
		if trim(coalesce(_valor, '')) <> '' then
			if _operador='LIKE' then
				set @cadena = concat(@cadena, ' and ', trim(_bCampos), ' LIKE ', '''','%',trim(_valor), '%','''');
			else
				set @cadena = concat(@cadena, ' and ', trim(_bCampos), trim(_operador), '''',trim(_valor), '''');
			end if;
		end if ;
		
		if coalesce(_adicional, '') <> '' then
			if trim(coalesce(@cadena, '')) = '' then
				set @cadena = concat(@cadena, ' and ', trim(_adicional)) ;
			else
				set @cadena = concat(@cadena, ' and ', _adicional) ;
			end if;
		end if;
		
		drop temporary table if exists sentencia ;
		set @cSentencia = concat('CREATE TEMPORARY TABLE sentencia SELECT SQL_CALC_FOUND_ROWS ',@cCampos,', (@fila:= @fila + 1) as RegFila',' FROM ', trim(_tabla), @cadena, ' ORDER BY ', rtrim(_ordenado), ' LIMIT ', @iLimiteInicio, ', ',  @iLimite);
		prepare sentencia from @cSentencia ;
		execute sentencia ;
		deallocate prepare sentencia ;
		
		set @iNumeroFila = FOUND_ROWS();
		set @iPaginaUltima =  round((@iNumeroFila/@iLimite), 0) ;
		if coalesce(@iPaginaUltima, 0) = 0 then
			set @iPaginaUltima = 1 ;
		end if ;
		
        -- ----------------------------------------------------------------------------------------------------
		select 	sentencia.*, 
				coalesce(cfg_mestado.nombre, '') as nestado,
				coalesce(cfg_mestado.clase_css, '') as nestado_clase_css,
				coalesce(cfg_mestado.img_icon, '') as nestado_img_icon,
				@iPagina as PagAct, 
				@iPaginaUltima as PagUltima, 
				@iNumeroFila as Filas 
			from sentencia
				left join cfg_mestado on sentencia.estado = cfg_mestado.codigo and cfg_mestado.tipo = rtrim(_tipo_estado) 
			order by sentencia.RegFila ;
	else
		select -1 ;
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cbusqueda_nocode` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cbusqueda_nocode`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _tabla varchar(100), 
	in _campos varchar(500), 
	in _ordenado varchar(50), 
	in _bCampos varchar(500), 
	in _operador varchar(5), 
	in _valor varchar(100), 
	in _pagina int, 
	in _regpp int, 
	in _adicional varchar(5000), 
	in _tipo_estado varchar(3),
	in _estado int,
    in _usuario varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2024.12.16, 2024.12.27
		Autor: 
	---------------------------------------------------------------------------------------------------- */
	
	-- Validación de parámetros
    if (_codemp is not null) OR (_sucursal is not null) or (_tabla is not null) or (_bcampos is not null) or (_operador is not null) then
		set @codemp = '..' ;
		set @bCampos = trim(_bCampos) ;
		set @tablaBA = coalesce(_tabla) ;
		set @jointb = '';
		set @camposB = '' ;
		set @cSentencia = '' ;
		set @estado = coalesce(_estado, 0) ;
		
		-- ----------------------------------------------------------------------------------------------------
		-- crea el cursor que validará los números que solo aplican para la búsqueda de los presupuestos.
		call str_cadena_nocode(@codemp, @codemp, _tabla, @tablaBA, @jointb, _campos, @camposB, _ordenado, _bCampos, _operador, _valor, _pagina, _regpp, _adicional, _tipo_estado, @estado, '', '', 0, @cSentencia) ;
		
		-- ----------------------------------------------------------------------------------------------------
		select 	sentencia.*,
				@iPagina as PagAct, 
				@iPaginaUltima as PagUltima, 
				@iNumeroFila as Filas 
			from sentencia
			order by sentencia.RegFila ;
	else
		select -1 ;
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cbusqueda_std_b` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cbusqueda_std_b`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _tabla varchar(50), 
	in _campos varchar(500), 
	in _ordenado varchar(50), 
	in _bcampos varchar(500), 
	in _operador varchar(5), 
	in _valor varchar(100), 
	in _pagina int, 
	in _regpp int, 
	in _adicional varchar(5000), 
	in _tipo_estado varchar(3),
    in _usuario varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Busqueda y paginador estandar para detalle de formularios 
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2025.01.03, 2025.01.24
		Autor: 
	---------------------------------------------------------------------------------------------------- */
	if (_codemp is null) OR (_sucursal is null) or (_tabla is null) or (_bcampos is null)  or (_operador is null) then
		set @ilimite = _regpp ;
		set @iPagina = _pagina ;
		set @cCampos = _campos ;
		set @ilimiteInicio = ((@iPagina - 1) * @ilimite) ;
		set @Fila = 0 ;
		
		-- Se filtra por empresa y sucursal
		set @sql_where = concat(' where codemp = ', _codemp);
		if trim(_sucursal) <> '' then
			set @sql_where = concat(@sql_where, ' and sucursal = ', _sucursal);
		end if;
		-- ----------------------------------------------------------------------------------------------------
		
		if trim(coalesce(_valor, '')) <> '' then
			set @sql_where = if(_operador = 'LIKE', concat(' where ', trim(_bCampos), ' like ', '''','%',trim(_valor), '%',''''), concat(' where ', trim(_bCampos), trim(_operador), '''',trim(_valor), '''') );
		end if ;
		if coalesce(_adicional, '') <> '' then
			set @sql_where = if(trim(coalesce(@sql_where, '')) = '', concat(' where ', trim(_adicional)), concat(@sql_where, ' and ', _adicional) );
		end if;
		
		set @sql_where = concat('create temporary table sql_tabla select SQL_CALC_found_ROWS ',@cCampos,', (@fila:= @fila + 1) as RegFila',' from ', trim(_tabla), @sql_where, ' order by ', rtrim(_ordenado), ' limit ', @ilimiteInicio, ', ',  @ilimite);
		drop temporary table sql_tabla ;
        prepare sql_tabla from @sql_where;
		execute sql_tabla ;
		deallocate prepare sql_tabla ;
		
		set @iNumerofila = found_ROWS();
		set @ipaginaultima =  round((@iNumeroFila/@ilimite), 0) ;
		set @iPaginaultima = if(round(@inumerofila/@ilimite, 0) = 0, 1, coalesce(round((@inumerofila/@ilimite), 0), 0)) ;
		set @sql_where = null;
		
        -- ----------------------------------------------------------------------------------------------------
		select 	sql_tabla.*, 
				1 as marca,
				@ipagina as pagAct, 
				@ipaginaUltima as PagUltima, 
				@iNumeroFila as Filas 
			from sql_tabla
				where sql_tabla.estado = 1
			order by RegFila ;
	else
		select -1 ;
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cbusqueda_s_log` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cbusqueda_s_log`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _tabla varchar(25), 
	in _campos varchar(500), 
	in _ordenado varchar(50), 
	in _bcampos varchar(500), 
	in _operador varchar(5), 
	in _valor varchar(100), 
	in _pagina int, 
	in _regpp int, 
	in _adicional varchar(5000), 
	in _tipo_estado varchar(3),
	in _estado int,
	in _desde varchar(10),
	in _hasta varchar(10),
    in _usuario varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 2024-12-01
		Actualizado: 2024-12-16, 2025-01-24, 2025-04-13, 2025-04-15, 2025-04-16
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
	set @usuario = coalesce(_usuario) ;
	select	coalesce(u218, ''), coalesce(u230, 0) into @grupo, @nivel
		from tb_musuario
		where u201 = @usuario ;
            
	set @bCampos = trim(_bCampos) ;
	set @tablaBA = coalesce(_tabla) ;
	set @jointb = concat(' inner join tb_musuario on tb_s_log.usuario = tb_musuario.u201 and tb_musuario.u230 between 1 and ', @nivel) ;
	set @camposB = '' ;
	set @cSentencia = '' ;
	set @supervisor = '' ;
	set @plantillas = '' ;
	set @estado = coalesce(_estado, 0) ;
	set @adicional = _adicional ;
	set @adicional = concat(@adicional, @supervisor, @plantillas) ;
   
	-- ----------------------------------------------------------------------------------------------------
	-- crea el cursor que validará los números que solo aplican para la búsqueda de los presupuestos.
	call str_cadena_log(_codemp, _sucursal, _tabla, @tablaBA, @jointb, _campos, @camposB, _ordenado, _bCampos, _operador, _valor, _pagina, _regpp, @adicional, _tipo_estado, @estado, _desde, _hasta, 1, @cSentencia) ;
	
	
	-- ----------------------------------------------------------------------------------------------------
	/*
	drop temporary table if exists op0 ;
	create temporary table op0
		select 0 as codigo, 'acceso' as nombre
			union select 1 as codigo, 'new' as nombre
			union select 2 as codigo, 'edit' as nombre
			union select 3 as codigo, 'delete' as nombre
			union select 4 as codigo, 'void' as nombre
			union select 5 as codigo, 'print' as nombre 
			union select 6 as codigo, 'send' as nombre        
			union select 7 as codigo, 'Approved' as nombre
			union select 8 as codigo, 'Processed' as nombre;
		*/
		
	
	select 	sentencia.*, 
			coalesce(tb_musuario.u202, '') as nusuario, 
			coalesce(cfg_lista_formularios.titulo, 'Acceso') as nformulario, 
			coalesce(cfg_mestado_log.nombre, '') as noperacion,
			coalesce(cfg_mestado_log.clase_css, '') as nestado_clase_css,
			coalesce(cfg_mestado_log.img_icon, '') as nestado_img_icon,
			
			@iPagina as PagAct, 
			@iPaginaUltima as PagUltima, 
			@iNumeroFila as Filas 
		from sentencia
			left join tb_musuario 
				on sentencia.usuario = tb_musuario.u201
			left join cfg_lista_formularios 
				on sentencia.formulario = cfg_lista_formularios.formulario
			left join cfg_mestado_log 
				on sentencia.operacion = cfg_mestado_log.codigo ;
		-- order by sentencia.item ;
		
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cfg_formulario_aesed_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cfg_formulario_aesed_c`(
	in _e01 int,
    in _e02 varchar(15),
    in _e03 varchar(50),
    out _e04 varchar(150)
)
begin
	select coalesce(e04, '') into @e04
		from cfg_formulario_pasod
        where e01 = _e01
			and e02 = _e02
            and e03 = _e03 ;
	
    if coalesce(@e04, '') = '' then
		select substring(RAND(), 3, 10) into @e04 ;
        insert into cfg_formulario_pasod (e01, e02, e03, e04)
			select _e01, _e02, _e03, @e04 ;
    end if ;
    set _e04 = @e04 ;
    
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cfg_formulario_detalle_campos` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cfg_formulario_detalle_campos`(
	_formulario int
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Consulta los campos del formulario para el detalle de campo
		Versión 1.0
		Creado: 08/06/2016
		Actualizado: 2025-01-30
		Autor: 
	---------------------------------------------------------------------------------------------------- */
	
	select 	cfg_formulario_detalle_campos.*, 
			coalesce(cfg_opciones_campos.readonly, cfg_formulario_detalle_campos.readonly, 1) as readonly      
		from cfg_formulario_detalle_campos 
			left join cfg_opciones_campos 
				on cfg_formulario_detalle_campos.formulario = cfg_opciones_campos.formulario
					and cfg_formulario_detalle_campos.id_detalle = cfg_opciones_campos.id_detalle
					and cfg_formulario_detalle_campos.campo = cfg_opciones_campos.campo
		where cfg_formulario_detalle_campos.formulario = _formulario
		order by cfg_formulario_detalle_campos.id_detalle, cfg_formulario_detalle_campos.orden ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cfg_mempresa_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cfg_mempresa_c`(
	in _codemp varchar(2)
)
begin
	-- ----------------------------------------------------
	-- Consulta datos de la empresa
	-- Versión 1.0
	-- Creado: 14/05/2015
	-- Actualizado: 2024.04.13, 18/07/2018
	-- Autor: 
	-- ----------------------------------------------------

	select	cfg_mempresa.codigo, 
			cfg_mempresa.nombre, 
            cfg_mempresa.pais, 
            cfg_mempresa.estado_ciudad, 
            cfg_mempresa.ciudad, 
            cfg_mempresa.zcode, 
            cfg_mempresa.web, 
            cfg_mempresa.email, 
            cfg_mempresa.telefono, 
            cfg_mempresa.direccion, 
            cfg_mempresa.divisa, 
            coalesce(tb_g_mdivisa_b.nombre, '') as ndivisa,
            cfg_mempresa.moneda, 
            coalesce(tb_g_mdivisa_c.nombre, '') as nmoneda,
            cfg_mempresa.logo, 
            cfg_mempresa.logo_qr, 
            cfg_mempresa.plataforma_a, 
            cfg_mempresa.plataforma_b, 
            cfg_mempresa.plataforma_c,
            cfg_mempresa.plataforma_d,
            cfg_mempresa.estado,
            coalesce(cfg_mestado.nombre, '') as nestado
		from cfg_mempresa
			left join tb_g_mdivisa as tb_g_mdivisa_b 
				on cfg_mempresa.codigo = tb_g_mdivisa_b.codemp
					and cfg_mempresa.divisa = tb_g_mdivisa_b.codigo
			left join tb_g_mdivisa as tb_g_mdivisa_c 
				on cfg_mempresa.codigo = tb_g_mdivisa_c.codemp
					and cfg_mempresa.moneda = tb_g_mdivisa_c.codigo
			left join cfg_mestado 
				on cfg_mempresa.estado = cfg_mestado.codigo 
					and cfg_mestado.tipo = trim('MAE')
		where cfg_mempresa.codigo = _codemp;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cfg_menu_nivel1` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cfg_menu_nivel1`(
	in _Parametro varchar(5),
    in _tipo_menu varchar(1)
)
begin
	drop temporary table if exists a0 ;
	create temporary table a0
		select modulo
			from cfg_lista_formularios
			where cfg_lista_formularios.estado = 1 
				and cfg_lista_formularios.menu = _tipo_menu
				and formulario in (select u202 from tb_musuario_dpermiso where u201 = _parametro and u204 = 1) 
			group by modulo ;

	select *
		from cfg_menu_modulo
		where codigo in (select modulo from a0)
		order by orden ;		
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cfg_menu_nivel2` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cfg_menu_nivel2`(
	in _Parametro varchar(5),
    in _tipo_menu varchar(1)
)
begin
	drop temporary table if exists a0 ;
	create temporary table a0
		select 	grupo
			from cfg_lista_formularios
			where cfg_lista_formularios.estado = 1 
				and cfg_lista_formularios.menu = _tipo_menu
				and formulario in (select u202 from tb_musuario_dpermiso where u201 = _parametro and u204 = 1) 
			group by grupo ;

	select 	cfg_lista_formularios.modulo,
			cfg_menu_grupo.codigo,
			cfg_menu_grupo.nombre,
            cfg_menu_grupo.img_icons,
            cfg_menu_grupo.etiqueta
		from cfg_lista_formularios
			inner join a0 
				on cfg_lista_formularios.grupo = a0.grupo
			inner join cfg_menu_grupo 
				on cfg_lista_formularios.grupo = cfg_menu_grupo.codigo 
					and cfg_lista_formularios.menu = _tipo_menu
		group by cfg_lista_formularios.modulo,
			cfg_menu_grupo.codigo,
			cfg_menu_grupo.nombre
		order by cfg_lista_formularios.modulo, 
					cfg_menu_grupo.orden ;
                    -- cfg_lista_formularios.orden ;
	
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cfg_menu_nivel3` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cfg_menu_nivel3`(
	in _Parametro varchar(5),
    in _tipo_menu varchar(1)
)
begin
	select 	formulario, formulario_archivo, img_icons, titulo, etiqueta, modulo, grupo, orden
		from cfg_lista_formularios
		where cfg_lista_formularios.estado = 1 
			and cfg_lista_formularios.menu = _tipo_menu
			and formulario in (select u202 from tb_musuario_dpermiso where u201 = _parametro and u204 = 1)
		order by orden, titulo ;	
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cfg_msucursal_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cfg_msucursal_c`(
	in _codemp varchar(2),
    in _sucursal varchar(3)
)
begin
	-- ----------------------------------------------------
	-- Consulta datos de la empresa
	-- Versión 1.0
	-- Creado: 2020.03.17
	-- Actualizado: 2024.04.13, 2020.03.17
	-- Autor: 
	-- ----------------------------------------------------
    
	select 	cfg_msucursal.codemp, 
			cfg_mempresa.nombre as nempresa,
			cfg_msucursal.codigo, 
            cfg_msucursal.nombre, 
            cfg_msucursal.pais, 
            cfg_msucursal.estado_provincia, 
            cfg_msucursal.ciudad, 
            cfg_msucursal.codigo_postal, 
            cfg_msucursal.rif, 
            cfg_msucursal.email, 
            cfg_msucursal.telefonos, 
            cfg_msucursal.direccion, 
            cfg_msucursal.almacen_e, 
            coalesce(tb_a_malmacen_e.nombre, '') as nalmacen_e,
            cfg_msucursal.almacen_s, 
            coalesce(tb_a_malmacen_s.nombre, '') as nalmacen_s,
            cfg_msucursal.almacen_actualiza, 
            cfg_msucursal.estado
		from cfg_msucursal
			inner join cfg_mempresa 
				on cfg_msucursal.codemp = cfg_mempresa.codigo
            left join tb_a_malmacen as tb_a_malmacen_e 
				on cfg_msucursal.codemp = tb_a_malmacen_e.codemp 
					and cfg_msucursal.codigo = tb_a_malmacen_e.sucursal
					and cfg_msucursal.almacen_e = tb_a_malmacen_e.codigo
			left join tb_a_malmacen as tb_a_malmacen_s 
				on cfg_msucursal.codemp = tb_a_malmacen_s.codemp 
					and cfg_msucursal.codigo = tb_a_malmacen_s.sucursal
					and cfg_msucursal.almacen_s = tb_a_malmacen_e.codigo
		where cfg_msucursal.codemp = _codemp
			and cfg_msucursal.codigo = _sucursal ;
            
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cfg_ocollate_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cfg_ocollate_u`(
	in _database varchar(50)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		SP para actualizar la COLLATE de las tablas de una base de datos
		Versión 1.0
		Creado: 2025-03-20
		Actualizado: 2025-03-20
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
	set @database = trim(_database) ;
	set @SQL = concat('
		select
			CONCAT("alter table ", table_schema, ".", table_name, " convert to character set utf8mb4 collate utf8mb4_spanish_ci;") as query
		from
			information_schema.tables
		where
			table_schema = @database
		;
	');
    
	prepare stmt from @SQL;
	execute stmt;
	deallocate prepare stmt;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cfg_opciones_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cfg_opciones_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _codigo varchar(50),
    out _valor varchar(100)
)
begin	
	/* ----------------------------------------------------------------------------------------------------
		Consulta el valor de una opcion
		Versión 1.0
		Creado: 2025-03-15
		Actualizado: 2025-03-15
		Autor: 
	---------------------------------------------------------------------------------------------------- */
    set @valor = '' ;
    select 	coalesce(valor, '') into @valor
		from cfg_opciones
        where codemp = _codemp
			and sucursal = _sucursal
            and trim(opcion) = trim(coalesce(_codigo, '')) ;
	
    -- ----------------------------------------------------------------------------------------------------
	set _valor = @valor ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_cfg_timezone_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_cfg_timezone_c`(
	in _codemp Varchar(2), 
	in _sucursal Varchar(3), 
	in _status int, 
	in _clave Varchar(255), 
	in _parametro Varchar(255)
)
begin
	/* -- ------------------------------------------
		Consulta de la lista de timezone
		Creado 2025-02-02
		Actualizado 2025-02-02
		Autor: Custom Systems Solutions LLC
	-- ------------------------------------------- */
                
	drop temporary table if exists a1;
	create temporary table a1
		select	codigo,
				descripcion as nombre
			from cfg_timezones
			where codemp = _codemp
				and codigo <> trim(coalesce(_clave, ''))
				and trim(coalesce(descripcion, '')) <> ''
                 and _status = 1
		union
		select	codigo,
				descripcion as nombre
			from cfg_timezones
			where codemp = _codemp
				and codigo = trim(coalesce(_clave, '')) ;
		
	select	a1.codigo,
			a1.nombre
		from a1
		order by a1.nombre ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_clista_operadores` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_clista_operadores`(in _codigo varchar(2))
begin
	/* ----------------------------------------------------------------------------------------------------
		Busqueda de los operadores del formularios listas
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2025.01.24
		Autor: 
    ---------------------------------------------------------------------------------------------------- */
	drop temporary table if exists a0;
	create temporary table a0
		select 	operador,
				etiqueta
			from cfg_lista_operador
			where formulario = _codigo ;
	
	drop temporary table if exists a1;
	create temporary table a1
		select 	operador,
				etiqueta
			from cfg_moperadores
			where operador not in (select operador from a0) ;
	
	drop temporary table if exists a2 ;
	create temporary table a2
		select operador, etiqueta from a0
		union select operador, etiqueta from a1 ;
	
    -- ----------------------------------------------------------------------------------------------------
	select * 
		from a2 
		order by etiqueta ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_con_cBusqueda` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_con_cBusqueda`(
	In _codemp varchar(2), 
	In _sucursal varchar(3), 
    In _tabla varchar(100), 
    In _campos varchar(500), 
    In _ordenado varchar(50), 
    In _bCampos varchar(500), 
    In _operador varchar(5), 
    In _valor varchar(50), 
    In _pagina int, 
    In _regpp int, 
    In _adicional varchar(5000), 
    In _tipo_estado varchar(3)
)
BEGIN
-- ----------------------------------------------------
-- Consulta lista páginas
-- Versión 1.0
-- Creado: 12/11/2014
-- Actualizado: 11/11/2017
-- Autor: Venesisco, c.a.
-- ----------------------------------------------------
	set @iLimite = _regpp ;
	set @iPagina = _pagina ;
	set @cCampos = _campos ;
	set @iLimiteInicio = ((@iPagina - 1) * @iLimite) ;
	set @Fila = 0 ;

	set @cadena = ' where formulario <> 1';
	-- -------------------
	
	if trim(coalesce(_valor, '')) <> '' then
		if _operador='LIKE' then
			set @cadena = concat(@cadena, ' and ', trim(_bCampos), ' LIKE ', '''','%',trim(_valor), '%','''');
		else
			set @cadena = concat(@cadena, ' and ', trim(_bCampos), trim(_operador), '''',trim(_valor), '''');
		end if;
	end if ;
	
	if coalesce(_adicional, '') <> '' then
		if trim(coalesce(@cadena, '')) = '' then
			set @cadena = concat(@cadena, ' and ', trim(_adicional)) ;
		else
			set @cadena = concat(@cadena, ' and ', _adicional) ;
		end if;
	end if;

	drop temporary table if exists sentencia ;
	set @cSentencia = concat('CREATE TEMPORARY TABLE sentencia SELECT SQL_CALC_FOUND_ROWS *, (@fila:= @fila + 1) as RegFila',' FROM ', trim(_tabla), @cadena, ' ORDER BY ', rtrim(_ordenado), ' LIMIT ', @iLimiteInicio, ', ',  @iLimite);
	PREPARE sentencia from @cSentencia ;
	EXECUTE sentencia ;
	DEALLOCATE PREPARE sentencia ;

	set @iNumeroFila = FOUND_ROWS();
	set @iPaginaUltima =  round((@iNumeroFila/@iLimite), 0) ;
	if coalesce(@iPaginaUltima, 0) = 0 then
		set @iPaginaUltima = 1 ;
	end if ;

	select 	sentencia.*, 
			coalesce(cfg_mestado.nombre, '') as nestado,
			coalesce(cfg_menu_modulo.nombre, '') as nmodulo,
			coalesce(cfg_menu_grupo.nombre, '') as ngrupo,
			@iPagina as PagAct, 
			@iPaginaUltima as PagUltima, 
			@iNumeroFila as Filas 
		from sentencia
			left join cfg_menu_modulo on sentencia.modulo = cfg_menu_modulo.codigo
			left join cfg_menu_grupo on sentencia.grupo = cfg_menu_grupo.codigo
			left join cfg_mestado on sentencia.estado = cfg_mestado.codigo and cfg_mestado.tipo = rtrim(_tipo_estado) 
		order by RegFila ;

END ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_con_cBusqueda_campos_listas` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_con_cBusqueda_campos_listas`(
	In _codemp varchar(2), 
    In _sucursal varchar(3), 
    In _tabla varchar(100), 
    In _campos varchar(500), 
    In _ordenado varchar(50), 
    In _bCampos varchar(500), 
    In _operador varchar(5), 
    In _valor varchar(50), 
    In _pagina int, 
    In _regpp int, 
    In _adicional varchar(5000), 
    In _tipo_estado varchar(3)
)
BEGIN
-- ----------------------------------------------------
-- Consulta campos listas
-- Versión 1.0
-- Creado: 12/11/2014
-- Actualizado: 11/11/2017
-- Autor: Venesisco, c.a.
-- ----------------------------------------------------
	set @iLimite = _regpp ;
	set @iPagina = _pagina ;
	set @cCampos = _campos ;
	set @iLimiteInicio = ((@iPagina - 1) * @iLimite) ;
	set @Fila = 0 ;

	set @cadena = ' where formulario <> 1';
	-- -------------------
	
	if trim(coalesce(_valor, '')) <> '' then
		if _operador='LIKE' then
			set @cadena = concat(@cadena, ' and ', trim(_bCampos), ' LIKE ', '''','%',trim(_valor), '%','''');
		else
			set @cadena = concat(@cadena, ' and ', trim(_bCampos), trim(_operador), '''',trim(_valor), '''');
		end if;
	end if ;
	
	if coalesce(_adicional, '') <> '' then
		if trim(coalesce(@cadena, '')) = '' then
			set @cadena = concat(@cadena, ' and ', trim(_adicional)) ;
		else
			set @cadena = concat(@cadena, ' and ', _adicional) ;
		end if;
	end if;

	drop temporary table if exists sentencia ;
	set @cSentencia = concat('CREATE TEMPORARY TABLE sentencia SELECT SQL_CALC_FOUND_ROWS *, (@fila:= @fila + 1) as RegFila',' FROM ', trim(_tabla), @cadena, ' ORDER BY ', rtrim(_ordenado), ' LIMIT ', @iLimiteInicio, ', ',  @iLimite);
	PREPARE sentencia from @cSentencia ;
	EXECUTE sentencia ;
	DEALLOCATE PREPARE sentencia ;

	set @iNumeroFila = FOUND_ROWS();
	set @iPaginaUltima =  round((@iNumeroFila/@iLimite), 0) ;
	if coalesce(@iPaginaUltima, 0) = 0 then
		set @iPaginaUltima = 1 ;
	end if ;

	select 	sentencia.*, 
			coalesce(cfg_lista_formularios.titulo, '') as nformulario,
			@iPagina as PagAct, 
			@iPaginaUltima as PagUltima, 
			@iNumeroFila as Filas 
		from sentencia
		left join cfg_lista_formularios on sentencia.formulario = cfg_lista_formularios.formulario 
		order by RegFila ;
END ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_con_form_campos_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_con_form_campos_u`(
	In _codemp varchar(2), 
    In _sucursal varchar(3),
	In _item int(11),
	In _formulario int(11),
	In _orden int(11),
	In _campo varchar(200), 
	In _etiqueta varchar(200), 
	In _ancho smallint(4), 
	In _tipo_campo varchar(15), 
	In _maximo int(11), 
	In _readonly varchar(8), 
	In _requerido varchar(10), 
	In _autofocus varchar(10), 
	In _procedimiento varchar(100), 
	In _parametro varchar(100), 
	In _campo_cbusca varchar(50), 
	In _columna smallint(1), 
	In _valor varchar(255), 
	In _tab smallint(6), 
	In _id_datepicker varchar(15), 
	In _decimales int(1), 
	In _orden_lista int(11), 
	In _campo_lista varchar(200), 
	In _ancho_lista smallint(4), 
	In _link varchar(250), 
	In _image varchar(250), 
	In _parametro_lista varchar(50), 
	In _titulo varchar(50), 
	In _onchange varchar(255), 
	In _L varchar(1), 
	In _B varchar(1), 
	In _O varchar(1), 
	In _F varchar(1),
	In _R varchar(1),
	out _valor_retorno varchar(11)
	)
Begin
	-- ----------------------------------------------------
	-- Actualiza los datos de campos del constructor
	-- Versión 1.0
	-- Creado: 12/11/2014
	-- Actualizado: 11/11/2017
	-- Autor: Venesisco, c.a.
	-- ----------------------------------------------------
	Declare _actualiza_L Int(1);
	Declare _actualiza_B Int(1);
	Declare _actualiza_O Int(1);
	Declare _actualiza_F Int(1);
	Declare _actualiza_R Int(1);
	
	-- Esta guarandinga es para darle formato a las cantidades
	set _actualiza_L = convert(trim(replace(_L,',','')), decimal(0,0));
	set _actualiza_O = convert(trim(replace(_O,',','')), decimal(0,0));
	set _actualiza_B = convert(trim(replace(_B,',','')), decimal(0,0));
	set _actualiza_F = convert(trim(replace(_F,',','')), decimal(0,0));
	set _actualiza_R = convert(trim(replace(_R,',','')), decimal(0,0));

    If _formulario = 0 Then
	    Insert Into cfg_formulario_campos (formulario, orden, campo, etiqueta, ancho, tipo_campo, maximo, readonly, requerido, autofocus, procedimiento, parametro, campo_cbusca, columna, valor, tab, id_datepicker, decimales, orden_lista, campo_lista, ancho_lista, link, image, parametro_lista, titulo, conchange, L, B, O, F, R)
			values (_formulario, _orden, _campo, _etiqueta, _ancho, _tipo_campo, _maximo, _readonly, _requerido, _autofocus, _procedimiento, _parametro, _campo_cbusca, _columna, _valor, _tab, _id_datepicker, _decimales, _orden_lista, _campo_lista, _ancho_lista, _link, _image, _parametro_lista, _titulo, _onchange, _actualiza_L, _actualiza_B, _actualiza_O, _actualiza_F, _actualiza_R) ;

		select max(item) into _item
			from cfg_formulario_campos;

	Else
		update 	cfg_formulario_campos set
			formulario = _formulario, 
			orden = _orden, 
			campo = _campo, 
			etiqueta = _etiqueta, 
			ancho = _ancho, 
			tipo_campo = _tipo_campo, 
			maximo = _maximo, 
			readonly = _readonly, 
			requerido = _requerido, 
			autofocus = _autofocus, 
			procedimiento = _procedimiento, 
			parametro = _parametro, 
			campo_cbusca = _campo_cbusca, 
			columna = _columna, 
			valor = _valor, 
			tab = _tab, 
			id_datepicker = _id_datepicker, 
			decimales = _decimales, 
			orden_lista = _orden_lista, 
			campo_lista = _campo_lista, 
			ancho_lista = _ancho_lista, 
			link = _link, 
			image = _image, 
			parametro_lista = _parametro_lista, 
			titulo = _titulo, 
			onchange = _onchange,
			L = _actualiza_L, 
			B = _actualiza_B, 
			O = _actualiza_O, 
			F = _actualiza_F,
			R = _actualiza_R
			where item = _item ;
	End If;

	set _valor_retorno = _item;
End ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_con_form_codigo_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_con_form_codigo_c`(
	In _codemp Varchar(2), 
    In _sucursal Varchar(3), 
    In _status Varchar(1), 
    In _parametro Varchar(255), 
    In _tabla Varchar(255), 
    In _tipo Varchar(3)
)
BEGIN
-- ----------------------------------------------------
-- Consulta generica de los datos para los formularios
-- Versión 1.0
-- Creado: 04/08/2014
-- Actualizado: 11/11/2017
-- Autor: Venesisco, c.a.
-- ----------------------------------------------------
	set @cadena = concat(' where formulario = ', _parametro);

	drop temporary table if exists a1;	
	set @cSentencia = CONCAT('create temporary table a1 Select * From cfg_lista_formularios', @cadena);
	PREPARE sentencia from @cSentencia ;
	EXECUTE sentencia ;
	DEALLOCATE PREPARE sentencia ;

	select	a1.*,
			coalesce(cfg_menu_modulo.nombre, '') as nmodulo,
			coalesce(cfg_menu_grupo.nombre, '') as ngrupo
		from a1
			inner join cfg_menu_modulo on a1.modulo = cfg_menu_modulo.codigo
			inner join cfg_menu_grupo on a1.grupo = cfg_menu_grupo.codigo 
		order by a1.modulo, a1.grupo, a1.orden ;
END ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_con_form_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_con_form_u`(
	In _codemp Varchar(2), 
	In _sucursal Varchar(3), 
	In _formulario int(11),
	In _modulo varchar(3),
	In _grupo varchar(3), 
	In _orden smallint(6), 
	In _titulo varchar(200), 
	In _tabla varchar(200), 
	In _estado int(1), 
	In _filtra_sucursal int(1), 
	In _formulario_archivo varchar(100), 
	In _ini_orden varchar(50), 
	In _ini_bcampo varchar(50), 
	In _ini_operador varchar(50), 
	In _ini_valor varchar(200), 
	In _link_nuevo varchar(200), 
	In _link_previa varchar(200), 
	In _link_imprimir varchar(200), 
	In _link_buscar varchar(200), 
	In _procedimiento varchar(100), 
	In _campos varchar(200), 
	In _ordenado varchar(50), 
	In _bcampo varchar(50), 
	In _operador varchar(10), 
	In _valor varchar(200), 
	In _adicional varchar(200),
	In _boton_nuevo varchar(200), 
	In _boton_nuevo_etiqueta varchar(50), 
	In _boton_vistap varchar(200), 
	In _boton_vistap_etiqueta varchar(50), 
	In _boton_imprimir varchar(200), 
	In _boton_imprimir_etiqueta varchar(50), 
	In _tipo_estado varchar(3), 
	In _procedimiento_c varchar(100), 
	In _procedimiento_u varchar(100), 
	In _procedimiento_ea varchar(100), 
	In _procedimiento_v_elimina varchar(100), 
	In _formulario_validar varchar(100), 
	In _tabs smallint(6), 
	In _columnas smallint(1), 
	In _puede_eliminar int(1), 
	In _crear int(1), 
	In _editar int(1), 
	In _eliminar_anular int(1), 
	In _imprimir int(1), 
	In _edita_anulado int(1), 
	In _formulario_post varchar(255), 
	In _formulario_detalle varchar(255), 
	In _formulario_detalle_post varchar(255), 
	In _formulario_encabezado varchar(255), 
	In _formulario_carga varchar(255), 
	In _formulario_actualiza_array varchar(255), 
	In _detalle smallint(6), 
	In _detalle_u smallint(6), 
	In _detalle_e smallint(6), 
	In _procedimiento_detalle_c varchar(100), 
	In _procedimiento_detalle_param varchar(100), 
	In _procedimiento_detalle_u varchar(255), 
	In _detalle_alto smallint(6), 
	In _guarda_detalle varchar(255),
	out _valor_retorno varchar(11)
	)
Begin
	-- ----------------------------------------------------
	-- Actualiza los datos del constructor
	-- Versión 1.0
	-- Creado: 27/10/2014
	-- Actualizado: 11/11/2017
	-- Autor: Venesisco, c.a.
	-- ----------------------------------------------------
	
    If _formulario = 0 Then
	    Insert Into cfg_lista_formularios (modulo, grupo, orden, titulo, tabla, filtra_sucursal, formulario_archivo, ini_orden, ini_bcampo, ini_operador, ini_valor, link_nuevo, link_previa, link_imprimir, link_buscar, procedimiento, campos, ordenado, bcampo, operador, valor, adicional, boton_nuevo, boton_nuevo_etiqueta, boton_vistap, boton_vistap_etiqueta, boton_imprimir, boton_imprimir_etiqueta, tipo_estado, procedimiento_c, procedimiento_u, procedimiento_ea, procedimiento_v_elimina, formulario_validar, tabs, columnas, puede_eliminar, crear, editar, eliminar_anular, imprimir, edita_anulado, formulario_post, formulario_detalle, formulario_detalle_post, formulario_encabezado, formulario_carga, formulario_actualiza_array, detalle, detalle_u, detalle_e, procedimiento_detalle_c, procedimiento_detalle_param, procedimiento_detalle_u, detalle_alto, guarda_detalle)
			values (_modulo, _grupo, _orden, _titulo, _tabla, _filtra_sucursal, _formulario_archivo, _ini_orden, _ini_bcampo, _ini_operador, _ini_valor, _link_nuevo, _link_previa, _link_imprimir, _link_buscar, _procedimiento, _campos, _ordenado, _bcampo, _operador, _valor, _adicional, _boton_nuevo, _boton_nuevo_etiqueta, _boton_vistap, _boton_vistap_etiqueta, _boton_imprimir, _boton_imprimir_etiqueta, _tipo_estado, _procedimiento_c, _procedimiento_u, _procedimiento_ea, _procedimiento_v_elimina, _formulario_validar, _tabs, _columnas, _puede_eliminar, _crear, _editar, _eliminar_anular, _imprimir, _edita_anulado, _formulario_post, _formulario_detalle, _formulario_detalle_post, _formulario_encabezado, _formulario_carga, _formulario_actualiza_array, _detalle, _detalle_u, _detalle_e, _procedimiento_detalle_c, _procedimiento_detalle_param, _procedimiento_detalle_u, _detalle_alto, _guarda_detalle) ;

		select max(formulario) into _formulario
			from cfg_lista_formularios;

		/*select formulario into _formulario
			from cfg_lista_formularios
			where titulo = _titulo ;*/
	Else
		update 	cfg_lista_formularios set
				modulo = _modulo, 
				grupo = _grupo, 
				orden = _orden, 
				titulo = _titulo, 
				tabla = _tabla, 
				estado = _estado, 
				filtra_sucursal = _filtra_sucursal, 
				formulario_archivo = _formulario_archivo, 
				ini_orden = _ini_orden, 
				ini_bcampo = _ini_bcampo, 
				ini_operador = _ini_operador, 
				ini_valor = _ini_valor, 
				link_nuevo = _link_nuevo, 
				link_previa = _link_previa, 
				link_imprimir = _link_imprimir, 
				link_buscar = _link_buscar, 
				procedimiento = _procedimiento, 
				campos = _campos, 
				ordenado = _ordenado, 
				bcampo = _bcampo, 
				operador = _operador, 
				valor = _valor, 
				adicional = _adicional, 
				boton_nuevo = _boton_nuevo, 
				boton_nuevo_etiqueta = _boton_nuevo_etiqueta, 
				boton_vistap = _boton_vistap, 
				boton_vistap_etiqueta = _boton_vistap_etiqueta, 
				boton_imprimir = _boton_imprimir, 
				boton_imprimir_etiqueta = _boton_imprimir_etiqueta, 
				tipo_estado = _tipo_estado, 
				procedimiento_c = _procedimiento_c, 
				procedimiento_u = _procedimiento_u, 
				procedimiento_ea = _procedimiento_ea, 
				procedimiento_v_elimina = _procedimiento_v_elimina, 
				formulario_validar = _formulario_validar, 
				tabs = _tabs, 
				columnas = _columnas, 
				puede_eliminar = _puede_eliminar, 
				crear = _crear, 
				editar = _editar, 
				eliminar_anular =_eliminar_anular, 
				imprimir = _imprimir, 
				edita_anulado = _edita_anulado, 
				formulario_post = _formulario_post, 
				formulario_detalle = _formulario_detalle, 
				formulario_detalle_post = _formulario_detalle_post, 
				formulario_encabezado = _formulario_encabezado, 
				formulario_carga = _formulario_carga, 
				formulario_actualiza_array = _formulario_actualiza_array, 
				detalle = _detalle, 
				detalle_u = _detalle_u, 
				detalle_e = _detalle_e, 
				procedimiento_detalle_c = _procedimiento_detalle_c, 
				procedimiento_detalle_param = _procedimiento_detalle_param, 
				procedimiento_detalle_u = _procedimiento_detalle_u, 
				detalle_alto = _detalle_alto, 
				guarda_detalle = _guarda_detalle
			where formulario = _formulario ;
	End If;

	if (select coalesce(count(formulario), 0) from cfg_formulario_campos where formulario = _formulario) = 0 then
		call sp_con_lista_tablas_campos_u(_formulario) ;
	end if ;
	
	set _valor_retorno = _formulario;
End ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_con_general_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_con_general_c`(
	In _codemp Varchar(2), 
    In _sucursal Varchar(3), 
    In _status Varchar(1), 
    In _parametro Varchar(255), 
    In _tabla Varchar(255), 
    In _tipo Varchar(3)
)
Begin

-- ----------------------------------------------------
-- Consulta generica de los datos para los formularios
-- Versión 1.0
-- Creado: 06/11/2014
-- Actualizado: 11/11/2017
-- Autor: Venesisco, c.a.
-- ----------------------------------------------------

	set @cadena = concat(' where formulario = ', trim(_parametro));

	/*if trim(coalesce(_parametro, '')) <> '' then
		set @cadena = concat(@cadena, ' where formulario = "', trim(_parametro), '"');
	end if;*/

	drop temporary table if exists a1;	
	set @cSentencia = CONCAT('create temporary table a1 Select * From ', trim(_tabla), @cadena);
	PREPARE sentencia from @cSentencia ;
	EXECUTE sentencia ;
	DEALLOCATE PREPARE sentencia ;
	
	select	a1.*
		from a1 ;

End ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_con_general_item_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_con_general_item_c`(
	In _codemp Varchar(2), 
    In _sucursal Varchar(3), 
    In _status Varchar(1), 
    In _parametro Varchar(255), 
    In _tabla Varchar(255),
    In _tipo Varchar(3)
)
Begin

-- ----------------------------------------------------
-- Consulta generica de los datos para los formularios
-- Versión 1.0
-- Creado: 06/11/2014
-- Actualizado: 11/11/2017
-- Autor: Venesisco, c.a.
-- ----------------------------------------------------

	set @cadena = concat(' where item = ', trim(_parametro));

	/*if trim(coalesce(_parametro, '')) <> '' then
		set @cadena = concat(@cadena, ' where formulario = "', trim(_parametro), '"');
	end if;*/

	drop temporary table if exists a1;	
	set @cSentencia = CONCAT('create temporary table a1 Select * From ', trim(_tabla), @cadena);
	PREPARE sentencia from @cSentencia ;
	EXECUTE sentencia ;
	DEALLOCATE PREPARE sentencia ;
		
	select	a1.*
		from a1;
End ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_con_lista_campos_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_con_lista_campos_c`(
	In _codemp Varchar(2), 
    In _sucursal Varchar(3), 
    In _parametro Int(11)
)
BEGIN
-- ----------------------------------------------------
-- Consulta de campos para la lista
-- Versión 1.0
-- Creado: 06/11/2014
-- Actualizado: 11/11/2017
-- Autor: Venesisco, c.a.
-- ----------------------------------------------------

	set @tabla = '';
	set @formulario = 0 ;
	
	select formulario into @formulario
		from cfg_formulario_campos
		where item = _parametro ;
	
	select trim(tabla) into @tabla
		from cfg_lista_formularios
		where formulario = @formulario ;
	
 	select 	table_schema, 
 			table_name, 
 			column_name, 
 			ordinal_position, 
 			is_nullable, 
 			data_type, 
 			coalesce(CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION,  '') longitud, 
 			column_type
 		from information_schema.columns 
 		where table_schema = schema()
 			and table_name collate utf8_spanish_ci = trim(@tabla) 
 		order by ordinal_position ;
END ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_con_lista_procedimiento` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_con_lista_procedimiento`(
	In _codemp Varchar(2), 
    In _sucursal Varchar(3), 
    In _estado int(1), 
    In _parametro Varchar(255), 
    In _tipo varchar(3)
)
BEGIN
	-- ------------------------------------------
	-- Consulta los SP que exisnten en la DB
	-- V 1.0
	-- Creado: 28/10/2014
	-- Actualizado 11/11/2017
	-- Autor: Venesisco, c.a.
	-- -------------------------------------------
	
	drop temporary table if exists a0 ;
	create temporary table a0
		select 	ROUTINE_NAME as codigo,
				ROUTINE_NAME as nombre
			from information_schema.ROUTINES 
			where ROUTINE_SCHEMA = schema()
				and ROUTINE_TYPE = 'PROCEDURE'
				and ROUTINE_NAME collate utf8_spanish_ci = _parametro 
		union
		select 	ROUTINE_NAME as codigo,
				ROUTINE_NAME as nombre
			from information_schema.ROUTINES 
			where ROUTINE_SCHEMA = schema()
				and ROUTINE_TYPE = 'PROCEDURE'
				and ROUTINE_NAME collate utf8_spanish_ci <> _parametro 
				and _parametro = '' ;
	
	select *
		from a0
		order by codigo ;

END ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_con_lista_tablas` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_con_lista_tablas`(
	In _codemp Varchar(2), 
    In _sucursal Varchar(3), 
    In _estado int(1), 
    In _parametro Varchar(255), 
    In _tipo varchar(3)
)
BEGIN
	-- ------------------------------------------
	-- Consulta las tablas que exisnten en la DB
	-- V 1.0
	-- Creado: 28/10/2014
	-- Actualizado 11/11/2017
	-- Autor: Venesisco, c.a.
	-- -------------------------------------------
	
	drop temporary table if exists a0 ;
	create temporary table a0
		select 	TABLE_NAME as codigo,
				TABLE_NAME as nombre
			from information_schema.tables 
			where table_schema = schema()
				and TABLE_TYPE = 'BASE TABLE'
				and TABLE_NAME collate utf8_spanish_ci = _parametro 
		union
		select 	TABLE_NAME as codigo,
				TABLE_NAME as nombre
			from information_schema.tables 
			where TABLE_SCHEMA = schema() 
				and TABLE_TYPE = 'BASE TABLE'
				and TABLE_NAME collate utf8_spanish_ci <> _parametro 
				and _parametro = '' ;
	
	select *
		from a0
		order by codigo ;

END ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_con_lista_tablas_campos` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_con_lista_tablas_campos`(
	In _codemp Varchar(2), 
    In _sucursal Varchar(3), 
    In _estado int(1), 
    In _parametro Int(11), 
    In _tipo varchar(3)
)
BEGIN
	-- ------------------------------------------
	-- Consulta los campos de las tablas que exisnten en la DB
	-- V 1.0
	-- Creado: 28/10/2014
	-- Actualizado 11/11/2017
	-- Autor: Venesisco, c.a.
	-- -------------------------------------------
	set @tabla = '';
	
	select trim(tabla) into @tabla
		from cfg_lista_formularios
		where formulario = _parametro ;
	
 	select 	table_schema, 
 			table_name, 
 			column_name, 
 			ordinal_position, 
 			is_nullable, 
 			data_type, 
 			coalesce(CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION,  '') longitud, 
 			column_type
 		from information_schema.columns 
 		where table_schema = schema()
 			and table_name collate utf8_spanish_ci = trim(@tabla) 
 		order by ordinal_position ;

END ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_con_lista_tablas_campos_d_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_con_lista_tablas_campos_d_c`(
	In _codemp varchar(2), 
	In _sucursal varchar(3), 
	In _formulario Int(11)
)
BEGIN
	-- ------------------------------------------
	-- Consulta los campos de las tablas que exisnten en la DB
	-- V 1.0
	-- Creado: 28/10/2014
	-- Actualizado 11/11/2017
	-- Autor: Venesisco, c.a.
	-- -------------------------------------------
	set @tabla = '';
	set @formulario = _formulario ;
	
	select trim(tabla) into @tabla
		from cfg_lista_formularios
		where formulario = @formulario ;
	
	drop temporary table if exists a0 ;
	create temporary table a0
		select 	table_schema collate utf8_spanish_ci, 
 				table_name collate utf8_spanish_ci,
 				column_name collate utf8_spanish_ci as campo,
 				concat('LBL_', trim(upper(column_name collate utf8_spanish_ci))) as etiqueta,
 				ordinal_position as orden, 
 				is_nullable collate utf8_spanish_ci, 
 				data_type collate utf8_spanish_ci as tipo_dato, 
 				coalesce(CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION,  null) as ancho, 
 				NUMERIC_SCALE as decimales,
 				column_type collate utf8_spanish_ci as tipo_columna
			from information_schema.columns 
			where table_schema = schema()
				and table_name collate utf8_spanish_ci = trim(@tabla)
			order by ordinal_position ;
	
	drop temporary table if exists a1 ;
	create temporary table a1
		select 	item, 
				formulario, 
				orden, 
				campo, 
				etiqueta, 
				ancho, 
				tipo_campo, 
				maximo, 
				readonly, 
				requerido, 
				autofocus, 
				procedimiento, 
				parametro, 
				campo_cbusca, 
				columna, 
				valor, 
				tab, 
				id_datepicker, 
				decimales,
				1 as basico
			from cfg_formulario_campos
			where formulario = _formulario 
		union
		select 	0 as item, 
				_formulario,
				orden,
				campo,
				etiqueta,
				ancho,
				tipo_dato as tipo_campo,
				ancho as maximo,
				'' as readonly, 
				'' as requerido, 
				'' as autofocus, 
				'' as procedimiento, 
				'' as parametro, 
				'' as campo_cbusca,
				0 as columna,
				'' as valor,
				0 as tab,
				0 as id_datepicker, 
				decimales,
				0 as basico
			from a0
			where campo collate utf8_spanish_ci not in (select campo from cfg_formulario_campos where formulario = @formulario);
		
	select 	a1.*,
			a0.tipo_columna
		from a1
			left join a0 on a0.campo  collate utf8_spanish_ci = a1.campo
		order by a1.basico desc, orden ;
END ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_con_lista_tablas_campos_d_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_con_lista_tablas_campos_d_u`(
	In _item int(11),
	In _formulario int(11),
	In _orden int(11),
	In _campo varchar(200), 
	In _etiqueta varchar(200), 
	In _ancho smallint(4), 
	In _tipo_campo varchar(15), 
	In _maximo int(11), 
	In _readonly varchar(8), 
	In _requerido varchar(10), 
	In _autofocus varchar(10), 
	In _procedimiento varchar(100), 
	In _parametro varchar(100), 
	In _campo_cbusca varchar(50), 
	In _columna smallint(1), 
	In _valor varchar(255), 
	In _tab smallint(6), 
	In _id_datepicker varchar(15), 
	In _decimales int(1)
)
BEGIN
	-- ------------------------------------------
	-- Guarda los campos de las tablas que exisnten en la DB
	-- V 1.0
	-- Creado: 28/10/2014
	-- Actualizado 11/11/2017
	-- Autor: Venesisco, c.a.
	-- -------------------------------------------
	if _item = 0 then
		insert into cfg_formulario_campos (formulario, orden, campo, etiqueta, ancho, tipo_campo, maximo, readonly, requerido, autofocus, procedimiento, parametro, campo_cbusca, columna, valor, tab, id_datepicker, decimales)
			select _formulario, _orden, _campo, _etiqueta, _ancho, _tipo_campo, _maximo, _readonly, _requerido, _autofocus, _procedimiento, _parametro, _campo_cbusca, _columna, _valor, _tab, _id_datepicker, _decimales ;
	else
		update cfg_formulario_campos set 
				formulario = _formulario, 
				orden = _orden, 
				campo = _campo, 
				etiqueta = _etiqueta, 
				ancho = _ancho, 
				tipo_campo = _tipo_campo, 
				maximo = _maximo, 
				readonly = _readonly, 
				requerido = _requerido, 
				autofocus = _autofocus, 
				procedimiento = _procedimiento, 
				parametro = _parametro, 
				campo_cbusca = _campo_cbusca, 
				columna = _columna, 
				valor = _valor, 
				tab = _tab, 
				id_datepicker = _id_datepicker, 
				decimales = _decimales
			where item = _item ;
	end if ;
END ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_con_lista_tablas_campos_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_con_lista_tablas_campos_u`(
	In _formulario int(11)
)
BEGIN
-- ----------------------------------------------------
-- Actualiza los datos de los campos del formulario
-- Versión 1.0
-- Creado: 07/11/2014
-- Actualizado: 11/11/2017
-- Autor: Venesisco, c.a.
-- ----------------------------------------------------

	set @tabla = '' ;
	set @formulario = _formulario ;
	
	select trim(tabla) into @tabla
		from cfg_lista_formularios
		where formulario = @formulario ;
	
	drop temporary table if exists a0 ;
	create temporary table a0
		select 	table_schema, 
				table_name, 
				column_name, 
				ordinal_position, 
				is_nullable, 
				data_type, 
				coalesce(CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION,  '') longitud, 
				numeric_scale,
				column_type,
				case  when is_nullable = 'NO' then 'required' else null end requerido
			from information_schema.columns 
			where table_schema = schema()
				and table_name collate utf8_spanish_ci = trim(@tabla) 
				and column_name collate utf8_spanish_ci not in (select campo from cfg_formulario_campos where formulario = @formulario) ;
	
	/* Inserta los nuevos campos de la tabla */
    insert into cfg_formulario_campos (formulario, orden, campo, etiqueta, ancho, tipo_campo, maximo, requerido, columna, decimales, F)
	select @formulario, 
			ordinal_position, 
			column_name, 
			concat('LBL_', trim(upper(column_name))), 
			longitud, 
			column_type,
			longitud,
			requerido, 
			1, 
			numeric_scale,
            1
		from a0
		order by ordinal_position ;
        /*substring(column_type, 1, 1),*/
        
	/*Inserta los botones ver y editar de la lista*/
    insert into cfg_formulario_campos (formulario, tipo_campo, orden_lista, campo_lista, ancho_lista, link, image, parametro_lista, titulo)
		values (_formulario, 'I', 100, 'codigo', 24, '../modulos/ad_sis_formulario_u_std.php?modo=0&tipo=1&_clave=', '../imagenes/find.png', 'codigo', 'Ver registro');
        
    insert into cfg_formulario_campos (formulario, tipo_campo, orden_lista, campo_lista, ancho_lista, link, image, parametro_lista, titulo)
		values (_formulario, 'I', 101, 'codigo', 24, '../modulos/ad_sis_formulario_u_std.php?modo=2&tipo=1&_clave=', '../imagenes/edit.png', 'codigo', 'Editar registro');
    
    
    /*Actualiza los tipos de campo*/
	update cfg_formulario_campos
		set tipo_campo='C'
    where formulario=_formulario
		and substring(tipo_campo,1,7)='varchar';
        
	update cfg_formulario_campos
		set tipo_campo='N'
    where formulario=_formulario
		and (substring(tipo_campo,1,3)='int' 
			or substring(tipo_campo,1,8)='smallint'
            or substring(tipo_campo,1,7)='decimal'
            or substring(tipo_campo,1,6)='double');

	update cfg_formulario_campos
		set tipo_campo='D'
    where formulario=_formulario
		and (substring(tipo_campo,1,4)='date'
			or substring(tipo_campo,1,8)='datetime');

	update cfg_formulario_campos
		set tipo_campo='list'
    where formulario=_formulario
		and campo='estado';        
END ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_dashboard_c_opurchase_orders_backorder` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_dashboard_c_opurchase_orders_backorder`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
    in _formulario int,
    in _usuario varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Dashboard: Consulta de las ordenes de ventas entregadas, según la fecha fe actualizaciún y el estatus
		Versión 1.0
		Creado: 2025-09-05
		Actualizado: 2025-09-05
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
	set @codemp = _codemp ;
    set @sucursal = _sucursal ;
    set @usuario = coalesce(_usuario) ;
    
	select curdate() - interval 1 month, curdate() into @fecha_d, @fecha_h ;
    select	tabla, campos, ordenado, bcampo, operador, valor
			into @tabla, @campos, @ordenado, @bcampo, @operador, @valor
		from cfg_lista_formularios
        where formulario = _formulario ;
        
	select	coalesce(u218, '') into @cliente
		from tb_musuario
        where u201 = @usuario ;
    
    drop temporary table if exists c_opurchase_orders ;
    create temporary table c_opurchase_orders
		select	codemp, sucursal, fecha, numero, cliente
			from tb_c_opurchase_orders
			where codemp = @codemp
				and sucursal = @sucursal
				-- and fecha between @fecha_d and @fecha_h
				and case when @cliente = '' 
							then cliente = cliente
							else cliente = @cliente
						end
				and estado = 1 ;
                
    select	tb_c_opurchase_dproducts.producto as codigo, 
			coalesce(tb_a_mproducts.nombre, '') as nproducto,
            c_opurchase_orders.fecha,
			tb_c_opurchase_dproducts.cantidad_backorder
		from tb_c_opurchase_dproducts
			inner join c_opurchase_orders
				on tb_c_opurchase_dproducts.codemp = c_opurchase_orders.codemp
					and tb_c_opurchase_dproducts.sucursal = c_opurchase_orders.sucursal
					and tb_c_opurchase_dproducts.numero = c_opurchase_orders.numero
                    and tb_c_opurchase_dproducts.cantidad_backorder > 0
			left join tb_a_mproducts
				on tb_c_opurchase_dproducts.codemp = tb_a_mproducts.codemp
					and tb_c_opurchase_dproducts.sucursal = tb_a_mproducts.sucursal
					and tb_c_opurchase_dproducts.producto = tb_a_mproducts.codigo
		order by coalesce(tb_a_mproducts.nombre, ''), tb_c_opurchase_dproducts.producto ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_dashboard_f_salesorders` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_dashboard_f_salesorders`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
    in _formulario int,
    in _usuario varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Dashboard: Consulta de las ordenes de ventas entregadas, según la fecha fe actualizaciún y el estatus
		Versión 1.0
		Creado: 2025-09-05
		Actualizado: 2025-09-05
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
	set @codemp = _codemp ;
    set @sucursal = _sucursal ;
    set @usuario = coalesce(_usuario) ;
    
	select curdate() - interval 1 month, curdate() into @fecha_d, @fecha_h ;
    select	tabla, campos, ordenado, bcampo, operador, valor
			into @tabla, @campos, @ordenado, @bcampo, @operador, @valor
		from cfg_lista_formularios
        where formulario = _formulario ;
        
	select	coalesce(u218, '') into @cliente
		from tb_musuario
        where u201 = @usuario ;
    
    select	*
		from tb_f_osales_orders
		where codemp = @codemp
			and sucursal = @sucursal
            and fecha_u between @fecha_d and @fecha_h
            and case when @cliente = '' 
						then cliente = cliente
                        else cliente = @cliente
					end
			and estado = 3
		order by numero ;
	
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_dashboard_f_salesorders_abiertas_vs_cerradas` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_dashboard_f_salesorders_abiertas_vs_cerradas`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
    in _formulario int,
    in _usuario varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Dashboard: Consulta de las ordenes de ventas entregadas, según la fecha fe actualizaciún y el estatus
		Versión 1.0
		Creado: 2025-09-05
		Actualizado: 2025-09-05
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
	set @codemp = _codemp ;
    set @sucursal = _sucursal ;
    set @usuario = coalesce(_usuario) ;
    
	select curdate() - interval 1 month, curdate() into @fecha_d, @fecha_h ;
    select	tabla, campos, ordenado, bcampo, operador, valor
			into @tabla, @campos, @ordenado, @bcampo, @operador, @valor
		from cfg_lista_formularios
        where formulario = _formulario ;
        
	select	coalesce(u218, '') into @cliente
		from tb_musuario
        where u201 = @usuario ;
    
    drop temporary table if exists f_salesorders ;
    create temporary table f_salesorders
    select	codemp, sucursal, numero, estado
		from tb_f_osales_orders
		where codemp = @codemp
			and sucursal = @sucursal
            and fecha between @fecha_d and @fecha_h
            and case when @cliente = '' 
						then cliente = cliente
                        else cliente = @cliente
					end ;
                    
    select count(numero) into @abiertas from f_salesorders where estado = 1 ;
    select count(numero) into @cerradas from f_salesorders where estado = 3 ;
        
    select	@abiertas as abiertas, @cerradas as cerradas ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_dashboard_f_salesorders_activa` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_dashboard_f_salesorders_activa`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
    in _formulario int,
    in _usuario varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Dashboard: Consulta de las ordenes de ventas entregadas, según la fecha fe actualizaciún y el estatus
		Versión 1.0
		Creado: 2025-09-05
		Actualizado: 2025-09-05
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
	set @codemp = _codemp ;
    set @sucursal = _sucursal ;
    set @usuario = coalesce(_usuario) ;
    
	select curdate() - interval 1 month, curdate() into @fecha_d, @fecha_h ;
    select	tabla, campos, ordenado, bcampo, operador, valor
			into @tabla, @campos, @ordenado, @bcampo, @operador, @valor
		from cfg_lista_formularios
        where formulario = _formulario ;
        
	select	coalesce(u218, '') into @cliente
		from tb_musuario
        where u201 = @usuario ;
    -- set @campo = 'numero, fecha, cliente'; 
    
    -- CALL sp_cbusqueda_f_sales_orders(@codemp, @sucursal, @tabla, 'numero, fecha, cliente', 'numero', 'numero', 'LIKE', '', '1', '25', '', 'GEN', 1, @fecha_d, @fecha_h) ;
    -- CALL sp_cbusqueda_f_sales_orders('01','001','tb_f_osales_orders','*', 'numero', 'numero', 'LIKE', '', '1', '25', '', 'GEN','1', '08/27/2025', '09/05/2025') ;
    
    
    select	codemp, sucursal, numero, vendedor, envio_nombre, referencia, numero_item, total_precio
		from tb_f_osales_orders
		where codemp = @codemp
			and sucursal = @sucursal
            and fecha between @fecha_d and @fecha_h
            and case when @cliente = '' 
						then cliente = cliente
                        else cliente = @cliente
					end
			and estado = 1
		order by numero ;
	
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_dashboard_f_salesorders_cerrada` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_dashboard_f_salesorders_cerrada`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
    in _formulario int,
    in _usuario varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Dashboard: Consulta de las ordenes de ventas entregadas, según la fecha fe actualizaciún y el estatus
		Versión 1.0
		Creado: 2025-09-05
		Actualizado: 2025-09-05
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
	set @codemp = _codemp ;
    set @sucursal = _sucursal ;
    set @usuario = coalesce(_usuario) ;
    
	select curdate() - interval 1 month, curdate() into @fecha_d, @fecha_h ;
    select	tabla, campos, ordenado, bcampo, operador, valor
			into @tabla, @campos, @ordenado, @bcampo, @operador, @valor
		from cfg_lista_formularios
        where formulario = _formulario ;
        
	select	coalesce(u218, '') into @cliente
		from tb_musuario
        where u201 = @usuario ;
    
    select	codemp, sucursal, numero, vendedor, envio_nombre, referencia, numero_item, total_precio
		from tb_f_osales_orders
		where codemp = @codemp
			and sucursal = @sucursal
            and fecha_u between @fecha_d and @fecha_h
            and case when @cliente = '' 
						then cliente = cliente
                        else cliente = @cliente
					end
			and estado = 3
		order by numero ;
	
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_dashboard_f_salesorders_dentr_vs_pend` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_dashboard_f_salesorders_dentr_vs_pend`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
    in _formulario int,
    in _usuario varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Dashboard: Consulta de las ordenes de ventas entregadas, según la fecha fe actualizaciún y el estatus
		Versión 1.0
		Creado: 2025-09-05
		Actualizado: 2025-09-05
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
	set @codemp = _codemp ;
    set @sucursal = _sucursal ;
    set @usuario = coalesce(_usuario) ;
    
	select curdate() - interval 1 month, curdate() into @fecha_d, @fecha_h ;
    select	tabla, campos, ordenado, bcampo, operador, valor
			into @tabla, @campos, @ordenado, @bcampo, @operador, @valor
		from cfg_lista_formularios
        where formulario = _formulario ;
        
	select	coalesce(u218, '') into @cliente
		from tb_musuario
        where u201 = @usuario ;
    -- set @campo = 'numero, fecha, cliente'; 
    
    -- CALL sp_cbusqueda_f_sales_orders(@codemp, @sucursal, @tabla, 'numero, fecha, cliente', 'numero', 'numero', 'LIKE', '', '1', '25', '', 'GEN', 1, @fecha_d, @fecha_h) ;
    -- CALL sp_cbusqueda_f_sales_orders('01','001','tb_f_osales_orders','*', 'numero', 'numero', 'LIKE', '', '1', '25', '', 'GEN','1', '08/27/2025', '09/05/2025') ;
    
    drop temporary table if exists f_salesorders ;
    create temporary table f_salesorders
    select	codemp, sucursal, numero
		from tb_f_osales_orders
		where codemp = @codemp
			and sucursal = @sucursal
            -- and fecha between @fecha_d and @fecha_h
            and case when @cliente = '' 
						then cliente = cliente
                        else cliente = @cliente
					end
			and estado = 1 ;
	
    
    drop temporary table if exists f_salesorders_dso ;
    create temporary table f_salesorders_dso
		select 	sum(coalesce(tb_f_osales_dproducts.cantidad_ord, 0)) as cantidad_ordenada, 
                sum(coalesce(tb_f_osales_dproducts.cantidad_env, 0)) as cantidad_enviada, 
                sum(coalesce(tb_f_osales_dproducts.cantidad_fac, 0)) as cantidad_facturada, 
                sum(coalesce(tb_f_osales_dproducts.cantidad_res, 0)) as cantidad_reservada
			from tb_f_osales_dproducts
				inner join f_salesorders
					on tb_f_osales_dproducts.codemp =f_salesorders.codemp
						and tb_f_osales_dproducts.sucursal =f_salesorders.sucursal
                        and tb_f_osales_dproducts.numero =f_salesorders.numero ;
	
    
    select	f_salesorders_dso.*
		from f_salesorders_dso ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_dashboard_neto_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_dashboard_neto_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Reporte de Timesheet de clientes, role y tarifa
		Versión 1.0
		Creado: 2025-08-12
		Actualizado: 2025-08-12
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
	set @codemp = _codemp ;
    set @sucursal = _sucursal ;
	set @personal_a = 0 ;
    set @personal_p = 0 ;
    
     select curdate() - interval 37 day, curdate() - interval 7 day, curdate() - interval 38 day, curdate() - interval 68 day into @fecha_da, @fecha_ha, @fecha_hp, @fecha_dp ;
	
    -- ----------------------------------------------------------------------------------------------------
    drop temporary table if exists c_timesheet ;
    create temporary table c_timesheet
		select	codemp, sucursal, numero, fecha_d, fecha_h
			from tb_f_otimesheet
            where codemp = @codemp
				and sucursal = @sucursal
                and fecha_d between @fecha_da and @fecha_ha
                and estado between 4 and 5
		union
        select	codemp, sucursal, numero, fecha_d, fecha_h
			from tb_f_otimesheet
            where codemp = @codemp
				and sucursal = @sucursal
                and fecha_d between @fecha_dp and @fecha_hp
                and estado between 4 and 5; 
    
    -- ----------------------------------------------------------------------------------------------------
	drop temporary table if exists c_timesheet_dpersonal_role ;
    create temporary table c_timesheet_dpersonal_role
		select	c_timesheet.codemp, 
				c_timesheet.sucursal,
                tb_f_otimesheet_dpersonal_role.personal
			from tb_f_otimesheet_dpersonal_role
				inner join c_timesheet
					on c_timesheet.codemp = tb_f_otimesheet_dpersonal_role.codemp
						and c_timesheet.sucursal = tb_f_otimesheet_dpersonal_role.sucursal
                        and c_timesheet.numero = tb_f_otimesheet_dpersonal_role.numero
			where c_timesheet.fecha_d between @fecha_da and @fecha_ha 
				and tb_f_otimesheet_dpersonal_role.horas > 0 
            group by c_timesheet.codemp, c_timesheet.sucursal, tb_f_otimesheet_dpersonal_role.personal ;
	
    select count(personal) into @personal_a
		from c_timesheet_dpersonal_role ;
        
	-- ----------------------------------------------------------------------------------------------------
	drop temporary table if exists c_timesheet_dpersonal_role ;
    create temporary table c_timesheet_dpersonal_role
		select	c_timesheet.codemp, 
				c_timesheet.sucursal,
                tb_f_otimesheet_dpersonal_role.personal
			from tb_f_otimesheet_dpersonal_role
				inner join c_timesheet
					on c_timesheet.codemp = tb_f_otimesheet_dpersonal_role.codemp
						and c_timesheet.sucursal = tb_f_otimesheet_dpersonal_role.sucursal
                        and c_timesheet.numero = tb_f_otimesheet_dpersonal_role.numero
			where c_timesheet.fecha_d between @fecha_dp and @fecha_hp
				and tb_f_otimesheet_dpersonal_role.horas > 0 
            group by c_timesheet.codemp, c_timesheet.sucursal, tb_f_otimesheet_dpersonal_role.personal ;
	
    select count(personal) into @personal_p
		from c_timesheet_dpersonal_role ;
        
    -- ----------------------------------------------------------------------------------------------------
	drop temporary table if exists c_timesheet_drole ;
    create temporary table c_timesheet_drole
		select	c_timesheet.codemp, 
				c_timesheet.sucursal,
                (case when fecha_d between @fecha_da and @fecha_ha then tb_f_otimesheet_dpersonal_role.horas else 0 end) as horas_a, /*
                (case when fecha_d between @fecha_da and @fecha_ha then tb_f_otimesheet_dpersonal_role.horas_rg else 0 end) as horas_rg_a, 
                (case when fecha_d between @fecha_da and @fecha_ha then tb_f_otimesheet_dpersonal_role.horas_ot else 0 end) as horas_ot_a, 
                (case when fecha_d between @fecha_da and @fecha_ha then tb_f_otimesheet_dpersonal_role.horas_fd else 0 end) as horas_fd_a, 
                (case when fecha_d between @fecha_da and @fecha_ha then tb_f_otimesheet_dpersonal_role.monto_staff_rg else 0 end) as monto_staff_rg_a, 
                (case when fecha_d between @fecha_da and @fecha_ha then tb_f_otimesheet_dpersonal_role.monto_staff_ot else 0 end) as monto_staff_ot_a, 
                (case when fecha_d between @fecha_da and @fecha_ha then tb_f_otimesheet_dpersonal_role.monto_staff_fd else 0 end) as monto_staff_fd_a, */
                (case when fecha_d between @fecha_da and @fecha_ha then tb_f_otimesheet_dpersonal_role.total_staff else 0 end) as total_staff_a, /*
                (case when fecha_d between @fecha_da and @fecha_ha then tb_f_otimesheet_dpersonal_role.monto_margin_rg else 0 end) as monto_margin_rg_a, 
                (case when fecha_d between @fecha_da and @fecha_ha then tb_f_otimesheet_dpersonal_role.monto_margin_ot else 0 end) as monto_margin_ot_a, 
                (case when fecha_d between @fecha_da and @fecha_ha then tb_f_otimesheet_dpersonal_role.monto_margin_fd else 0 end) as monto_margin_fd_a,*/
                (case when fecha_d between @fecha_da and @fecha_ha then tb_f_otimesheet_dpersonal_role.total_cliente else 0 end) as total_customer_a,
                
                (case when fecha_d between @fecha_dp and @fecha_hp then tb_f_otimesheet_dpersonal_role.horas else 0 end) as horas_p, /*
                (case when fecha_d between @fecha_dp and @fecha_hp then tb_f_otimesheet_dpersonal_role.horas_rg else 0 end) as horas_rg_p, 
                (case when fecha_d between @fecha_dp and @fecha_hp then tb_f_otimesheet_dpersonal_role.horas_ot else 0 end) as horas_ot_p, 
                (case when fecha_d between @fecha_dp and @fecha_hp then tb_f_otimesheet_dpersonal_role.horas_fd else 0 end) as horas_fd_p, 
                (case when fecha_d between @fecha_dp and @fecha_hp then tb_f_otimesheet_dpersonal_role.monto_staff_rg else 0 end) as monto_staff_rg_p, 
                (case when fecha_d between @fecha_dp and @fecha_hp then tb_f_otimesheet_dpersonal_role.monto_staff_ot else 0 end) as monto_staff_ot_p, 
                (case when fecha_d between @fecha_dp and @fecha_hp then tb_f_otimesheet_dpersonal_role.monto_staff_fd else 0 end) as monto_staff_fd_p, */
                (case when fecha_d between @fecha_dp and @fecha_hp then tb_f_otimesheet_dpersonal_role.total_staff else 0 end) as total_staff_p, /*
                (case when fecha_d between @fecha_dp and @fecha_hp then tb_f_otimesheet_dpersonal_role.monto_margin_rg else 0 end) as monto_margin_rg_p, 
                (case when fecha_d between @fecha_dp and @fecha_hp then tb_f_otimesheet_dpersonal_role.monto_margin_ot else 0 end) as monto_margin_ot_p, 
                (case when fecha_d between @fecha_dp and @fecha_hp then tb_f_otimesheet_dpersonal_role.monto_margin_fd else 0 end) as monto_margin_fd_p,*/
                (case when fecha_d between @fecha_dp and @fecha_hp then tb_f_otimesheet_dpersonal_role.total_cliente else 0 end) as total_customer_p
			from tb_f_otimesheet_dpersonal_role
				inner join c_timesheet
					on c_timesheet.codemp = tb_f_otimesheet_dpersonal_role.codemp
						and c_timesheet.sucursal = tb_f_otimesheet_dpersonal_role.sucursal
                        and c_timesheet.numero = tb_f_otimesheet_dpersonal_role.numero
			where tb_f_otimesheet_dpersonal_role.horas > 0 ;
	
    -- ----------------------------------------------------------------------------------------------------
	drop temporary table if exists t_timesheet_drole ;
	create temporary table t_timesheet_drole
		select	codemp, 
				sucursal,
                sum(horas_a) as horas_a, /*
                sum(horas_rg_a) as horas_rg_a, 
                sum(horas_ot_a) as horas_ot_a, 
                sum(horas_fd_a) as horas_fd_a, 
                sum(monto_staff_rg_a) as monto_staff_rg_a, 
                sum(monto_staff_ot_a) as monto_staff_ot_a, 
                sum(monto_staff_fd_a) as monto_staff_fd_a, */
                sum(total_staff_a) as total_staff_a, /*
                sum(monto_margin_rg_a) as monto_margin_rg_a, 
                sum(monto_margin_ot_a) as monto_margin_ot_a, 
                sum(monto_margin_fd_a) as monto_margin_fd_a,*/
                sum(total_customer_a) as total_customer_a,
                
                sum(horas_p) as horas_p, /*
                sum(horas_rg_p) as horas_rg_p, 
                sum(horas_ot_p) as horas_ot_p, 
                sum(horas_fd_p) as horas_fd_p, 
                sum(monto_staff_rg_p) as monto_staff_rg_p, 
                sum(monto_staff_ot_p) as monto_staff_ot_p, 
                sum(monto_staff_fd_p) as monto_staff_fd_p, */
                sum(total_staff_p) as total_staff_p, /*
                sum(monto_margin_rg_p) as monto_margin_rg_p, 
                sum(monto_margin_ot_p) as monto_margin_ot_p, 
                sum(monto_margin_fd_p) as monto_margin_fd_p,*/
                sum(total_customer_p) as total_customer_p
			from c_timesheet_drole
            group by codemp, sucursal ;
            
	-- ----------------------------------------------------------------------------------------------------
    select	concat(@fecha_da, ' - ',  @fecha_ha) as fecha_a,
			@personal_a as personal_a,
			-- t_timesheet_drole.horas_rg_a, t_timesheet_drole.horas_ot_a, t_timesheet_drole.horas_fd_a, 
            t_timesheet_drole.horas_a, 
			-- t_timesheet_drole.monto_staff_rg_a, t_timesheet_drole.monto_staff_ot_a, t_timesheet_drole.monto_staff_fd_a, 
            t_timesheet_drole.total_staff_a, 
			-- t_timesheet_drole.monto_margin_rg_a, t_timesheet_drole.monto_margin_ot_a, t_timesheet_drole.monto_margin_fd_a, 
            t_timesheet_drole.total_customer_a,
            
            concat(@fecha_dp, ' - ', @fecha_hp) as fecha_p,
            @personal_p as personal_p,
			-- t_timesheet_drole.horas_rg_p, t_timesheet_drole.horas_ot_p, t_timesheet_drole.horas_fd_p, 
            t_timesheet_drole.horas_p, 
			-- t_timesheet_drole.monto_staff_rg_p, t_timesheet_drole.monto_staff_ot_p, t_timesheet_drole.monto_staff_fd_p, 
            t_timesheet_drole.total_staff_p, 
			-- t_timesheet_drole.monto_margin_rg_p, t_timesheet_drole.monto_margin_ot_p, t_timesheet_drole.monto_margin_fd_p, 
            t_timesheet_drole.total_customer_p,
            
            round(t_timesheet_drole.total_customer_a - t_timesheet_drole.total_staff_a, 2) as total_neto_a,
            round(t_timesheet_drole.total_customer_p - t_timesheet_drole.total_staff_p, 2) as total_neto_p,
            
            round(@personal_a - @personal_p, 0) as diferencia_staff,
            round(t_timesheet_drole.horas_a - t_timesheet_drole.horas_p, 2) as diferencia_horas,
            round((t_timesheet_drole.total_staff_a - t_timesheet_drole.total_staff_p) * 100, 2) as diferencia_staff_total,
            round((t_timesheet_drole.total_customer_a - t_timesheet_drole.total_customer_p) * 100, 2) as diferencia_customer_total
		from t_timesheet_drole  ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_a_mproducts_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_a_mproducts_u`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
	in _usuario varchar(10),
	in _codigo varchar(100),
    in _nombre varchar(120),
    in _disponible decimal(10,2), 
    in _enmano decimal(10,2), 
    in _reservado decimal(10,2), 
    in _condicion varchar(15), 
    in _receiveDate varchar(10), 
    in _expirationDate varchar(10),
    in _serial varchar(50),
    in _unitCost decimal(10,2),
    in _unitPrice decimal(10,2),
    in _orden_compra varchar(15)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Actualiza los datos del maestro de products
		Versión 1.0
		Creado: 2025-08-31
		Actualizado: 2025-09-10
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
    set @tipo = 1 ;
    set @receiveDate = substring(Trim(_receiveDate),1, 10) ;
    set @expirationDate = substring(Trim(_expirationDate),1, 10) ;
    
    select count(codigo) into @existe
		from tb_a_mproducts
        where codemp = _codemp
			and sucursal = _sucursal
			and trim(codigo) = _codigo ;
    
	if (@existe = 0) then
		insert into tb_a_mproducts (codemp, sucursal, codigo, nombre, stock_disponible, stock_reserv, stock_enmano, nuevo_usado, fecha_rec, fecha_vence, serial, precio_compra, precio_venta, orden_compra_numero, estado, fecha_sync, tipo_sync)
			values (_codemp, _sucursal, _codigo, _nombre, _disponible, _reservado, _enmano, _condicion, @receiveDate, @expirationDate, _serial, _unitCost, _unitPrice, _orden_compra, 1, curdate(), 1) ;
	else
		update tb_a_mproducts
			set
				nombre = _nombre, 
                stock_disponible = _disponible, 
                stock_reserv = _reservado, 
                stock_enmano = _enmano, 
                nuevo_usado = _condicion, 
                fecha_rec = @receiveDate, 
                fecha_vence = @expirationDate, 
                serial = _serial, 
                precio_compra = _unitCost, 
                precio_venta = _unitPrice, 
                orden_compra_numero = _orden_compra, 
                fecha_sync = curdate(), 
                tipo_sync = 2
			where codemp = _codemp
				and sucursal = _sucursal
				and trim(codigo) = _codigo ;	
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_a_mproduct_dpurchase_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_a_mproduct_dpurchase_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
    in _modo smallint(1),
	in _producto varchar(100),
    in _usuario varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Consulta generica de los datos para los formularios
		Versión 1.0
		Creado: 2025-09-04
		Actualizado: 2025-09-04
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    drop temporary table if exists a_mproduct_dpurchase ;
    create temporary table a_mproduct_dpurchase 
		select 	*
			from tb_c_opurchase_dproducts
            where codemp = _codemp
				and sucursal = _sucursal
                and producto = _producto ;
	
	select	a_mproduct_dpurchase.*,
            coalesce(tb_c_mvendors.nombre, '') as nvendor,
			coalesce(tb_f_mcustomers.nombre, '') as ncustomer,
			round(a_mproduct_dpurchase.precio_unitario * a_mproduct_dpurchase.cantidad_backorder, 2) total_backorder,
            round(a_mproduct_dpurchase.precio_unitario * a_mproduct_dpurchase.cantidad_order, 2) total_order,
            round(a_mproduct_dpurchase.precio_unitario * a_mproduct_dpurchase.cantidad_rec, 2) total_rec
		from a_mproduct_dpurchase
			left join tb_c_opurchase_orders
				on a_mproduct_dpurchase.codemp = tb_c_opurchase_orders.codemp
					and a_mproduct_dpurchase.sucursal = tb_c_opurchase_orders.sucursal
					and a_mproduct_dpurchase.numero = tb_c_opurchase_orders.numero
			left join tb_c_mvendors
				on tb_c_opurchase_orders.codemp = tb_c_mvendors.codemp
					and tb_c_opurchase_orders.sucursal = tb_c_mvendors.sucursal
					and tb_c_opurchase_orders.proveedor = tb_c_mvendors.codigo			
			left join tb_f_mcustomers
				on tb_c_opurchase_orders.codemp = tb_f_mcustomers.codemp
					and tb_c_opurchase_orders.sucursal = tb_f_mcustomers.sucursal
                    and tb_c_opurchase_orders.cliente = tb_f_mcustomers.codigo
		order by a_mproduct_dpurchase.numero desc ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_a_mproduct_dsales_d_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_a_mproduct_dsales_d_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
    in _modo smallint(1),
	in _producto varchar(100),
    in _usuario varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Consulta generica de los datos para los formularios
		Versión 1.0
		Creado: 2025-09-04
		Actualizado: 2025-09-04
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    set @usuario = coalesce(_usuario) ;
	select	coalesce(u218, '') into @cliente
		from tb_musuario
        where u201 = @usuario ;
        
    drop temporary table if exists c_mproduct_dsale ;
    create temporary table c_mproduct_dsale
		select	tb_f_osales_dproducts.*
			from tb_f_osales_dproducts
				inner join tb_f_osales_orders
					on tb_f_osales_dproducts.codemp = tb_f_osales_orders.codemp
					and tb_f_osales_dproducts.sucursal = tb_f_osales_orders.sucursal
					and tb_f_osales_dproducts.numero = tb_f_osales_orders.numero
					and case when @cliente = '' 
								then tb_f_osales_orders.cliente = tb_f_osales_orders.cliente
                                else tb_f_osales_orders.cliente = @cliente
							end
            where tb_f_osales_dproducts.codemp = _codemp
				and tb_f_osales_dproducts.sucursal = _sucursal
                and tb_f_osales_dproducts.producto = _producto ;
	
	select	c_mproduct_dsale.*,
            coalesce(tb_f_mcustomers.nombre, '') as ncustomer,
			round(c_mproduct_dsale.precio_venta * c_mproduct_dsale.cantidad_ord, 2) total_ord,
            round(c_mproduct_dsale.precio_venta * c_mproduct_dsale.cantidad_env, 2) total_ent
		from c_mproduct_dsale
			inner join tb_f_osales_orders
				on c_mproduct_dsale.codemp = tb_f_osales_orders.codemp
					and c_mproduct_dsale.sucursal = tb_f_osales_orders.sucursal
					and c_mproduct_dsale.numero = tb_f_osales_orders.numero
			left join tb_f_mcustomers
				on tb_f_osales_orders.codemp = tb_f_mcustomers.codemp
					and tb_f_osales_orders.sucursal = tb_f_mcustomers.sucursal
                    and tb_f_osales_orders.cliente = tb_f_mcustomers.codigo
		order by coalesce(c_mproduct_dsale.numero, '') desc ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_a_oproduct_dsales_d_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_a_oproduct_dsales_d_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
    in _modo smallint(1),
	in _producto varchar(100)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Consulta generica de los datos para los formularios
		Versión 1.0
		Creado: 2025-09-04
		Actualizado: 2025-09-04
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    drop temporary table if exists c_mproduct_dsale ;
    create temporary table c_mproduct_dsale
		select	*
			from tb_f_osales_dproducts
            where codemp = _codemp
				and sucursal = _sucursal
                and producto = _producto ;
	
	select	c_mproduct_dsale.*,
			coalesce(tb_a_mproducts.nombre, '') as nproduct,
			round(c_mproduct_dsale.precio_venta * c_mproduct_dsale.cantidad_ord, 2) total_ord,
            round(c_mproduct_dsale.precio_venta * c_mproduct_dsale.cantidad_env, 2) total_ent
		from c_mproduct_dsale
			left join tb_f_osales
				on c_mproduct_dsale.codemp = tb_f_osales.codemp
					and c_mproduct_dsale.sucursal = tb_f_osales.sucursal
					and c_mproduct_dsale.numero = tb_f_osales.numero
		order by tb_f_osales_dproducts.numero desc ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_cfg_acceso_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_cfg_acceso_c`(
	in _cadena_prim varchar(50), 
	in _cadena_seg varchar(50)
)
begin
	/* ---------------------------------------------------------------------------------------------------------------------------------------------
		Comprueba si el usuario existe, si está activo y si la contraseña coincice
		V 1.0
		Creado 2025-02-03
		Actualizado 2025-02-03, 2025-02-08, 2025-03-23
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
	set @_codemp = '01';

	if (( Trim(_cadena_prim )<> '' ) and ( Trim(_cadena_seg )<> '' )) then
		select 	tb_musuario.*,
				coalesce(cfg_mlenguaje.archivo,'') as lenguaje,
				coalesce(cfg_mlenguaje.archivo_rp,'') as lenguaje_rp,
				coalesce(cfg_mformato.formato_fecha,'') as formato_fecha,
				coalesce(cfg_mformato.formato_hora,'') as formato_hora,
                coalesce(cfg_timezones.nombre,'') as timezone,
                coalesce(cfg_mempresa.nombre,'') as nempresa
			from tb_musuario
				left join tb_musuario_grupo on tb_musuario_grupo.u201 = tb_musuario.u206
				left join cfg_mlenguaje on tb_musuario.u212 = trim(cfg_mlenguaje.codigo)
				left join cfg_mformato on tb_musuario.u213 = cfg_mformato.codigo
				left join cfg_timezones on tb_musuario.u217 = cfg_timezones.codigo
                left join cfg_mempresa on cfg_mempresa.codigo = @_codemp
			where tb_musuario.u203 = _cadena_prim 
				and tb_musuario.u204 = sha1(_cadena_seg) 
				and tb_musuario.estado = 1 ;
	else
		select -1 ;
	end if;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_cfg_acceso_pin_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_cfg_acceso_pin_c`(
	in _cadena_prim varchar(50), 
	in _cadena_seg varchar(50)
)
begin
	/* ---------------------------------------------------------------------------------------------------------------------------------------------
		Comprueba si el usuario existe, si está activo y si la contraseña coincice
		V 1.0
		Creado 2025-02-03
		Actualizado 2025-02-03, 2025-02-08, 2025-03-09
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */

	if (( Trim(_cadena_prim )<> '' ) and ( Trim(_cadena_seg )<> '' )) then
		select 	u201 into @codigo
			from tb_musuario
			where tb_musuario.u203 = _cadena_prim 
				and tb_musuario.estado = 1 ;
			
		set @KeyU220 = '' ;  
        call sp_cfg_formulario_aesed_c(5, @codigo, 'u220', @KeyU220) ;
    
		select 	tb_musuario.u219
			from tb_musuario
			where tb_musuario.u203 = _cadena_prim 
				and tb_musuario.u220 = aes_encrypt(_cadena_seg,  @KeyU220)
				and tb_musuario.estado = 1 ;
	else
		select -1 ;
	end if;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_cfg_mdepartamento_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_cfg_mdepartamento_u`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _usuario varchar(10),
	in _caja varchar(10),
	in _codigo varchar(5), 
	in _nombre varchar(120), 
	in _estado varchar(1), 
	out _valor varchar(11)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Actualiza los datos del maestro de departamentos
		Versión 1.0
		Creado: 02/07/2014
		Actualizado: 2024.04.13, 01/09/2014
		Autor: 
	---------------------------------------------------------------------------------------------------- */
	
   if trim(_codigo) = '' then
		call sp_tdocumento_u('cfg_mdepartamento', 5, 1, @_codigo);
		set _codigo = @_codigo;
	    insert into cfg_mdepartamento (codemp, codigo, nombre, estado) values (_codemp, _codigo, ltrim(_nombre), _estado);
	else
		update cfg_mdepartamento 
			set 
				nombre = _nombre, 
				estado = _estado 
			where codigo = _codigo 
				and codemp = _codemp;
	end if;
	set _valor = _codigo;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_cfg_mempresa_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_cfg_mempresa_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _status varchar(1), 
	in _parametro varchar(3),
	in _tabla varchar(20),
	in _tipo varchar(3)
)
begin
	-- ----------------------------------------------------
	-- Consulta datos de la empresa
	-- Versión 1.0
	-- Creado: 2024.12.01
	-- Actualizado: 2024.12.29
	-- Autor: 
	-- ----------------------------------------------------
	if (_codemp is not null) OR (_sucursal is not null) or (_tabla is not null) or (_parametro is not null) then
		set @sql_where = concat(' where codigo = ', _codemp);
		
		-- ----------------------------------------------------
		call sql_prepare(trim(_tabla), @sql_where) ;
		set @sql_where = null ;
		
		-- ----------------------------------------------------
		select	sql_tabla.*,
				coalesce(tb_g_mdivisa_b.nombre, '') as ndivisa,
                coalesce(tb_g_mdivisa_c.nombre, '') as nmoneda,
				coalesce(cfg_mestado.nombre, '') as nestado,
				coalesce(cfg_mestado.clase_css, '') as nestado_clase_css,
				coalesce(cfg_mestado.img_icon, '') as nestado_img_icon
			from sql_tabla
				left join tb_g_mdivisa as tb_g_mdivisa_b 
					on sql_tabla.codigo = tb_g_mdivisa_b.codemp
						and sql_tabla.divisa = tb_g_mdivisa_b.codigo
				left join tb_g_mdivisa as tb_g_mdivisa_c 
					on sql_tabla.codigo = tb_g_mdivisa_c.codemp
						and sql_tabla.moneda = tb_g_mdivisa_c.codigo
				left join cfg_mestado 
					on sql_tabla.estado = cfg_mestado.codigo 
						and cfg_mestado.tipo = trim(_tipo);
		
	else
		select -1 ;
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_cfg_mempresa_smtp_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_cfg_mempresa_smtp_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _status varchar(1), 
	in _parametro varchar(255), 
	in _tabla varchar(255), 
	in _tipo varchar(3)
)
begin
	-- ----------------------------------------------------
	-- consulta generica de los datos para los formularios
	-- Versión 1.0
	-- Creado: 2025-09-23
	-- Actualizado: 2025-09-23
	-- Autor: 
	-- ----------------------------------------------------
    if (_codemp is not null) OR (_sucursal is not null) or (_tabla is not null) or (_parametro is not null) then
		set @sql_where = concat(' where estado <> 0');
		if trim(coalesce(_parametro, '')) <> '' then
			set @sql_where = concat(@sql_where, ' and codigo = "', trim(_parametro), '"');
		end if;
		
		-- ----------------------------------------------------
		call sql_prepare(trim(_tabla), @sql_where) ;
		set @sql_where = null ;
		
		-- ----------------------------------------------------
		call sp_cfg_formulario_aesed_c(40, _parametro, 'smtp', @key1) ;    
        call sp_cfg_formulario_aesed_c(40, _parametro, 'email', @key2) ;  
        call sp_cfg_formulario_aesed_c(40, _parametro, 'pass', @key3) ; 
        
		select	sql_tabla.codemp, sql_tabla.codigo, sql_tabla.nombre, 
				sql_tabla.puerto, sql_tabla.asunto, 
                convert(aes_decrypt(sql_tabla.servidor_smtp, @key1) using utf8mb4) as servidor_smtp,
                convert(aes_decrypt(sql_tabla.email, @key2) using utf8mb4) as email,
				convert(aes_decrypt(sql_tabla.password, @key3) using utf8mb4) as password,
                sql_tabla.estado, coalesce(cfg_mestado.nombre, '') as nestado
			from sql_tabla
				inner join cfg_mestado 
					on sql_tabla.estado = cfg_mestado.codigo 
						and cfg_mestado.codemp = _codemp 
						and cfg_mestado.tipo = trim(_tipo)  ;
		
	else
		select -1 ;
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_cfg_mempresa_smtp_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_cfg_mempresa_smtp_u`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
	in _usuario varchar(10),
    in _formulario int,
	in _codigo varchar(5),
    in _nombre varchar(100),
	in _email varchar(50),
    in _asunto varchar(100),
    in _estado char(3),
    in _servidor_smtp varchar(100),
    in _puerto varchar(5),
    in _password varchar(50),
	out _valor varchar(15)
)
begin
	-- -----------------------------------------------------
	-- Actualiza los datos de la sucursal
	-- Versión 1.0
	-- Creado: 20205-09-23
	-- Actualizado: 2025-09-23
	-- Autor: 
	-- ---------------------------------------------------
    
    set @key1 = '' ; 
    select case when coalesce( _estado, '') = '' then '1' else coalesce( _estado, '1') end into @estado;
	
	if (trim(_codigo) = '') then
		call sp_tdocumento_u(concat(_codemp, 'cfg_mempresa_smtp'), 3, 1, @_codigo);
		set _codigo = concat(_codemp, @_codigo);
        call sp_cfg_formulario_aesed_c(40, _codigo, 'smtp', @key1) ;     
		set @_smtp = aes_encrypt(trim(coalesce(_servidor_smtp, '')), @key1);
        
        call sp_cfg_formulario_aesed_c(40, _codigo, 'email', @key1) ;     
		set @_email = aes_encrypt(trim(coalesce(_email, '')), @key1);
        
        call sp_cfg_formulario_aesed_c(40, _codigo, 'pass', @key1) ;     
		set @_password = aes_encrypt(trim(coalesce(_password, '')), @key1);
		
        insert into cfg_mempresa_smtp(codemp, codigo, nombre, servidor_smtp, puerto, password, email, asunto, estado) 
			select	_codemp, _codigo, _nombre, @_smtp, _puerto, @_password, @_email, _asunto, 1;
        
	else
        call sp_cfg_formulario_aesed_c(40, _codigo, 'smtp', @key1) ;     
		set @_smtp = aes_encrypt(trim(coalesce(_servidor_smtp, '')), @key1);
        
        call sp_cfg_formulario_aesed_c(40, _codigo, 'email', @key1) ;     
		set @_email = aes_encrypt(trim(coalesce(_email, '')), @key1);
        
        call sp_cfg_formulario_aesed_c(40, _codigo, 'pass', @key1) ;     
		set @_password = aes_encrypt(trim(coalesce(_password, '')), @key1);
        
	   	update  cfg_mempresa_smtp
			set
				nombre = _nombre, 
                servidor_smtp = @_smtp, 
                puerto = _puerto, 
                password = @_password, 
                email = @_email, 
                asunto = _asunto, 
                estado = @estado
			where codemp = _codemp
				and codigo = _codigo;
                
	end if;
    set _valor = _codigo;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_cfg_mempresa_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_cfg_mempresa_u`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
	in _usuario varchar(10),
    in _formulario int,
	in _codigo varchar(2), 
    in _estado_ciudad varchar(5), 
    in _ciudad varchar(100), 
    in _zcode varchar(10),
    in _estado varchar(3),
    in _web varchar(100), 
    in _email varchar(100), 
    in _direccion varchar(1000), 
    in _divisa varchar(5),
    in _moneda varchar(5), 
    in _logo_qr varchar(50),
	in _plataforma_a varchar(50),
	in _plataforma_b varchar(50),
	in _plataforma_c varchar(50),
	in _plataforma_d varchar(50),
	out _valor varchar(15)    
)
begin
	-- -----------------------------------------------------
	-- Actualiza los datos de la organización
	-- Versión 1.0
	-- Creado: 2024.12.01
	-- Actualizado: 2024.12.30
	-- Autor: 
	-- ---------------------------------------------------
    select pais into @pais
		from tb_g_mestado_ciudad
        where codigo = _estado_ciudad ;
        
    if coalesce(_codigo, '') != '' then 
		update cfg_mempresa 
			set
				pais = @pais, 
				estado_ciudad = _estado_ciudad, 
				ciudad = _ciudad, 
				zcode = _zcode, 
                web = _web,
				email = _email, 
				direccion = _direccion, 
				divisa = _divisa, 
				moneda = _moneda,
				logo_qr = _logo_qr,
				plataforma_a = _plataforma_a,
				plataforma_b = _plataforma_b,
				plataforma_c = _plataforma_c,
				plataforma_d = _plataforma_d
			where codigo = _codigo ;
	end if ;
    set _valor = _codigo;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_cfg_msucursal_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_cfg_msucursal_u`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
	in _usuario varchar(10),
    in _formulario int,
	in _codigo varchar(3), 
    in _nombre varchar(100), 
    in _pais varchar(100), 
    in _estado_provincia varchar(100), 
    in _ciudad varchar(100), 
    in _codigo_postal varchar(10), 
    in _email varchar(100), 
    in _telefonos varchar(100), 
    in _direccion varchar(8000), 
    in _almacen_e varchar(10),
    in _almacen_s varchar(10), 
    in _almacen_a int(1), 
    in _estado char(3), 
	out _valor varchar(15)
)
begin
	-- -----------------------------------------------------
	-- Actualiza los datos de la sucursal
	-- Versión 1.0
	-- Creado: 2020.03.17
	-- Actualizado: 2024.04.13, 2020.03.17
	-- Autor: 
	-- ---------------------------------------------------
    
    if coalesce(_codigo, '') != '' then 
		update cfg_msucursal 
			set
				pais = _pais, 
				estado_provincia = _estado_provincia, 
				ciudad = _ciudad, 
				codigo_postal = _codigo_postal, 
				email = _email, 
				telefonos = _telefonos, 
				direccion = _direccion, 
				almacen_e = _almacen_e, 
				almacen_s = _almacen_s, 
				almacen_actualiza = _almacen_a
			where codemp = _codemp
				and codigo = _codigo ;
	end if ;
    set _valor = _codigo;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_cfg_musuaiod_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_cfg_musuaiod_c`(
	in _codemp varchar(2), 
    in _sucursal varchar(3), 
    in _parametro varchar(15))
begin
	-- ---------------------------------------------------
	-- Consulta datos del detalle de usuarios
	-- Empresas y sucursales
	-- Versión 1.0
	-- Creado: 18/08/2014
	-- Actualizado: 2024.04.13, 27/10/2014
	-- Autor: 
	-- ---------------------------------------------------
	
	drop temporary table if exists a1;
	create temporary table a1
		select 	empresa as codemp, 
				sucursal,
				1 as marca,
				item
			from tb_musuariod
			where u201 = trim(_parametro) ;

	drop temporary table if exists a2 ;
	create temporary table a2
		select 	codemp, 
				codigo as sucursal, 
				0 as marca,
				0 as item
			from cfg_msucursal 
			where concat(codemp, codigo) not in (select concat(codemp, sucursal) from a1) ;

	drop temporary table if exists a3 ;
	create temporary table a3
		select codemp, sucursal, marca, item 
			from a1
		union 
		select codemp, sucursal, marca, item 
			from a2 ;
	
	
	select	a3.codemp,
			coalesce(cfg_mempresa.nombre,'') as nempresa,
			a3.sucursal,
			coalesce(cfg_msucursal.nombre,'') as nsucursal,
			a3.marca,
			a3.item
		from a3
			left join cfg_mempresa 
				on cfg_mempresa.codigo = a3.codemp
			left join cfg_msucursal 
				on cfg_msucursal.codemp = a3.codemp 
					and cfg_msucursal.codigo = a3.sucursal
	order by a3.codemp, cfg_msucursal.nombre;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_cfg_musuariod_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_cfg_musuariod_u`(
	in _nousar1 varchar(1),
	in _nousar2 varchar(1),
	in _parametro varchar(5),
	in _nousar3 varchar(1),
	in _nousar4 varchar(1),
	in _marca int(1),
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _item int(11)
)
begin
	-- --------------------------------------------------
	-- inserta o actualiza registros del detalle de 
	-- usuarios (empresas y sucursales )
	-- Versión 1.0
	-- Creado: 14/08/2014
	-- Actualizado: 2024.04.13, 15/09/2015
	-- Autor: 
	-- --------------------------------------------------

	if _item = 0 and _marca = 1 then
		-- Si no está guardado y está marcado se inserta
		insert into tb_musuariod(u201, empresa, sucursal)
			Values (_parametro, _codemp, _sucursal);
	elseif _item <>0 then
		-- actualiza los registros del detalle
		if _marca = 0 then
		   delete 
			from tb_musuariod 
			where u201 = _parametro
				and item = _item ;
		else
			update tb_musuariod 
				set
					empresa = _codemp,
					sucursal = _sucursal
				where u201 = _parametro
					and item = _item ;
		end if;
	end if;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_cfg_musuario_acceso_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_cfg_musuario_acceso_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
	in _u201 varchar(5),
	in _formulario int(11)
)
begin
	-- ---------------------------------------------------
	-- consulta los accesos de usuario 
	-- Versión 1.0
	-- Creado: 07/10/2015
	-- Actualizado: 2024.04.13, 07/02/2018
	-- Autor: 
	-- ---------------------------------------------------
	set @grupo = '' collate utf8mb4_spanish_ci;
	select u206 into @grupo
		from tb_musuario
		where u201 = _u201;

	select * 
		from tb_musuario_dpermiso
		where u201 = @grupo
			and u202 = _formulario;

end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_cfg_musuario_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_cfg_musuario_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _status varchar(1), 
	in _parametro varchar(255), 
	in _tabla varchar(255), 
	in _tipo varchar(3))
begin
	-- ----------------------------------------------------
	-- consulta generica de los datos para los formularios
	-- Versión 1.0
	-- Creado: 2024.12.0
	-- Actualizado: 2024.12.29
	-- Autor: 
	-- ----------------------------------------------------
    if (_codemp is not null) OR (_sucursal is not null) or (_tabla is not null) or (_parametro is not null) then
		set @sql_where = concat(' where estado <> 0');
		if trim(coalesce(_parametro, '')) <> '' then
			set @sql_where = concat(@sql_where, ' and u201 = "', trim(_parametro), '"');
		end if;
		
		-- ----------------------------------------------------
		call sql_prepare(trim(_tabla), @sql_where) ;
		set @sql_where = null ;
		
		-- ----------------------------------------------------
        set @KeyU220 = '' ;  
        call sp_cfg_formulario_aesed_c(5, _parametro, 'u220', @KeyU220) ;
		select	sql_tabla.u201, sql_tabla.u202, sql_tabla.u203, sql_tabla.u204, sql_tabla.u205, sql_tabla.u205_s, 
				sql_tabla.u206, sql_tabla.u207, sql_tabla.u209, sql_tabla.u210, sql_tabla.u211, sql_tabla.u212, 
				sql_tabla.u213, sql_tabla.u214, sql_tabla.u215, sql_tabla.u216, sql_tabla.estado, sql_tabla.u217, 
				sql_tabla.u218, sql_tabla.u219, sql_tabla.u221,
				sql_tabla.u224, sql_tabla.u225, sql_tabla.u226,
				convert(aes_decrypt(sql_tabla.u220, @KeyU220) using utf8) as u220,
				coalesce(cfg_mestado.nombre, '') as nestado,
				coalesce(cfg_mdepartamento.nombre,'') as ndepartamento,
				coalesce(tb_musuario_grupo.u202,'') as ngrupo
			from sql_tabla
				left join cfg_mdepartamento 
					on sql_tabla.u210 = cfg_mdepartamento.codigo 
						and cfg_mdepartamento.codemp = _codemp
				left join tb_musuario_grupo 
					on sql_tabla.u206 = tb_musuario_grupo.u201
				inner join cfg_mestado 
					on sql_tabla.estado = cfg_mestado.codigo 
						and cfg_mestado.codemp = _codemp 
						and cfg_mestado.tipo = trim(_tipo)  ;
		
	else
		select -1 ;
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_cfg_musuario_cambiopwd_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_cfg_musuario_cambiopwd_u`(
	in _usuario varchar(10),
	in _pass varchar(50)
)
begin
	-- -------------------------------------------
	-- actualiza el passord de usuarios, 
	-- V 1.0
	-- Creado 07/01/2016
	-- Actualizado 03-16-2025
	-- Autor:  Custom Systems Solutions LLC
	-- -------------------------------------------
    
	update tb_musuario 
		set
			u221 = null,
			u204 = sha1(md5(_pass))
		where u203 = _usuario;
        
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_cfg_musuario_dgrupo_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_cfg_musuario_dgrupo_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
    in _modo varchar(1),
	in _parametro varchar(15),
    in _usuario varchar(10)
)
begin
	-- ------------------------------------------------------------------------------------------------------------------------
	-- Consulta datos del detalle de grupos de usuarios
	-- Versión 1.0
	-- Creado: 2025-03-02
	-- Actualizado: 2025-07-10
	-- Autor: Custom Systems Solutions LLC
	-- ------------------------------------------------------------------------------------------------------------------------
    set @usuario = coalesce(_usuario, '') ;
	select	coalesce(u218, ''), coalesce(u230, 0) into @grupo, @nivel from tb_musuario where u201 = @usuario ;
     
	drop temporary table if exists a1;
	create temporary table a1
		select *
			from tb_musuario_dpermiso
			where u201 = coalesce(_parametro, '') ;
	
	drop temporary table if exists a2;
	create temporary table a2
		select 	coalesce(_parametro, '') u201,
				formulario as  u202,
				0 u204, 0 u205, 
                0 u206, 0 u207, 0 u208, 0 u209, 0 u210,
				0 u211, 0 u212, 0 u213, 0 u214, 0 u215, 
                0 u216, 0 u217, 0 u218, 0 u219, 0 u220
			from cfg_lista_formularios
			where formulario not in (select u202 from a1) ;
		
	drop temporary table if exists a3 ;
	create temporary table a3
		select 	u201, u202, u204, u205, u206, u207, u208, u209, u210, 
				u211, u212, u213, u214, u215, u216, u217, u218, u219, u220 
			from a1
		union 
		select 	u201, u202, u204, u205, u206, u207, u208, u209, u210, 
				u211, u212, u213, u214, u215, u216, u217, u218, u219, u220 
			from a2 ;

	select	a3.*,
			coalesce(cfg_lista_formularios.titulo,'') as nopcion,
			coalesce(cfg_menu_modulo.nombre,'') as nmodulo,
			coalesce(cfg_menu_grupo.nombre,'') as ngrupo
		from a3
			inner join cfg_lista_formularios 
				on cfg_lista_formularios.formulario = a3.u202
					and cfg_lista_formularios.nivel between 1 and @nivel
                    and cfg_lista_formularios.estado = 1
			left join cfg_menu_modulo 
				on cfg_menu_modulo.codigo = cfg_lista_formularios.modulo
			left join cfg_menu_grupo 
				on cfg_menu_grupo.codigo = cfg_lista_formularios.grupo
	order by cfg_menu_modulo.codigo, cfg_menu_grupo.codigo, cfg_lista_formularios.titulo;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_cfg_musuario_dgrupo_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_cfg_musuario_dgrupo_u`(
	in _codemp varchar(2), 
    in _sucursal varchar(3),
	in _u201 varchar(5),
	in _u202 smallint,
	in _u204 smallint, 
	in _u205 smallint, 
	in _u206 smallint, 
	in _u207 smallint, 
	in _u208 smallint, 
	in _u209 smallint, 
	in _u210 smallint, 
	in _u211 smallint, 
	in _u212 smallint, 
	in _u213 smallint, 
	in _u214 smallint, 
    in _u215 smallint, 
    in _u216 smallint, 
    in _u217 smallint, 
    in _u218 smallint, 
    in _u219 smallint, 
	in _item int(11)
)
begin
	-- ------------------------------------------------------------------------------------------------------------------------
	-- inserta o actualiza registros del detalle de grupos de usuarios (accesos)
	-- Versión 1.0
	-- Creado: 2024-12-01
	-- Actualizado: 2025-07-15
	-- Autor: Custom Systems Solutions LLC
	-- ------------------------------------------------------------------------------------------------------------------------
    
	if coalesce(_item, 0) = 0 then
		-- Si no está guardado y está marcado se inserta
		insert into tb_musuario_dpermiso(u201, u202, u204, u205, u206, u207, u208, u209, u210, u211, u212, u213, u214, u215, u216, u217, u218, u219)
			values (_u201, _u202, _u204, _u205, _u206, _u207, _u208, _u209, _u210, _u211, _u212, _u213, _u214, _u215, _u216, _u217, _u218, u219);
	else
		-- Actualiza los registros del detalle
		update tb_musuario_dpermiso 
			set
				u204 = _u204,
				u205 = _u205,
				u206 = _u206,
				u207 = _u207,
				u208 = _u208,
				u209 = _u209,
				u210 = _u210,
				u211 = _u211,
				u212 = _u212,
				u213 = _u213,
				u214 = _u214,
                u215 = _u215,
                u216 = _u216,
                u217 = _u217,
                u218 = _u218,
                u219 = _u219
			where u201 = _u201
				and u202 = _u202
				and u220 = _item ;
	end if;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_cfg_musuario_grupo_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_cfg_musuario_grupo_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _status varchar(1), 
	in _parametro varchar(255), 
	in _tabla varchar(255), 
	in _tipo varchar(3)
)
begin
	-- ------------------------------------------------------------------------------------------------------------------------
	-- consulta generica de los datos para los formularios
	-- Versión 1.0
	-- Creado: 2024.12.01
	-- Actualizado: 2024.12.29
	-- Autor: Custom Systems Solutions LLC
	-- ------------------------------------------------------------------------------------------------------------------------
    if (_codemp is not null) OR (_sucursal is not null) or (_tabla is not null) or (_parametro is not null) then
		set @sql_where = concat(' where estado <> 0');
		if trim(coalesce(_parametro, '')) <> '' then
			set @sql_where = concat(@sql_where, ' and u201 = "', trim(_parametro), '"');
		end if;
		
		-- ----------------------------------------------------
		call sql_prepare(trim(_tabla), @sql_where) ;
		set @sql_where = null ;
		
		-- ----------------------------------------------------
		select	sql_tabla.*,
				coalesce(cfg_mestado.nombre, '') as nestado
			from sql_tabla
				inner join cfg_mestado 
					on sql_tabla.estado = cfg_mestado.codigo 
						and cfg_mestado.codemp = _codemp 
						and cfg_mestado.tipo = trim(_tipo)  ;
		
	else
		select -1 ;
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_cfg_musuario_grupo_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_cfg_musuario_grupo_u`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _usuario varchar(10),
	in _formulario varchar(5),
	in _codigo varchar(5), 
	in _nombre varchar(120), 
    in _notificacion char(1),     
	in _estado char(3), 
	out _valor varchar(11)
)
begin
	-- -------------------------------------------------------
	-- actualiza los datos del maestro de grupos de usuarios
	-- Versión 1.0
    -- Creado 2024-12-01
	-- Actualizado 2025-07-09
	-- Autor: Custom Systems Solutions LLC
	-- -------------------------------------------------------
	set @notificacion = coalesce(NULLIF(_notificacion, 0), 0) ;
	if (Trim(_codigo) = '') then
		call sp_tdocumento_u('tb_musuario_grupo', 5, 1, @_codigo);
		set _codigo = @_codigo;
        insert into tb_musuario_grupo (u201, u202, u224, estado) 
				Values (_codigo, _nombre, @notificacion, 1);
	else
		update tb_musuario_grupo 
			set
				u202 = _nombre,
                u224 = @notificacion,
				estado = _estado
			where u201 = _codigo;
    end if;
	set _valor = _codigo;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_cfg_musuario_req_cambio_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_cfg_musuario_req_cambio_c`(
	in _hash varchar(100)
)
begin
	-- -------------------------------------------
	-- actualiza los datos de usuarios, 
	-- V 1.0
	-- Creado 03/14/2025
	-- Actualizado 03/16/2025
	-- Autor: Custom Systems Solutions LLC
	-- -------------------------------------------
    set @variable = _hash collate utf8mb4_spanish_ci;
    -- collate utf8mb4_spanish_ci
    
	SELECT coalesce(TIMESTAMPDIFF(MINUTE, u222, NOW()), 31)  into @date_time_actual_reg
		FROM tb_musuario
		WHERE u221 = @variable ;
	
	if @date_time_actual_reg > 30  then
		update tb_musuario
			set
				u221 = null
			where u221 = @variable ;
	end if ;	

	select case when @date_time_actual_reg between 0 and 30 then 1 else 0 end ;
    
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_cfg_musuario_req_cambio_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_cfg_musuario_req_cambio_u`(
	in _usuario varchar(10),
	out _valor varchar(100)
)
begin
	-- -------------------------------------------
	-- actualiza los datos de usuarios, 
	-- V 1.0
	-- Creado 03/14/2025
	-- Actualizado 
	-- Autor: Custom Systems Solutions LLC
	-- -------------------------------------------
	set @KeyU221 = sha(substring(rand(), 3, 5));
	set @date_time = CURRENT_TIMESTAMP();
    
    -- select TIMESTAMPDIFF(MINUTE, @time, NOW()) as now;
    
	update tb_musuario 
		set
			u221 = @KeyU221,
			u222 = @date_time
		where u203 = _usuario;

	set _valor = @KeyU221;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_cfg_musuario_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_cfg_musuario_u`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _usuario varchar(10),
	in _formulario varchar(10),
	in _codigo varchar(5),
	in _nombre varchar(120), 
	in _login varchar(50),
	in _cambio_pass char(1), 
	in _grupo varchar(10),
    in _cliente varchar(15),
    in _estado varchar(1),
    in _timezone varchar(10),    
	in _lenguaje varchar(5),
	in _formato_fecha_hora varchar(1),
	in _signo_decimal varchar(1),
	in _signo_miles varchar(1), 
	in _pin varchar(5),
	in _email varchar(50), 
    in _notificacion char(1), 
    in _externo char(1), 
    in _requiere_localizacion char(1), 
	out _valor varchar(11)
)
begin
	-- -------------------------------------------
	-- actualiza los datos de usuarios, 
	-- V 1.0
	-- Creado 2024-12-01
	-- Actualizado 2025-07-10
	-- Autor: Custom Systems Solutions LLC
	-- -------------------------------------------
    
    select case when coalesce(_timezone, '') = '' then '108' else coalesce(_timezone, '') end into @timezone ;
    select case when coalesce(_formato_fecha_hora, '') = ''  then '2' else coalesce(_formato_fecha_hora, '2') end into @formato_fecha_hora ;
	select case when coalesce(_signo_decimal, '') = '' then '.' else coalesce(_signo_decimal, '.') end into @signo_decimal;
    select case when coalesce( _signo_miles, '') = '' then ',' else coalesce( _signo_miles, ',') end into @signo_miles;
    select case when coalesce( _lenguaje, '') = '' then 'en_us' else coalesce( _lenguaje, 'en_us') end into @lenguaje;
    select case when coalesce( _pin, '') = '' then substring(rand(), 3, 5) else coalesce( _pin, substring(rand(), 3, 5)) end into _pin;
    select case when coalesce( _estado, '') = '' then '1' else coalesce( _estado, '1') end into @estado;
    select case when coalesce( _externo, '') = '' then '0' else coalesce( _externo, '1') end into @externo;
    select case when coalesce( _requiere_localizacion, '') = '' then '0' else coalesce( _requiere_localizacion, '1') end into @localizacion;
    
	set @cambio_pass = coalesce(NULLIF(_cambio_pass, 0), 0) ;
    set @notificacion = coalesce(NULLIF(_notificacion, 0), 0) ;
    -- set @externo = coalesce(NULLIF(_externo, 0), 0) ;
    set @login = '' collate utf8mb4_spanish_ci ;
    
    -- set @KeyU205 = '' ;
    set @KeyU220 = '' ;  
    
	if (trim(_codigo) = '') then
		call sp_tdocumento_u('tb_musuario', 5, 1, @_codigo);
		set _codigo = @_codigo;
		-- call sp_cfg_formulario_aesed_c(5, @_codigo, 'u205', @KeyU205) ;
		call sp_cfg_formulario_aesed_c(5, @_codigo, 'u220', @KeyU220) ;
        set @pin = aes_encrypt(coalesce(_pin, ''), @KeyU220);
        
        select coalesce(u203) into @login
			from tb_musuario
            where u203 = _login ;

		select case when trim(_login) = trim(@login) then concat(trim(_login), substring(rand(), 3, 5)) else _login end into @login ;
        
        insert into tb_musuario(u201, u202, u203, u204, u205, u206, u207, estado, u209, u210, u211, u212, u213, u214, u215, u216, u217, u218, u219, u220, u224, u225, u226) 
			Values (_codigo, _nombre, @login, sha1(md5('Temporal1$')), '', _grupo, @cambio_pass, 1, '', '', '', @lenguaje, @formato_fecha_hora, @signo_decimal, @signo_miles, '01', @timezone, _cliente, _email, @pin, @notificacion, @externo, @localizacion);
        
        -- Asigna sucursal 00001 al usuario nuevo            
		insert into tb_musuariod (u201, empresa, sucursal) Values (_codigo, '01', '');
        
	else
		call sp_cfg_formulario_aesed_c(5, _codigo, 'u220', @KeyU220) ;
        set @pin = aes_encrypt(coalesce(_pin, ''), @KeyU220);

        select coalesce(u203) into @login 
			from tb_musuario
            where u203 = _login
				and u201 <> _codigo ;

		select case when trim(_login) = trim(@login) then concat(trim(_login), substring(rand(), 3, 5)) else _login end into @login ;
        
	   	update tb_musuario 
			set
				u202 = _nombre,
				u203 = @login COLLATE utf8mb4_spanish_ci,
				u205 = '',
				u206 = _grupo,
				u207 = @cambio_pass,
				u209 = '',
				u210 = '',
				u211 = '',
				u212 = @lenguaje,
				u213 = @formato_fecha_hora,
				u214 = @signo_decimal,
				u215 = @signo_miles,
				u217 = @timezone,
                u218 = _cliente,
				u219 = _email,
                u220 = @pin,
                u224 = @notificacion,
                u225 = @externo,
                u226 = @localizacion,
                estado = @estado
			where u201 = _codigo;
	end if;
	set _valor = _codigo;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_c_mvendors_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_c_mvendors_u`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
	in _usuario varchar(10),
	-- in _formulario int,
	in _codigo varchar(10),
    in _nombre varchar(120),
    in _telefono varchar(30), 
    in _pais varchar(70), 
    in _estado_ciudad varchar(70), 
    in _ciudad varchar(70), 
    in _zcode varchar(10), 
    in _direccion varchar(500),
    in _fecha_r varchar(25),
    in _fecha_u varchar(25)
    -- in _estado varchar(3)
    -- out _valor varchar(15)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Actualiza los datos del maestro de cliente
		Versión 1.0
		Creado: 2025-08-29
		Actualizado: 2025-09-10
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    set @tipo = 1 ;
    set @pais = coalesce(_pais, '') ;
    set @estado_ciudad = coalesce(_estado_ciudad, '');
    set @ciudad = coalesce(_ciudad, '');
    
    set @fecha_r = substring(Trim(_fecha_r),1, 10) ;
    set @fecha_u = substring(Trim(_fecha_u),1, 10) ;
    
    /*    
	delete 
		from tb_c_mvendors
        where codemp = _codemp
			and sucursal = _sucursal
			and trim(codigo) = _codigo ;
	
    insert into tb_c_mvendors (codemp, sucursal, codigo, nombre, pais, estado_ciudad, ciudad, zcode, telefono, direccion, fecha_r, fecha_u, usuario, estado, fecha_sync, tipo_sync)
		values (_codemp, _sucursal, _codigo, _nombre, @pais, @estado_ciudad, @ciudad, _zcode, _telefono, _direccion, @fecha_r, @fecha_u, _usuario, 1, curdate(), 1 );
	*/
    
	select count(codigo) into @existe
		from tb_c_mvendors
        where codemp = _codemp
			and sucursal = _sucursal
			and trim(codigo) = _codigo ;
        
	if (@existe = 0) then
        insert into tb_c_mvendors (codemp, sucursal, codigo, nombre, pais, estado_ciudad, ciudad, zcode, telefono, direccion, fecha_r, fecha_u, usuario, estado, fecha_sync, tipo_sync)
			values (_codemp, _sucursal, _codigo, _nombre, @pais, @estado_ciudad, @ciudad, _zcode, _telefono, _direccion, @fecha_r, @fecha_u, _usuario, 1, curdate(), 1 );
	else
		set @tipo = 2 ;
		update tb_c_mvendors
			set
				nombre = _nombre,
                pais = @pais,
				estado_ciudad = @estado_ciudad,
				ciudad = @ciudad, 
				zcode = _zcode, 
                telefono = _telefono,
                direccion = _direccion,
                fecha_u = @fecha_u,
                usuario = case when coalesce(usuario, '') = '' then _usuario else usuario end,
                fecha_sync = curdate(), 
                tipo_sync = 2
                -- estado = _estado
			where codemp = _codemp 
				and sucursal = _sucursal
				and codigo = _codigo;
	end if;
    
    -- call sp_s_log_u(_codemp, _sucursal, _formulario, _usuario, _codigo, @tipo, '','','','','','','','','','','') ;
    
	-- set _valor = _codigo;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_c_opurchase_dproducts_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_c_opurchase_dproducts_u`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
	in _usuario varchar(10),
	in _numero varchar(15),
	in _producto varchar(100), 
    in _descripcion varchar(250),
    in _precio_venta decimal(10,2), 
    in _precio_lista decimal(10,2),  
    in _precio_estimado decimal(10,2), 
    in _cantidad_backorder decimal(10,2), 
    in _cantidad_order decimal(10,2), 
    in _cantidad_rec decimal(10,2), 
    in _fecha_shipdate varchar(10), 
    in _envio_metodo varchar(10), 
    in _fecha_lastdate varchar(10), 
    in _fecha_nextdeli varchar(10), 
    in _notas varchar(1000), 
    in _nuevo_usado varchar(15),
    in _precio_unitario decimal(10,2),
    in _monto_tax decimal(10,2),
    in _unidad_medida varchar(15)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Actualiza los datos del opurchase dproducts
		Versión 1.0
		Creado: 2025-08-31
		Actualizado: 2025-08-31
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
	
    set @fecha_shipdate = substring(Trim(_fecha_shipdate), 1, 10) ;
    set @fecha_lastdate = substring(Trim(_fecha_lastdate), 1, 10) ;
    set @fecha_nextdeli = substring(Trim(_fecha_nextdeli), 1, 10) ;

	insert into tb_c_opurchase_dproducts (codemp, sucursal, numero, producto, nombre, precio_lista, precio_venta, precio_estimado, precio_unitario, monto_tax, cantidad_backorder, cantidad_order, cantidad_rec, fecha_shipdate, envio_metodo, fecha_lastdate, fecha_nextdeli, notas, nuevo_usado, unidad_medida, fecha_sync, tipo_sync)
		values (_codemp, _sucursal, _numero, _producto, _descripcion, _precio_lista, _precio_venta, _precio_estimado, _precio_unitario, _monto_tax, _cantidad_backorder, _cantidad_order, _cantidad_rec, @fecha_shipdate, _envio_metodo, @fecha_lastdate, @fecha_nextdeli, _notas, _nuevo_usado, _unidad_medida, curdate(), 1) ;
	
    set @existe = 0 ;
    select count(codigo) into @existe
		from tb_a_mproducts
        where codemp = _codemp
			and sucursal = _sucursal
            and codigo = _producto ;
	
   if (@existe = 0) then
		insert into tb_a_mproducts (codemp, sucursal, codigo, nombre, stock_disponible, stock_reserv, stock_enmano, stock_existencia, estado, fecha_sync, tipo_sync) 
			values (_codemp, _sucursal, _producto, _descripcion, 0, 0, 0, 0, 1, curdate(), 3) ;
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_c_opurchase_orders_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_c_opurchase_orders_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _status varchar(1), 
	in _parametro varchar(255), 
	in _tabla varchar(255), 
	in _tipo varchar(3)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Consulta generica de los datos para los formularios
		Versión 1.0
		Creado: 2025-09-04
		Actualizado: 2025-09-04
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
   if (_codemp is null) OR (_sucursal is null) or (_tabla is null) or (_parametro is null) then
        signal sqlstate '45000'
            set message_text = 'Parámetros incompletos. Todos los campos deben estar especificados.';
    end if ;
	set @sql_where = concat(' where codemp = ', _codemp, ' and estado <> 0');
	if trim(_sucursal) <> '' then
		set @sql_where = concat(@sql_where, ' and sucursal = ', _sucursal);
	end if;
	if trim(coalesce(_parametro, '')) <> '' then
		set @sql_where = concat(@sql_where, ' and numero = "', trim(_parametro), '"');
	end if;

	set @sql_where = concat('create temporary table sentencia select * from ', trim(_tabla), @sql_where);
    begin
		declare exit handler for sqlexception
        begin
            -- Manejo de errores de consulta
            rollback;
            select 'Error al ejecutar la consulta: ' || SQLERRM;
        end;
        
		prepare sentencia from @sql_where;
		execute sentencia ;
		deallocate prepare sentencia ;
	end ;
    set @sql_where = null ;
    
    -- ----------------------------------------------------------------------------------------------------
	select	sentencia.*,
            coalesce(tb_c_mvendors.nombre, '') as nvendor,
			coalesce(tb_f_mcustomers.nombre, '') as ncustomer,
			coalesce(cfg_mestado.nombre, '') as nestado,
			coalesce(cfg_mestado.clase_css, '') as nestado_clase_css,
			coalesce(cfg_mestado.img_icon, '') as nestado_img_icon
		from sentencia
			left join tb_f_mcustomers
				on sentencia.codemp = tb_f_mcustomers.codemp
					and sentencia.sucursal = tb_f_mcustomers.sucursal
					and sentencia.cliente = tb_f_mcustomers.codigo
			left join tb_c_mvendors
				on sentencia.codemp = tb_c_mvendors.codemp
					and sentencia.sucursal = tb_c_mvendors.sucursal
					and sentencia.proveedor = tb_c_mvendors.codigo
            left join cfg_mestado 
				on sentencia.codemp = cfg_mestado.codemp
					and sentencia.estado = cfg_mestado.codigo 
					and cfg_mestado.tipo = trim(_tipo) ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_c_opurchase_orders_d_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_c_opurchase_orders_d_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
    in _modo smallint(1),
	in _numero varchar(15),
    in _usuario varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Consulta generica de los datos para los formularios
		Versión 1.0
		Creado: 2025-09-01
		Actualizado: 2025-09-01
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
	select	tb_c_opurchase_dproducts.*,
			coalesce(tb_a_mproducts.nombre, '') as nproducto,
			round(tb_c_opurchase_dproducts.precio_unitario * tb_c_opurchase_dproducts.cantidad_backorder, 2) total_backorder,
            round(tb_c_opurchase_dproducts.precio_unitario * tb_c_opurchase_dproducts.cantidad_order, 2) total_order,
            round(tb_c_opurchase_dproducts.precio_unitario * tb_c_opurchase_dproducts.cantidad_rec, 2) total_rec
		from tb_c_opurchase_dproducts
			left join tb_a_mproducts
				on tb_c_opurchase_dproducts.codemp = tb_a_mproducts.codemp
					and tb_c_opurchase_dproducts.sucursal = tb_a_mproducts.sucursal
					and tb_c_opurchase_dproducts.producto = tb_a_mproducts.codigo
		where tb_c_opurchase_dproducts.codemp = _codemp
			and tb_c_opurchase_dproducts.sucursal = _sucursal
            and tb_c_opurchase_dproducts.numero = _numero 
		order by tb_c_opurchase_dproducts.producto ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_c_opurchase_orders_d_del` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_c_opurchase_orders_d_del`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
	in _numero varchar(15)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Actualiza los datos del maestro de cliente
		Versión 1.0
		Creado: 2025-08-30
		Actualizado: 2025-08-30
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
	
    delete from tb_c_opurchase_dproducts
		where codemp = _codemp 
			and sucursal = _sucursal
			and numero = _numero ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_c_opurchase_orders_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_c_opurchase_orders_u`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
	in _usuario varchar(10),
	in _numero varchar(15),
	in _fecha varchar(25),
    in _fecha_need varchar(25),
    in _fecha_ship varchar(25),
	in _fecha_repl varchar(25),
    in _fecha_rece varchar(25),
    in _fecha_comi varchar(25),
    in _fecha_u varchar(25),
    in _proveedor varchar(10),
    in _cliente varchar(10),
    in _referencia varchar(45),
    in _tracking varchar(45),
    in _envio_prioridad varchar(45),
    in _total_precio decimal(10,2),
	in _moneda varchar(5),
    in _usuario_sistema varchar(45),
    in _numero_item smallint(3),
    in _diferido varchar(1),
    in _estatus varchar(45)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Actualiza los datos de la opurchase orders
		Versión 1.0
		Creado: 2025-08-31
		Actualizado: 2025-08-31
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
	
    set @fecha = substring(Trim(_fecha),1, 10) ;
    set @fecha_need = substring(Trim(_fecha_need),1, 10) ;
    set @fecha_ship = substring(Trim(_fecha_ship),1, 10) ;
    set @fecha_repl = substring(Trim(_fecha_repl),1, 10) ;
	set @fecha_rece = substring(Trim(_fecha_rece),1, 10) ;
    set @fecha_comi = substring(Trim(_fecha_comi),1, 10) ;
    set @fecha_u = substring(Trim(_fecha_u),1, 10) ;
    set @diferido = case when coalesce(_diferido, '') = '' then '0' else '1' end ;
    set @estado = case 
						when substring(_estatus, 1, 3) = 'OPE' then 1
						when substring(_estatus, 1, 3) = 'CAN' then 2
						when substring(_estatus, 1, 3) = 'CLO' then 3
						else 1
					end ;
	select count(numero) into @existe
		from tb_c_opurchase_orders
        where trim(numero) = _numero ;
	
	if (@existe = 0) then
		insert into tb_c_opurchase_orders (codemp, sucursal, numero, fecha, fecha_need, fecha_ship, fecha_repl, fecha_rece, fecha_comi, fecha_u, proveedor, cliente, referencia, tracking, envio_prioridad, numero_item, total_precio, moneda, usuario_sistema, estatus, diferido, estado, fecha_sync, tipo_sync)
			values (_codemp, _sucursal, _numero, @fecha, @fecha_need, @fecha_ship, @fecha_repl, @fecha_rece, @fecha_comi, @fecha_u, _proveedor, _cliente, _referencia, _tracking, _envio_prioridad, _numero_item, _total_precio, _moneda, _usuario_sistema, _estatus, @diferido, @estado, curdate(), 1) ;
	else
		set @tipo = 2 ;
		update tb_c_opurchase_orders
			set 
				fecha_need = @fecha_need, 
                fecha_ship = @fecha_ship, 
                fecha_repl = @fecha_repl, 
                fecha_rece = @fecha_rece, 
                fecha_comi = @fecha_comi, 
                fecha_u = @fecha_u, 
                proveedor = _proveedor, 
                cliente = _cliente, 
                referencia = _referencia, 
                tracking = _tracking, 
                envio_prioridad = _envio_prioridad, 
                numero_item = _numero_item, 
                total_precio = _total_precio, 
                moneda = _moneda, 
                usuario_sistema = _usuario_sistema, 
                estatus = _estatus, 
                estatus = @estatus, 
                estado = @estado, 
                fecha_sync = curdate(), 
                tipo_sync = 2
			where codemp = _codemp 
				and sucursal = _sucursal
				and numero = _numero;
	end if;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_elimina_codigo` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_elimina_codigo`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _parametro varchar(255), 
	in _tabla varchar(255)
)
begin
	-- --------------------------------------------------
	-- procedimiento genérico que elimina registros
	-- Versión 1.0
	-- Creado: 21/07/2014
	-- Actualizado: 2024.04.13, 27/10/2014
	-- Autor: 
	-- --------------------------------------------------
   if (_codemp is null) OR (_sucursal is null) or (_tabla is null) or (_parametro is null) then
        signal sqlstate '45000'
            set message_text = 'Parámetros incompletos. Todos los campos deben estar especificados.';
    end if ;
	set @sql_where = concat('delete from ', trim(_tabla),' where codemp = ', _codemp) ;
    set @sql_where = if(trim(coalesce(_sucursal, '')) <> '', concat(@sql_where, ' and sucursal = ', _sucursal), @sql_where) ;
    set @sql_where = concat(@sql_where, ' and codigo = ', _parametro, ' and estado = 1 ');
	
    begin
		declare exit handler for sqlexception
        begin
            -- Manejo de errores de consulta
            rollback;
            select 'Error al ejecutar la consulta: ' || SQLERRM;
        end;
        
		prepare sql_tabla from @sql_where;
		execute sql_tabla ;
		deallocate prepare sql_tabla ;
	end ;
    set @sql_where = null ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_elimina_musuario_grupo` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_elimina_musuario_grupo`(
	in _codemp varchar(2), 
    in _sucursal varchar(3), 
    in _parametro varchar(255), 
    in _tabla varchar(255)
)
begin
	-- ---------------------------------------------------
	-- procedimiento genérico que elimina registros
	-- Versión 1.0
	-- Actualizado: 2024.04.13, 21/07/2014
	-- Autor: 
	-- ---------------------------------------------------
   if (_codemp is null) OR (_sucursal is null) or (_tabla is null) or (_parametro is null) then
        signal sqlstate '45000'
            set message_text = 'Parámetros incompletos. Todos los campos deben estar especificados.';
    end if ;
	set @sql_where = concat('delete from ', trim(_tabla),' where u201 = ', _parametro, ' and estado = 1 ');
    begin
		declare exit handler for sqlexception
        begin
            -- Manejo de errores de consulta
            rollback;
            select 'Error al ejecutar la consulta: ' || SQLERRM;
        end;
        
		prepare sql_tabla from @sql_where;
		execute sql_tabla ;
		deallocate prepare sql_tabla ;
	end ;
    set @sql_where = null ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_elimina_numero` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_elimina_numero`(
	in _codemp varchar(2), 
    in _sucursal varchar(3), 
    in _parametro varchar(255), 
    in _tabla varchar(255)
)
begin
	-- ---------------------------------------------------
	-- procedimiento genérico que elimina registros
	-- Versión 1.0
	-- Creado: 21/07/2014
	-- Actualizado: 2024.04.13, 27/10/2014
	-- Autor: 
	-- ---------------------------------------------------
   if (_codemp is null) OR (_sucursal is null) or (_tabla is null) or (_parametro is null) then
        signal sqlstate '45000'
            set message_text = 'Parámetros incompletos. Todos los campos deben estar especificados.';
    end if ;
	set @sql_where = concat('delete from ', trim(_tabla),' where codemp = ', _codemp) ;
    set @sql_where = if(trim(coalesce(_sucursal, '')) <> '', concact(@sql_where, ' and sucursal = ', _sucursal), @sql_where);
    set @sql_where = concat(@sql_where, ' and numero = ', _parametro, ' and estado = 1 ');

    begin
		declare exit handler for sqlexception
        begin
            -- Manejo de errores de consulta
            rollback;
            select 'Error al ejecutar la consulta: ' || SQLERRM;
        end;
        
		prepare sql_tabla from @sql_where;
		execute sql_tabla ;
		deallocate prepare sql_tabla ;
	end ;
    set @sql_where = null ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_estado_l` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_estado_l`(
	in _tipo varchar(3), 
    in _codigo int(3)
)
begin
	-- ------------------------------------------
	-- consulta del maestro de estados, 
	-- de acuerdo al tipo, para crear la lista
	-- desplegable.
	-- V 1.0
	-- Actualizado 06/05/2014
	-- Autor: 
	-- -------------------------------------------
	
	drop temporary table if exists a0 ;
	create temporary table a0
		select codigo, nombre
			from cfg_mestado
			where tipo = _tipo
				and codigo = _codigo 
				and _codigo > 0
		union
		select codigo, nombre
			from cfg_mestado
			where tipo = _tipo
				and codigo <> _codigo 
				and _codigo = 0 ;

	select *
		from a0
		order by codigo ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_f_mcustomers_group_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_f_mcustomers_group_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _status varchar(1), 
	in _parametro varchar(255), 
	in _tabla varchar(255), 
	in _tipo varchar(3)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Consulta generica de los datos para los formularios
		Versión 1.0
		Creado: 2025-09-26
		Actualizado: 2025-09-26
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
	
	if (_codemp is null) OR (_sucursal is null) or (_tabla is null) or (_parametro is null) then
        signal sqlstate '45000'
            set message_text = 'Parámetros incompletos. Todos los campos deben estar especificados.';
    end if ;
	set @sql_where = concat(' where codemp = ', _codemp, ' and estado <> 0');
	if trim(_sucursal) <> '' then
		set @sql_where = concat(@sql_where, ' and sucursal = ', _sucursal);
	end if;
	if trim(coalesce(_parametro, '')) <> '' then
		set @sql_where = concat(@sql_where, ' and codigo = "', trim(_parametro), '"');
	end if;

	set @sql_where = concat('create temporary table sentencia select * from ', trim(_tabla), @sql_where);
    begin
		declare exit handler for sqlexception
        begin
            -- Manejo de errores de consulta
            rollback;
            select 'Error al ejecutar la consulta: ' || SQLERRM;
        end;
        
		prepare sentencia from @sql_where;
		execute sentencia ;
		deallocate prepare sentencia ;
	end ;
    set @sql_where = null ;
    
    -- ----------------------------------------------------------------------------------------------------
	select	sentencia.*,
			coalesce(tb_musuario.u202, '') as nusuario,
			coalesce(cfg_mestado.nombre, '') as nestado,
			coalesce(cfg_mestado.clase_css, '') as nestado_clase_css,
			coalesce(cfg_mestado.img_icon, '') as nestado_img_icon
		from sentencia
			left join tb_musuario
				on sentencia.usuario = tb_musuario.u201
            left join cfg_mestado 
				on sentencia.codemp = cfg_mestado.codemp
					and sentencia.estado = cfg_mestado.codigo 
					and cfg_mestado.tipo = trim(_tipo) ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_f_mcustomers_group_d_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_f_mcustomers_group_d_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
    in _modo smallint(1),
	in _codigo varchar(15),
    in _usuario varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Consulta generica de los datos para los formularios
		Versión 1.0
		Creado: 2025-09-26
		Actualizado: 2025-09-26
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
   	drop temporary table if exists a1 ;
	create temporary table a1
		select 	*, 
                1 as marca
			from tb_f_mcustomers_group_d
			where codemp = _codemp
				and sucursal = _sucursal
				and codigo = _codigo ;
	
    drop temporary table if exists a2 ;
    create temporary table a2
		select	codemp, 
				sucursal, 
                _codigo as codigo,
                codigo as cliente,
                0 as marca,
                0 as item
			from tb_f_mcustomers
            where codemp = _codemp
				and sucursal = _sucursal
                and _modo <> 0
				and codigo not in (select cliente from a1) ;
	
    drop temporary table if exists a3 ;
    create temporary table a3
		select codemp, sucursal, codigo, cliente, marca, item from a1 
			union select codemp, sucursal, codigo, cliente, marca, item from a2 ;
    
    -- ----------------------------------------------------------------------------------------------------
	select	a3.*,
			coalesce(tb_f_mcustomers.nombre, '') as ncliente
		from a3
			left join tb_f_mcustomers
				on a3.codemp = tb_f_mcustomers.codemp
					and a3.sucursal = tb_f_mcustomers.sucursal
                    and a3.cliente = tb_f_mcustomers.codigo
		order by a3.marca desc, tb_f_mcustomers.nombre ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_f_mcustomers_group_d_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_f_mcustomers_group_d_u`(
	in _codemp varchar(2),
    in _sucursal varchar(3),
    in _codigo varchar(15),
	in json_data JSON
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Actualiza el detalle con los cliente asociados al grupo para los usuarios
		Versión 1.0
		Creado: 2025-09-26
		Actualizado: 2025-09-27
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
	
    drop temporary table if exists a0 ;
    create temporary table a0
		SELECT	_codemp as codemp, _sucursal as sucursal, _codigo as codigo,
				cliente,
				marca,
				item
			FROM JSON_TABLE(
					json_data,
					'$.*'
					COLUMNS(
						cliente VARCHAR(20) PATH '$.cliente',
						marca integer(1) PATH '$.marca',
						item integer(5) PATH '$.item'
					)
				) AS jt
			where (coalesce(marca, 0) + coalesce(item, 0)) > 0 ;
            
	-- ------------------------------------------------------------------------------------------------------------------------
	insert into tb_f_mcustomers_group_d (codemp, sucursal, codigo, cliente)
		select codemp, sucursal, codigo, cliente 
			from a0
			where marca = 1 and item = 0 ;
	
    -- ------------------------------------------------------------------------------------------------------------------------
    delete tb_f_mcustomers_group_d
		from tb_f_mcustomers_group_d
			inner join a0
				on tb_f_mcustomers_group_d.item = a0.item 
					and a0.marca = 0 ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_f_mcustomers_group_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_f_mcustomers_group_u`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
	in _usuario varchar(10),
	in _formulario int,
	in _codigo varchar(10),
    in _nombre varchar(120),
    in _estado varchar(1),
	out _valor varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Actualiza los datos del maestro del grupo
		Versión 1.0
		Creado: 2025-09-26
		Actualizado: 2025-09-26
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
    set @tipo = 1 ;
	if trim(_codigo) = '' then
		call sp_tdocumento_u(concat(_codemp, _sucursal, 'tb_f_mcustomers_group'), 5, 1, @codigo);
		set _codigo = concat(_codemp, _sucursal, @codigo);
		insert into tb_f_mcustomers_group (codemp, sucursal, codigo, nombre, usuario, estado)
			values (_codemp, _sucursal, _codigo, _nombre, _usuario, 1 );
	else
		set @tipo = 2 ;
		update tb_f_mcustomers_group 
			set
				nombre = _nombre,
                usuario = case when coalesce(usuario, '') = '' then _usuario else usuario end,
                estado = _estado
			where codemp = _codemp 
				and sucursal = _sucursal
				and codigo = _codigo;
	end if;
    
    call sp_s_log_u(_codemp, _sucursal, _formulario, _usuario, _codigo, @tipo, '','','','','','','','','','','') ;
	set _valor = _codigo;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_f_mcustomers_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_f_mcustomers_u`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
	in _usuario varchar(10),
	-- in _formulario int,
	in _codigo varchar(10),
    in _nombre varchar(120),
    in _telefono varchar(30),
    in _pais varchar(70), 
    in _estado_ciudad varchar(70), 
    in _ciudad varchar(70), 
    in _zcode varchar(10), 
    in _direccion varchar(500),
    in _fecha_r varchar(25),
    in _fecha_u varchar(25)
    -- in _estado varchar(3)
    -- out _valor varchar(15)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Actualiza los datos del maestro de cliente
		Versión 1.0
		Creado: 2025-08-29
		Actualizado: 2025-09-10
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    set @tipo = 1 ;
    set @pais = coalesce(_pais, '') ;
    set @estado_ciudad = coalesce(_estado_ciudad, '');
    set @ciudad = coalesce(_ciudad, '');
    
    set @fecha_r = substring(Trim(_fecha_r),1, 10) ;
    set @fecha_u = substring(Trim(_fecha_u),1, 10) ;
    /*
	delete 
		from tb_f_mcustomers
        where codemp = _codemp
			and sucursal = _sucursal
			and trim(codigo) = _codigo ;
	
    insert into tb_f_mcustomers (codemp, sucursal, codigo, nombre, pais, estado_ciudad, ciudad, zcode, telefono, direccion, fecha_r, fecha_u, usuario, estado, fecha_sync, tipo_sync)
			values (_codemp, _sucursal, _codigo, _nombre, @pais, @estado_ciudad, @ciudad, _zcode, _telefono, _direccion, @fecha_r, @fecha_u, _usuario, 1, curdate(), 1 );
	*/
    
    select count(codigo) into @existe
		from tb_f_mcustomers
        where codemp = _codemp
			and sucursal = _sucursal
			and trim(codigo) = _codigo ;
    
	if (@existe = 0) then
        insert into tb_f_mcustomers (codemp, sucursal, codigo, nombre, pais, estado_ciudad, ciudad, zcode, telefono, direccion, fecha_r, fecha_u, usuario, estado, fecha_sync, tipo_sync)
			values (_codemp, _sucursal, _codigo, _nombre, @pais, @estado_ciudad, @ciudad, _zcode, _telefono, _direccion, @fecha_r, @fecha_u, _usuario, 1, curdate(), 1 );
	
    else
		set @tipo = 2 ;
		update tb_f_mcustomers
			set
				nombre = _nombre,
                pais = @pais,
				estado_ciudad = @estado_ciudad,
				ciudad = @ciudad, 
				zcode = _zcode, 
                telefono = _telefono,
                direccion = _direccion,
                fecha_u = @fecha_u,
                usuario = case when coalesce(usuario, '') = '' then _usuario else usuario end, 
                fecha_sync = curdate(), 
                tipo_sync = 2
			where codemp = _codemp 
				and sucursal = _sucursal
				and codigo = _codigo;
	end if;
    
    -- call sp_s_log_u(_codemp, _sucursal, _formulario, _usuario, _codigo, @tipo, '','','','','','','','','','','') ;
    
	-- set _valor = _codigo;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_f_mcustomers_u_sync` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_f_mcustomers_u_sync`(
	in _codemp varchar(2), 
	in _sucursal varchar(3)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Actualiza los datos del maestro de cliente desde las Sales Orden
		Versión 1.0
		Creado: 2025-09-10
		Actualizado: 2025-09-10
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
    drop temporary table if exists c0 ;
	create temporary table c0
		select	codemp, sucursal, cliente
			from tb_f_osales_orders
			where codemp = _codemp
				and sucursal = _sucursal 
				and cliente not in (select codigo from tb_f_mcustomers where codemp = _codemp and sucursal = _sucursal)
			group by codemp, sucursal, cliente ;
	
    -- ----------------------------------------------------------------------------------------------------
    drop temporary table if exists c1 ;
    create temporary table c1
		select	tb_c_mvendors.codemp, tb_c_mvendors.sucursal, tb_c_mvendors.codigo, 
				tb_c_mvendors.nombre, tb_c_mvendors.referencia, tb_c_mvendors.contacto, 
                tb_c_mvendors.pais, tb_c_mvendors.estado_ciudad, tb_c_mvendors.ciudad, 
                tb_c_mvendors.zcode, tb_c_mvendors.web, tb_c_mvendors.email, tb_c_mvendors.telefono, 
                tb_c_mvendors.direccion, tb_c_mvendors.nota, tb_c_mvendors.fecha_r, tb_c_mvendors.fecha_u, 
                tb_c_mvendors.usuario, tb_c_mvendors.estado
			from tb_c_mvendors
				inner join c0
					on tb_c_mvendors.codemp = c0.codemp
						and tb_c_mvendors.sucursal = c0.sucursal
                        and tb_c_mvendors.codigo = c0.cliente ;
	
    -- ----------------------------------------------------------------------------------------------------
    insert into tb_f_mcustomers (codemp, sucursal, codigo, nombre, referencia, contacto, pais, estado_ciudad, ciudad, zcode, web, email, telefono, direccion, nota, fecha_r, fecha_u, usuario, estado, fecha_sync, tipo_sync)
		select	codemp, sucursal, codigo, nombre, referencia, contacto, pais, estado_ciudad, ciudad, zcode, web, email, telefono, direccion, nota, fecha_r, fecha_u, usuario, estado, curdate(), 3
			from c1
            order by codemp, sucursal, codigo ;
    
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_f_osales_orders_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_f_osales_orders_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _status varchar(1), 
	in _parametro varchar(255), 
	in _tabla varchar(255), 
	in _tipo varchar(3)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Consulta generica de los datos para los formularios
		Versión 1.0
		Creado: 2025-08-30
		Actualizado: 202508-30
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
	
	if (_codemp is null) OR (_sucursal is null) or (_tabla is null) or (_parametro is null) then
        signal sqlstate '45000'
            set message_text = 'Parámetros incompletos. Todos los campos deben estar especificados.';
    end if ;
	set @sql_where = concat(' where codemp = ', _codemp, ' and estado <> 0');
	if trim(_sucursal) <> '' then
		set @sql_where = concat(@sql_where, ' and sucursal = ', _sucursal);
	end if;
	if trim(coalesce(_parametro, '')) <> '' then
		set @sql_where = concat(@sql_where, ' and numero = "', trim(_parametro), '"');
	end if;

	set @sql_where = concat('create temporary table sentencia select * from ', trim(_tabla), @sql_where);
    begin
		declare exit handler for sqlexception
        begin
            -- Manejo de errores de consulta
            rollback;
            select 'Error al ejecutar la consulta: ' || SQLERRM;
        end;
        
		prepare sentencia from @sql_where;
		execute sentencia ;
		deallocate prepare sentencia ;
	end ;
    set @sql_where = null ;
    
    -- ----------------------------------------------------------------------------------------------------
	select	sentencia.*,
			coalesce(tb_f_mcustomers.nombre, '') as ncustomer,
			coalesce(cfg_mestado.nombre, '') as nestado,
			coalesce(cfg_mestado.clase_css, '') as nestado_clase_css,
			coalesce(cfg_mestado.img_icon, '') as nestado_img_icon
		from sentencia
			left join tb_f_mcustomers
				on sentencia.codemp = tb_f_mcustomers.codemp
					and sentencia.sucursal = tb_f_mcustomers.sucursal
					and sentencia.cliente = tb_f_mcustomers.codigo
            left join cfg_mestado 
				on sentencia.codemp = cfg_mestado.codemp
					and sentencia.estado = cfg_mestado.codigo 
					and cfg_mestado.tipo = trim(_tipo) ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_f_osales_orders_d_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_f_osales_orders_d_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
    in _modo smallint(1),
	in _numero varchar(15),
    in _usuario varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Consulta generica de los datos para los formularios
		Versión 1.0
		Creado: 2025-08-31
		Actualizado: 2025-08-31
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
	select	tb_f_osales_dproducts.*,
			coalesce(tb_a_mproducts.nombre, '') as nproducto,
			round(tb_f_osales_dproducts.precio_venta * tb_f_osales_dproducts.cantidad_ord, 2) total_ord,
            round(tb_f_osales_dproducts.precio_venta * tb_f_osales_dproducts.cantidad_env, 2) total_ent
		from tb_f_osales_dproducts
			left join tb_a_mproducts
				on tb_f_osales_dproducts.codemp = tb_a_mproducts.codemp
					and tb_f_osales_dproducts.sucursal = tb_a_mproducts.sucursal
					and tb_f_osales_dproducts.producto = tb_a_mproducts.codigo
		where tb_f_osales_dproducts.codemp = _codemp
			and tb_f_osales_dproducts.sucursal = _sucursal
            and tb_f_osales_dproducts.numero = _numero 
		order by tb_f_osales_dproducts.producto ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_f_osales_orders_d_del` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_f_osales_orders_d_del`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
	in _numero varchar(15)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Actualiza los datos del maestro de cliente
		Versión 1.0
		Creado: 2025-08-30
		Actualizado: 2025-08-30
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
	
    delete from tb_f_osales_dproducts
		where codemp = _codemp 
			and sucursal = _sucursal
			and numero = _numero ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_f_osales_orders_d_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_f_osales_orders_d_u`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
	in _usuario varchar(10),
	in _numero varchar(15),
	in _producto varchar(100), 
    in _descripcion varchar(250),
    in _descuento_p decimal(6,2), 
    in _precio_lista decimal(10,2), 
    in _cantidad_fac decimal(10,2), 
    in _cantidad_ord decimal(10,2), 
    in _cantidad_res decimal(10,2), 
    in _cantidad_env decimal(10,2), 
    in _fecha_ent varchar(10), 
    in _fecha_req varchar(10), 
    in _fecha_pfe varchar(10), 
    in _nota  varchar(500), 
    in _nuevo_usado  varchar(15), 
    in _precio_venta decimal(10, 2), 
    in _fecha_env  varchar(10), 
    in _impuesto_monto decimal(6,2), 
    in _costo_unitario decimal(10,2), 
    in _unidad_medida varchar(15),
    in _invoice varchar(25),
    in _fecha_invoice varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Actualiza los datos del maestro de cliente
		Versión 1.0
		Creado: 2025-08-30
		Actualizado: 2025-09-12
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
	
    set @fecha_ent = substring(Trim(_fecha_ent), 1, 10) ;
    set @fecha_req = substring(Trim(_fecha_req), 1, 10) ;
    set @fecha_pfe = substring(Trim(_fecha_pfe), 1, 10) ;
    set @fecha_env = substring(Trim(_fecha_env), 1, 10) ;
    set @fecha_fac = substring(Trim(_fecha_invoice), 1, 10) ;
    
	insert into tb_f_osales_dproducts (codemp, sucursal, numero, producto, nombre, descuento_p, precio_lista, cantidad_fac, cantidad_ord, cantidad_res, cantidad_env, fecha_ent, fecha_req, fecha_pfe, nota, nuevo_usado, precio_venta, fecha_env, impuesto_monto, costo_unitario, unidad_medida, invoice, fecha_invoice, fecha_sync, tipo_sync)
		value (_codemp, _sucursal, _numero, _producto, _descripcion, _descuento_p, _precio_lista, _cantidad_fac, _cantidad_ord, _cantidad_res, _cantidad_env, @fecha_ent, @fecha_req, @fecha_pfe, _nota, _nuevo_usado, _precio_venta, @fecha_env, _impuesto_monto, _costo_unitario, _unidad_medida, _invoice, @fecha_fac, curdate(), 1) ;
	
    set @existe = 0 ;
    select count(codigo) into @existe
		from tb_a_mproducts
        where codemp = _codemp
			and sucursal = _sucursal
            and codigo = _producto ;
	
   if (@existe = 0) then
		insert into tb_a_mproducts (codemp, sucursal, codigo, nombre, stock_disponible, stock_reserv, stock_enmano, stock_existencia, estado, fecha_sync, tipo_sync) 
			values (_codemp, _sucursal, _producto, _descripcion, 0, 0, 0, 0, 1, curdate(), 4) ;
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_f_osales_orders_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_f_osales_orders_u`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
	in _usuario varchar(10),
	in _numero varchar(15),
	in _fecha varchar(25),
    in _fecha_v varchar(25),
    in _fecha_r varchar(25),
    in _fecha_u varchar(25),
    in _estatus varchar(25),
    in _cliente varchar(120),
    in _total_precio decimal(10,2),
    in _envio_nombre varchar(100),
    in _envio_pais varchar(70), 
    in _envio_estado_ciudad varchar(70), 
    in _envio_ciudad varchar(70), 
    in _envio_zcode varchar(10), 
    in _envio_direccion varchar(250),
    in _envio_completo_req varchar(1),
    in _envio_prioridad varchar(45),
    in _vendedor varchar(120),
    in _referencia varchar(45),
    in _bill_name varchar(100),
	in _moneda varchar(5),
    in _usuario_sistema varchar(45),
    in _numero_item smallint(3) 
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Actualiza los datos del maestro de cliente
		Versión 1.0
		Creado: 2025-08-30
		Actualizado: 2025-09-09
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
	
    set @fecha = substring(Trim(_fecha),1, 10) ;
    set @fecha_v = substring(Trim(_fecha_v),1, 10) ;
    set @fecha_r = substring(Trim(_fecha_r),1, 10) ;
    set @fecha_u = substring(Trim(_fecha_u),1, 10) ;
    set @envio_completo_req = case when coalesce(_envio_completo_req, '') = '' then '0' else '1' end ;
    set @estado = case 
						when substring(_estatus, 1, 3) = 'OPE' then 1
						when substring(_estatus, 1, 3) = 'CAN' then 2
						when substring(_estatus, 1, 3) = 'CLO' then 3
						else 1
					end ;
	select count(numero) into @existe
		from tb_f_osales_orders
        where trim(numero) = _numero ;
	
	if (@existe = 0) then
		insert into tb_f_osales_orders (codemp, sucursal, numero, fecha, fecha_v, fecha_r, fecha_u, cliente, purchase, numero_documento, tracking, numero_item, total_precio, envio_nombre, envio_pais, envio_estado_ciudad, envio_ciudad, envio_zcode, envio_direccion, envio_completo_req, envio_prioridad, vendedor, usuario_sistema, referencia, bill_name, moneda, estatus, estado, fecha_sync, tipo_sync )
			values (_codemp, _sucursal, _numero, @fecha, @fecha_v, @fecha_r, @fecha_u, _cliente, '', '', '', _numero_item, _total_precio, _envio_nombre, _envio_pais, _envio_estado_ciudad, _envio_ciudad, _envio_zcode, _envio_direccion, @envio_completo_req, _envio_prioridad, _vendedor, _usuario_sistema, _referencia, _bill_name, _moneda, _estatus, @estado, curdate(), 1) ;
	else
		set @tipo = 2 ;
		update tb_f_osales_orders
			set fecha_v = @fecha_v, 
				fecha_r = @fecha_r,
                fecha_u = @fecha_u, 
                cliente = _cliente,
                numero_item = _numero_item, 
                total_precio = _total_precio, 
                envio_nombre = _envio_nombre, 
                envio_pais = _envio_pais, 
                envio_estado_ciudad = _envio_estado_ciudad, 
                envio_ciudad = _envio_ciudad, 
                envio_zcode = _envio_zcode,
                envio_direccion = _envio_direccion, 
                envio_completo_req = @envio_completo_req, 
                envio_prioridad = _envio_prioridad, 
                vendedor = _vendedor, 
                usuario_sistema = _usuario_sistema,
                estatus = _estatus,
                estado = @estado,
                referencia = _referencia,
                bill_name = _bill_name,
                moneda = _moneda,
                fecha_sync = curdate(),
                tipo_sync = 2
			where codemp = _codemp 
				and sucursal = _sucursal
				and numero = _numero;
	end if;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_f_osales_order_estatus_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_f_osales_order_estatus_u`(
	in _codemp varchar(2),
    in _sucursal varchar(3),
	in _usuario varchar(10),
	in _formulario int,
    in _numero varchar(15),
	in _estado varchar(1)
    
)
begin
	/* ----------------------------------------------------------------------------------------------------
		SP para cambiar el estatus del timesheet a: 3- Enviado, 4- Aprovado, 1- Reversado a Activo
		Versión 1.0
		Creado: 2025-09-15
		Actualizado: 2025-09-15
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    set @tipo = _estado ;
	
    -- ----------------------------------------------------------------------------------------------------
	update tb_f_osales_orders
		set
			ocultar = _estado
		where codemp = _codemp
			and sucursal = _sucursal
			and numero = _numero ;
	
    call sp_s_log_u(_codemp, _sucursal, _formulario, _usuario, _numero, @tipo, '','','','','','','','','','','');
    -- Falta generar la actualizacion para el balance, el cual permitira generar los cheques de pago
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_general_codigo_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_general_codigo_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _status varchar(1), 
    in _parametro varchar(255), 
    in _tabla varchar(255), 
    in _tipo varchar(3)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Consulta generica de los datos para los formularios
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2024.12.29
		Autor: 
	---------------------------------------------------------------------------------------------------- */
	if (_codemp is not null) OR (_sucursal is not null) or (_tabla is not null) or (_parametro is not null) then
		set @sql_where = concat(' where codemp = ', _codemp, ' and estado <> 0');
		if trim(_sucursal) <> '' then
			set @sql_where = concat(@sql_where, ' and sucursal = ', _sucursal);
		end if;
		if trim(coalesce(_parametro, '')) <> '' then
			set @sql_where = concat(@sql_where, ' and codigo = "', trim(_parametro), '"');
		end if;
		
		-- ----------------------------------------------------
		call sql_prepare(trim(_tabla), @sql_where) ;
		set @sql_where = null ;
		
		-- ----------------------------------------------------
		select	sql_tabla.*,
				coalesce(cfg_mestado.nombre, '') as nestado,
				coalesce(cfg_mestado.clase_css, '') as nestado_clase_css,
				coalesce(cfg_mestado.img_icon, '') as nestado_img_icon
			from sql_tabla
				inner join cfg_mestado 
					on sql_tabla.codemp = cfg_mestado.codemp
						and sql_tabla.estado = cfg_mestado.codigo 
						and cfg_mestado.tipo = trim(_tipo) ;
	else
		select -1 ;
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_general_mdetalle_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_general_mdetalle_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _status varchar(1), 
	in _parametro varchar(255), 
	in _tabla varchar(255), 
	in _tipo varchar(3)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Consulta generica de los datos para los formularios
		Creado: 2024.05.10
		Actualizado: 2024.05.10
		Autor: 
	---------------------------------------------------------------------------------------------------- */
   if (_codemp is null) OR (_sucursal is null) or (_tabla is null) or (_parametro is null) then
        signal sqlstate '45000'
            set message_text = 'Parámetros incompletos. Todos los campos deben estar especificados.';
    end if ;
	
	set @cadena = concat(' where estado <> 0');
	if trim(coalesce(_parametro, '')) <> '' then
		set @cadena = concat(@cadena, ' and u201 = ', trim(_parametro));
	end if ;
	
	drop temporary table if exists a1 ;
	set @cSentencia = concat('create temporary table a1 select * from ', trim(_tabla), @cadena);
	prepare sentencia from @cSentencia ;
	execute sentencia ;
	deallocate prepare sentencia ;
	
	select	a1.*
		from a1
        order by nombre ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_general_numero_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_general_numero_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _status varchar(1), 
	in _parametro varchar(255), 
	in _tabla varchar(255), 
	in _tipo varchar(3)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Consulta generica de los datos para los formularios
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2025.01.24
		Autor: 
	---------------------------------------------------------------------------------------------------- */
    
   if (_codemp is null) OR (_sucursal is null) or (_tabla is null) or (_parametro is null) then
        signal sqlstate '45000'
            set message_text = 'Parámetros incompletos. Todos los campos deben estar especificados.';
    end if ;
	set @sql_where = concat(' where codemp = ', _codemp, ' and estado <> 0');
	if trim(_sucursal) <> '' then
		set @sql_where = concat(@sql_where, ' and sucursal = ', _sucursal);
	end if;
	if trim(coalesce(_parametro, '')) <> '' then
		set @sql_where = concat(@sql_where, ' and numero = "', trim(_parametro), '"');
	end if;

	set @sql_where = concat('create temporary table sql_tabla select * from ', trim(_tabla), @sql_where);
    begin
		declare exit handler for sqlexception
        begin
            -- Manejo de errores de consulta
            rollback;
            select 'Error al ejecutar la consulta: ' || SQLERRM;
        end;
        
		prepare sql_tabla from @sql_where;
		execute sql_tabla ;
		deallocate prepare sql_tabla ;
	end ;
    set @sql_where = null ;
    
    -- ----------------------------------------------------------------------------------------------------
	select	sql_tabla.*,
			coalesce(tb_musuario.u202, '') as nusuario,
			coalesce(cfg_mestado.nombre, '') as nestado,
			coalesce(cfg_mestado.clase_css, '') as nestado_clase_css,
			coalesce(cfg_mestado.img_icon, '') as nestado_img_icon
		from sql_tabla
			left join tb_musuario 
					on tb_musuario.u201 = coalesce(sql_tabla.usuario,'')
            left join cfg_mestado 
				on sql_tabla.codemp = cfg_mestado.codemp
					and sql_tabla.estado = cfg_mestado.codigo 
					and cfg_mestado.tipo = trim(_tipo) ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_gen_eliminar_codigo` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_gen_eliminar_codigo`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _parametro varchar(255),
	in _tabla varchar(100)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Procedimiento genérico que elimina o anula registros
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2024.12.27, 2025.01.24
		Autor: 
	---------------------------------------------------------------------------------------------------- */
    
	if (_codemp is not null) and (_sucursal is not null) and (_tabla is not null) and (_parametro is not null) then
		set @sql_where = concat('delete from ', trim(_tabla), ' where codemp = ', _codemp);
        set @sucursal = case when coalesce(_sucursal, '') <> '' then concat(' and sucursal = ', _sucursal) else '' end ;
		set @sql_where = concat(@sql_where, @sucursal, ' and codigo = ', _parametro, ' ;');	
		
		prepare sql_tabla from @sql_where;
		execute sql_tabla ;
		deallocate prepare sql_tabla ;
        set @sql_where = null ;
    else
		select -1 ;
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_gen_eliminar_numero` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_gen_eliminar_numero`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _parametro varchar(255),
	in _tabla varchar(100))
begin
	/* ----------------------------------------------------------------------------------------------------
		Procedimiento genérico que elimina o anula registros
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2024.12.27, 2025.01.24
		Autor: 
	---------------------------------------------------------------------------------------------------- */
	if (_codemp is not null) OR (_sucursal is not null) or (_tabla is not null) or (_parametro is not null) then
		set @sql_where = concat('delete from ', trim(_tabla), ' where codemp = ', _codemp);
		set @sql_where = if(trim(coalesce(_sucursal, '')) <> '', concat(@sql_where, ' and sucursal = ', _sucursal), @sql_where);
		set @sql_where = concat(@sql_where, ' and numero = ', _parametro, ' and estado = 1 ');	
		
		prepare sql_tabla from @sql_where;
		execute sql_tabla ;
		deallocate prepare sql_tabla ;
        set @sql_where = null ;
    else
		select -1 ;
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_g_documento_dgaleria_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_g_documento_dgaleria_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _numero varchar(15),
    in _formulario int
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Consulta los archivos de la galeria del timesheet
		Versión 1.0
		Creado: 2025-02-11
		Actualizado: 2025-07-06
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
	select	*
		from tb_g_documentos_galeria
		where codemp = _codemp
			and sucursal = _sucursal
            and numero = _numero
            and case _formulario 
						when 18 then ((formulario = 18) or (formulario = 37))
                        when 37 then ((formulario = 18) or (formulario = 37))
					end
		order by tipo_archivo, titulo, descripcion, archivo ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_g_documento_dgaleria_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_g_documento_dgaleria_u`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
	in _usuario varchar(10),
	in _formulario int,
	in _numero varchar(15),
    in _archivo varchar(200),
    in _tipo_archivo varchar(5),
    in _descripcion varchar(100),
    in _tipo int
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Actualiza (I/U/D) de los archivos de la galeria del timesheet
		Versión 1.0
		Creado: 2025-02-11
		Actualizado: 2025-07-06
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    set @archivo = coalesce(_archivo, '') COLLATE utf8mb4_spanish_ci ;
	if coalesce(_tipo, 0) = 1 then
		insert into tb_g_documentos_galeria (codemp, sucursal, numero, archivo, archivo_original, titulo, fecha, descripcion, ancho_minimo, tipo_archivo, categoria, formulario)
			select _codemp, _sucursal, _numero, @archivo, '', '', curdate(), _descripcion, 0, _tipo_archivo, '', _formulario ;
	
    elseif coalesce(_tipo, 0) = 2 then
		update tb_g_documentos_galeria
			set 
				descripcion = _descripcion
			where codemp = _codemp
				and sucursal = _sucursal
                and numero = _numero
                and archivo COLLATE utf8mb4_spanish_ci = @archivo ;
	
    elseif coalesce(_tipo, 0) = 3 then
		delete
			from tb_g_documentos_galeria
            where codemp = _codemp
				and sucursal = _sucursal
                and numero = _numero
                and archivo COLLATE utf8mb4_spanish_ci = @archivo ;
                
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_g_mnotificacion_dformulario_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_g_mnotificacion_dformulario_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),     
    in _modo smallint(1),
	in _codigo varchar(15)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Consulta los tipo de rol o tareas que realiza una persona
		Versión 1.0
		Creado: 2025-07-08
		Actualizado: 2025-07-08
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
	
   	drop temporary table if exists a1 ;
	create temporary table a1
		select 	codemp, sucursal, codigo, formulario, 1 as marca, item
			from tb_g_mnotificacion_dformulario 
			where codemp = _codemp
				and sucursal = _sucursal
				and codigo = _codigo ;
	
    drop temporary table if exists a2 ;
    create temporary table a2
		select	_codemp as codemp, 
				_sucursal as sucursal, 
                _codigo as codigo, 
                formulario, 
                0 as marca,
                0 as item
			from cfg_lista_formularios
            where coalesce(notificaciones, 0) = 1
                and _modo <> 0
				and formulario not in (select formulario from a1) ;
	
    drop temporary table if exists a3 ;
    create temporary table a3
		select codemp, sucursal, codigo, formulario, marca, item from a1 
			union select codemp, sucursal, codigo, formulario, marca, item from a2 ;
    
    -- ----------------------------------------------------------------------------------------------------
	select	a3.*,
			coalesce(cfg_lista_formularios.titulo, '') as nformulario,
            coalesce(cfg_lista_formularios.etiqueta, '') as etiqueta
		from a3
			left join cfg_lista_formularios
				on a3.formulario = cfg_lista_formularios.formulario
		order by a3.marca desc, cfg_lista_formularios.modulo, cfg_lista_formularios.menu, cfg_lista_formularios.grupo, cfg_lista_formularios.orden  ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_g_mnotificacion_dformulario_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_g_mnotificacion_dformulario_u`(
	in _codemp varchar(2),
    in _sucursal varchar(3),
    in _codigo varchar(15),
    in _formulario int,
    in _marca int(1), 
	in _item int(11)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Actualiza los formularios a los que se aplicará la notificación
		Versión 1.0
		Creado: 2025-07-09
		Actualizado: 2025-07-09
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
    if _item = 0 and _marca = 1 then
		insert into tb_g_mnotificacion_dformulario (codemp, sucursal, codigo, formulario)
			select _codemp, _sucursal, _codigo, _formulario ;
                
    elseif _item != 0 and _marca = 0 then
		delete 
			from tb_g_mnotificacion_dformulario
            where codemp = _codemp 
				and sucursal = _sucursal 
				and item = _item ;
    end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_g_mnotificacion_dusuario_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_g_mnotificacion_dusuario_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),     
    in _modo smallint(1),
	in _codigo varchar(15)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Consulta los tipo de rol o tareas que realiza una persona
		Versión 1.0
		Creado: 2025-07-08
		Actualizado: 2025-07-08
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
	
   	drop temporary table if exists a1 ;
	create temporary table a1
		select 	codemp, sucursal, codigo, usuario, leida, 1 as marca, item
			from tb_g_mnotificacion_dusuario
			where codemp = _codemp
				and sucursal = _sucursal
				and codigo = _codigo ;
	
    drop temporary table if exists a2 ;
    create temporary table a2
		select	_codemp as codemp, 
				_sucursal as sucursal, 
                _codigo as codigo, 
                tb_musuario.u201 as usuario, 
                0 as leida, 
                0 as marca,
                0 as item
			from tb_musuario
				inner join tb_musuario_grupo
					on tb_musuario.u206 = tb_musuario_grupo.u201
						and tb_musuario_grupo.u224 = 1
            where coalesce(tb_musuario.u224, 0) = 0
                and _modo <> 0
				and tb_musuario.u201 not in (select usuario from a1) 
                and tb_musuario.estado = 1 ;
	
    drop temporary table if exists a3 ;
    create temporary table a3
		select codemp, sucursal, codigo, usuario, leida, marca, item from a1 
			union select codemp, sucursal, codigo, usuario, leida, marca, item from a2 ;
    
    -- ----------------------------------------------------------------------------------------------------
	select	a3.*,
			coalesce(tb_musuario.u202, '') as nusuario,
            coalesce(tb_f_mplantilla.nombre) as nplantilla
		from a3
			left join tb_musuario
				on a3.usuario = tb_musuario.u201
			left join tb_f_mplantilla
				on tb_f_mplantilla.codemp = _codemp
					and tb_f_mplantilla.sucursal = _sucursal
                    and tb_musuario.u218 = tb_f_mplantilla.codigo
		order by a3.marca desc, coalesce(tb_f_mplantilla.nombre), coalesce(tb_musuario.u202, '') ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_g_mnotificacion_dusuario_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_g_mnotificacion_dusuario_u`(
	in _codemp varchar(2),
    in _sucursal varchar(3),
    in _codigo varchar(15),
    in _usuario varchar(10),
    in _marca int(1), 
	in _item int(11)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Actualiza los usuario a los que se aplicará la notificación
		Versión 1.0
		Creado: 2025-07-09
		Actualizado: 2025-07-09
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
    if _item = 0 and _marca = 1 then
		insert into tb_g_mnotificacion_dusuario (codemp, sucursal, codigo, usuario, leida)
			value( _codemp, _sucursal, _codigo, _usuario, 0 );
                
    elseif _item != 0 and _marca = 0 then
		delete 
			from tb_g_mnotificacion_dusuario
            where codemp = _codemp 
				and sucursal = _sucursal 
				and item = _item ;
    end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_g_mnotificacion_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_g_mnotificacion_u`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
	in _usuario varchar(10),
	in _formulario int,
	in _codigo varchar(10),
    in _nombre varchar(100),
    in _plantilla varchar(15),
    in _cliente varchar(10),
    in _nota varchar(500),
    in _fecha varchar(10),
    in _fecha_u varchar(10),
    in _fecha_d varchar(10),
    in _fecha_h varchar(10),
    in _vence varchar(1),
    in _interno varchar(1),
	out _valor varchar(10)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Actualiza los datos del maestro de cliente
		Versión 1.0
		Creado: 2025-07-09
		Actualizado: 2025-07-09
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
	set @tipo = 1 ;
    set @fecha = coalesce(STR_TO_DATE(Trim(_fecha), '%m/%d/%Y'), curdate());
    set @fecha_u = coalesce(STR_TO_DATE(Trim(_fecha_u), '%m/%d/%Y'), curdate());
    set @fecha_d = coalesce(STR_TO_DATE(Trim(_fecha_d), '%m/%d/%Y'), curdate());
    set @fecha_h = coalesce(STR_TO_DATE(Trim(_fecha_h), '%m/%d/%Y'), curdate());
    set @vence = case when coalesce(_vence, '') = '' then 0 else _vence end ;
    set @interno = case when coalesce(_interno, '') = '' then 0 else _interno end ;
    set @estado = 1 ;
    
	if trim(_codigo) = '' then
		call sp_tdocumento_u(concat(_codemp, _sucursal, 'tb_g_mnotificacion'), 5, 1, @codigo);
		set _codigo = concat(_codemp, _sucursal, @codigo); 
		insert into tb_g_mnotificacion (codemp, sucursal, codigo, nombre, plantilla, cliente, nota, fecha, fecha_d, fecha_h, fecha_u, vence, interno, usuario, estado)
			select _codemp, _sucursal, _codigo, _nombre, _plantilla, _cliente, _nota, @fecha, @fecha_d, @fecha_h, @fecha_u, @vence, @interno, _usuario, @estado ;
	else
		set @tipo = 2 ;
		update tb_g_mnotificacion 
			set
				nombre = _nombre,
                plantilla = _plantilla, 
                cliente = _cliente, 
                nota = _nota, 
                fecha_d = @fecha_d, 
                fecha_h = @fecha_h, 
                fecha_u = @fecha_u, 
                vence = @vence, 
                interno = @interno, 
                usuario = case when coalesce(usuario, '') = '' then _usuario else usuario end
			where codemp = _codemp 
				and sucursal = _sucursal
				and codigo = _codigo;
	end if;
    call sp_s_log_u(_codemp, _sucursal, _formulario, _usuario, _codigo, @tipo, '','','','','','','','','','','') ;
	set _valor = _codigo; 
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_mempresa_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_mempresa_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _status varchar(1), 
	in _parametro varchar(1),
	in _tabla varchar(20),
	in _tipo varchar(3)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Consulta datos de la empresa
		Versión 1.0
		Creado: 14/05/2015
		Actualizado: 2024.04.13, 18/07/2018
		Autor: 
	---------------------------------------------------------------------------------------------------- */
	
	select	cfg_mempresa.codigo, 
			cfg_mempresa.nombre, 
            cfg_mempresa.nombre_comercial, 
            cfg_mempresa.siglas, 
            cfg_mempresa.pais, 
            cfg_mempresa.estado_provincia, 
            cfg_mempresa.ciudad, 
            cfg_mempresa.codigo_postal, 
            cfg_mempresa.web, 
            cfg_mempresa.email, 
            cfg_mempresa.telefonos, 
            cfg_mempresa.direccion, 
            cfg_mempresa.divisa, 
            coalesce(tb_g_mdivisa_b.nombre, '') as ndivisa,
            cfg_mempresa.moneda, 
            coalesce(tb_g_mdivisa_c.nombre, '') as nmoneda,
            cfg_mempresa.logo, 
            cfg_mempresa.id_fiscal, 
            cfg_mempresa.id_isae, 
            cfg_mempresa.fax, 
            cfg_mempresa.estado,
            coalesce(cfg_mestado.nombre, '') as nestado,
			coalesce(cfg_mestado.clase_css, '') as nestado_clase_css,
			coalesce(cfg_mestado.img_icon, '') as nestado_img_icon
		from cfg_mempresa
			left join tb_g_mdivisa as tb_g_mdivisa_b 
				on cfg_mempresa.codigo = tb_g_mdivisa_b.codemp
					and cfg_mempresa.divisa = tb_g_mdivisa_b.codigo
			left join tb_g_mdivisa as tb_g_mdivisa_c 
				on cfg_mempresa.codigo = tb_g_mdivisa_c.codemp
					and cfg_mempresa.moneda = tb_g_mdivisa_c.codigo
			left join cfg_mestado 
				on cfg_mempresa.estado = cfg_mestado.codigo 
					and cfg_mestado.tipo = trim(_tipo)
		where cfg_mempresa.codigo = _codemp;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_mempresa_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_mempresa_u`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
	in _usuario varchar(10),
    in _formulario int,
	in _codigo varchar(2), 
    in _nombre_comercial varchar(100), 
    in _siglas varchar(45), 
    in _pais varchar(100), 
    in _estado_provincia varchar(100), 
    in _ciudad varchar(100), 
    in _codigo_postal varchar(10), 
    in _web varchar(100), 
    in _email varchar(100), 
    in _telefonos varchar(100), 
    in _fax varchar(50),
    in _direccion varchar(8000), 
    in _divisa varchar(5),
    in _moneda varchar(5), 
    in _id_fiscal varchar(45), 
    in _id_isae varchar(15), 
	out _valor varchar(15)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Actualiza los datos de la organización
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2025.01.24
		Autor: 
	---------------------------------------------------------------------------------------------------- */
    
    if coalesce(_codigo, '') != '' then 
		update cfg_mempresa 
			set
				nombre_comercial = _nombre_comercial, 
				siglas = _siglas, 
				pais = _pais, 
				estado_provincia = _estado_provincia, 
				ciudad = _ciudad, 
				codigo_postal = _codigo_postal, 
                web = _web,
				email = _email, 
				telefonos = _telefonos, 
				direccion = _direccion, 
				divisa = _divisa, 
				moneda = _moneda, 
				id_fiscal = _id_fiscal, 
				id_isae = _id_isae, 
				fax = _fax
			where codigo = _codigo ;
	end if ;
    set _valor = _codigo;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_vinculadas_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_vinculadas_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _filtra_sucursal smallint, 
	in _tabla varchar(255), 
	in _valor varchar(255), 
	out _resultado int
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Verifica que un registro vinculado no esté en alguna de sus tablas vinculadas antes de ser eliminado
		si existe el valor devuelto es 1
		Versión 2.0
		Creado: 2024.12.01
		Actualizado: 2024.12.27, 2025.01.24
		Autor: 
	---------------------------------------------------------------------------------------------------- */
	declare done int default 0 ;
	declare _RegFila int default 0 ;
	declare _tabla_vinculada varchar(100) default '' ;
	declare _campo_tabla_vinculada varchar(100) default '' ;
	declare sqlcursor cursor for 
		select tabla_vinculada, campo_tabla_vinculada
			from cfg_tablas_vinculadas 
			where trim(tabla) = trim(_tabla) ;

	declare continue handler for sqlstate '02000' set done = 1 ;
	
	set @cadena = '' ;
	set @linea = 1 ;
    set @resultado = 0 ;

	select count(tabla) into @registros 
		from cfg_tablas_vinculadas 
		where trim(tabla) = trim(_tabla) ;

	open sqlcursor;

	repeat
		fetch sqlcursor into _tabla_vinculada, _campo_tabla_vinculada ;

		if (@linea <= @registros) then
			if @linea = 1 then 
				set @cadena = concat('select ', trim(_campo_tabla_vinculada), ' as campo from ', trim(_tabla_vinculada), ' where codemp = ',trim(_codemp), ' and ', trim(_campo_tabla_vinculada), ' = ', trim(_valor));
			else
				set @cadena = concat(@cadena, ' union select ', trim(_campo_tabla_vinculada), ' as campo from ', trim(_tabla_vinculada), ' where codemp = ',trim(_codemp), ' and ', trim(_campo_tabla_vinculada), ' = ', trim(_valor));
			end if ;

			if (_filtra_sucursal = 1) then
				set @cadena = concat(@cadena, ' and sucursal = ', trim(_sucursal) ) ;
			end if ;
		end if;
		set @linea  = (@linea + 1) ;
	until done = 1 end repeat ;
	close sqlcursor ;
    
    if trim(@cadena) <> '' then
		drop temporary table if exists sentencia ;
		set @cSentencia = concat('CREATE TEMPORARY TABLE sentencia ', @cadena );
		PREPARE sentencia from @cSentencia ;
		EXECUTE sentencia ;
		DEALLOCATE PREPARE sentencia ;
		select count(campo) into @resultado from sentencia ;
	end if ;
    set _resultado = coalesce(@resultado, 0)  ;
    
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_form_vinculadas_nocodemp_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_form_vinculadas_nocodemp_c`(
	in _codemp varchar(2), 
    in _sucursal varchar(3), 
    in _filtra_sucursal smallint, 
    in _tabla varchar(255), 
    in _valor varchar(255), 
    out _resultado int
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Verifica que un registro vinculado no esté en alguna de sus tablas vinculadas antes de ser eliminado
		si existe el valor devuelto es 1
		Versión 2.0
		Creado: 2024.12.01
		Actualizado: 2024.12.27, 2025.01.24
		Autor: 
	---------------------------------------------------------------------------------------------------- */
	set @sql_where = '';
    set @resultado = 5000 ;
    
	-- Validación de parámetros
    if (_codemp is not null) OR (_sucursal is not null) or (_tabla is not null) or (_valor is not null) then
 		select 	group_concat(
					concat('select ', trim(campo_tabla_vinculada), ' as cantidad from ', trim(tabla_vinculada), 
					' where ', trim(campo_tabla_vinculada), ' = ''', trim(_valor), ''''
				) separator ' union all ') 
				into @sql_where
			from cfg_tablas_vinculadas
			where trim(tabla) = trim(_tabla);
		
        if @sql_where is not null and @sql_where <> '' then
			prepare sql_tabla from @sql_where;
			execute sql_tabla ;
			deallocate prepare sql_tabla ;
            select cantidad into @resultado from sql_tabla ;
		end if;
		set @sql_where = null ;
	end if ;
    set _resultado = if(coalesce(@resultado, 0) = 0 , -1, @resultado) ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_lista_cfg_mformato` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_lista_cfg_mformato`(
	in _codemp Varchar(2), 
	in _sucursal Varchar(3), 
	in _status int, 
	in _clave Varchar(255),
	in json_data JSON
)
begin
	-- ------------------------------------------
	-- Consulta del maestro de formatos fecha y hora, 
	-- para crear la lista desplegable.
	-- V 1.0
	-- Creado: 2024.05.06
	-- Actualizado: (Iluminado) 2025-09-15
	-- Autor: 
	-- -------------------------------------------
	
    -- ------------------------------------------------------------------------------------------------------------
    drop temporary table if exists js0 ;
    create temporary table js0
		select	JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.usuario')) AS usuario,
				JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.el_parametro')) AS parametro ;
	
    select 	usuario, parametro into @usuario, @parametro from js0 ;
    select	coalesce(u218, '') into @grupo from tb_musuario where u201 = @usuario ;
	
    -- ------------------------------------------------------------------------------------------------------------
	drop temporary table if exists a1;
	create temporary table a1
		select	cfg_mformato.codigo,
				cfg_mformato.nombre
			From cfg_mformato
			where trim(coalesce(cfg_mformato.nombre, '')) <> ''
				and cfg_mformato.codigo <> trim(coalesce(_clave, ''))
				-- and trim(coalesce(_clave, '')) = ''
                and _status = 1
		union
		select	cfg_mformato.codigo,
				cfg_mformato.nombre
			From cfg_mformato
			where cfg_mformato.codigo = trim(coalesce(_clave, '')) 
				and trim(coalesce(_clave, '')) <> '';
		
		select	a1.codigo,
				nombre
			from a1
			order by a1.nombre ;
		
End ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_lista_cfg_mlenguaje` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_lista_cfg_mlenguaje`(
	in _codemp Varchar(2), 
	in _sucursal Varchar(3), 
	in _status int, 
	in _clave Varchar(255), 
	in json_data JSON
)
begin
	-- ------------------------------------------
	-- Consulta del maestro de lenguajes, 
	-- para crear la lista desplegable.
	-- V 1.0
	-- Creado: 2024.05.06
	-- Actualizado: 2024.05.06
	-- Autor: 
	-- -------------------------------------------
	
    -- ------------------------------------------------------------------------------------------------------------
    drop temporary table if exists js0 ;
    create temporary table js0
		select	JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.usuario')) AS usuario,
				JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.el_parametro')) AS parametro ;
	
    select 	usuario, parametro into @usuario, @parametro from js0 ;
    select	coalesce(u218, '') into @grupo from tb_musuario where u201 = @usuario ;
	
    -- ------------------------------------------------------------------------------------------------------------
	drop temporary table if exists a1;
	create temporary table a1
		select	codigo,
				nombre
			from cfg_mlenguaje
			where codigo <> trim(coalesce(_clave, ''))
				and trim(coalesce(nombre, '')) <> ''
                and _status = 1
		union
		select	codigo,
				nombre
			from cfg_mlenguaje
			where codigo = trim(coalesce(_clave, '')) ; 
				-- and _status = 0 ;
		
	select	a1.codigo,
			concat(a1.codigo,' ',trim(a1.nombre)) as nombre
		from a1
		order by a1.nombre ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_lista_cfg_musuario_grupo` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_lista_cfg_musuario_grupo`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _status varchar(1), 
	in _codigo varchar(255), 
	in json_data JSON
)
begin
	-- ------------------------------------------
	-- consulta del maestro de grupos de usuarios, 
	-- para crear la lista desplegable.
	-- V 1.0
	-- Creado: 2024.05.06
	-- Actualizado: 2025-09-27
	-- Autor: 
	-- -------------------------------------------
	
    -- ------------------------------------------------------------------------------------------------------------
    drop temporary table if exists js0 ;
    create temporary table js0
		select	JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.usuario')) AS usuario,
				JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.el_parametro')) AS parametro ;
	
    select 	usuario, parametro into @usuario, @parametro from js0 ;
    select	coalesce(u218, ''), coalesce(u230, 0) into @grupo, @nivel from tb_musuario where u201 = @usuario ;
	
    -- ------------------------------------------------------------------------------------------------------------
	drop temporary table if exists a1;
	create temporary table a1
		select	tb_musuario_grupo.u201,
				tb_musuario_grupo.u202
			from tb_musuario_grupo
			where tb_musuario_grupo.estado = _status
				and trim(coalesce(tb_musuario_grupo.u202, '')) <> ''
				-- and tb_musuario_grupo.u201 <> trim(coalesce(_codigo, ''))
                and tb_musuario_grupo.u230 between 1 and @nivel
		union 
		select	tb_musuario_grupo.u201,
				tb_musuario_grupo.u202
			from tb_musuario_grupo
			where tb_musuario_grupo.u201 = trim(coalesce(_codigo, '')) ;

	select	a1.u201 as codigo,
			a1.u202 as nombre
		from a1
		order by a1.u202 ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_lista_c_mvendors` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_lista_c_mvendors`(
	in _codemp Varchar(2), 
	in _sucursal Varchar(3), 
	in _status int, 
	in _clave Varchar(255), 
	in json_data JSON
)
begin
	/* -- ------------------------------------------
		Consulta del maestro de grupo, para clasificar a los clientes
		Creado 2025-09-04
		Actualizado 2025-09-04
		Autor: Custom Systems Solutions LLC
	-- ------------------------------------------- */
	
    -- ------------------------------------------------------------------------------------------------------------
    drop temporary table if exists js0 ;
    create temporary table js0
		select	JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.usuario')) AS usuario,
				JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.el_parametro')) AS parametro ;
	
    select 	usuario, parametro into @usuario, @parametro from js0 ;
    select	coalesce(u218, '') into @grupo from tb_musuario where u201 = @usuario ;
	
    -- ------------------------------------------------------------------------------------------------------------
	drop temporary table if exists a1;
	create temporary table a1
		select	codigo,
				nombre
			from tb_c_mvendors
			where codemp = _codemp
                and sucursal = _sucursal
				and codigo <> trim(coalesce(_clave, ''))
				and trim(coalesce(nombre, '')) <> ''
				and estado = _status
		union
		select	codigo,
				nombre
			from tb_c_mvendors
			where codemp = _codemp
                and sucursal = _sucursal
				and codigo = trim(coalesce(_clave, '')) ;
		
	select	a1.codigo,
			a1.nombre
		from a1
		order by a1.nombre ;
		
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_lista_f_mcustomers` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_lista_f_mcustomers`(
	in _codemp Varchar(2), 
	in _sucursal Varchar(3), 
	in _status int, 
	in _clave Varchar(255), 
	in json_data JSON
)
begin
	/* -- ------------------------------------------
		Consulta del maestro de grupo, para clasificar a los clientes
		Creado 2025-08-28
		Actualizado 2025-08-29
		Autor: Custom Systems Solutions LLC
	-- ------------------------------------------- */
	
    -- ------------------------------------------------------------------------------------------------------------
    drop temporary table if exists js0 ;
    create temporary table js0
		select	JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.usuario')) AS usuario,
				JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.el_parametro')) AS parametro ;
	
    select 	usuario, parametro into @usuario, @parametro from js0 ;
    select	coalesce(u218, '') into @grupo from tb_musuario where u201 = @usuario ;
	
    -- ------------------------------------------------------------------------------------------------------------
    drop temporary table if exists f_mcustomer_grupo_d ;
    create temporary table f_mcustomer_grupo_d
		select	codemp, sucursal, cliente
			from tb_f_mcustomers_group_d
            where codemp = _codemp
				and sucursal = _sucursal
                and codigo = @grupo 
                and @grupo <> ''
		union
        select	codemp, sucursal, codigo as cliente
			from tb_f_mcustomers
            where codemp = _codemp
				and sucursal = _sucursal
                and @grupo = '' 
                and estado = 1 ;
    
	drop temporary table if exists a1;
	create temporary table a1
		select	tb_f_mcustomers.codigo,
				tb_f_mcustomers.nombre
			from tb_f_mcustomers
				inner join f_mcustomer_grupo_d
					on tb_f_mcustomers.codemp = f_mcustomer_grupo_d.codemp
						and tb_f_mcustomers.sucursal = f_mcustomer_grupo_d.sucursal
                        and tb_f_mcustomers.codigo = f_mcustomer_grupo_d.cliente
			where tb_f_mcustomers.codemp = _codemp
                and tb_f_mcustomers.sucursal = _sucursal
				and tb_f_mcustomers.codigo <> trim(coalesce(_clave, ''))
				and trim(coalesce(tb_f_mcustomers.nombre, '')) <> ''
				and tb_f_mcustomers.estado = _status
		union
		select	codigo,
				nombre
			from tb_f_mcustomers
			where codemp = _codemp
                and sucursal = _sucursal
				and codigo = trim(coalesce(_clave, '')) ;
	
	select	a1.codigo,
			a1.nombre
		from a1
		order by a1.nombre ;
		
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_lista_f_mcustomers_group` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_lista_f_mcustomers_group`(
	in _codemp Varchar(2), 
	in _sucursal Varchar(3), 
	in _status int, 
	in _clave Varchar(255), 
	in json_data JSON
)
begin
	/* -- ------------------------------------------
		Consulta del maestro de grupo, para clasificar a los clientes
		Creado 2025-09-27
		Actualizado 2025-09-27
		Autor: Custom Systems Solutions LLC
	-- ------------------------------------------- */
	
    -- ------------------------------------------------------------------------------------------------------------
    drop temporary table if exists js0 ;
    create temporary table js0
		select	JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.usuario')) AS usuario,
				JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.el_parametro')) AS parametro ;
	
    select 	usuario, parametro into @usuario, @parametro from js0 ;
    select	coalesce(u218, '') into @grupo from tb_musuario where u201 = @usuario ;
	
    -- ------------------------------------------------------------------------------------------------------------
	drop temporary table if exists a1;
	create temporary table a1
		select	codigo,
				nombre
			from tb_f_mcustomers_group
			where codemp = _codemp
                and sucursal = _sucursal
				and codigo <> trim(coalesce(_clave, ''))
				and trim(coalesce(nombre, '')) <> ''
				and estado = _status
		union
		select	codigo,
				nombre
			from tb_f_mcustomers_group
			where codemp = _codemp
                and sucursal = _sucursal
				and codigo = trim(coalesce(_clave, '')) ;
		
	select	a1.codigo,
			a1.nombre
		from a1
		order by a1.nombre ;
		
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_lista_g_mciudad` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_lista_g_mciudad`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _status int, 
	in _clave varchar(255), 
	in json_data JSON
)
BEGIN
	/* ------------------------------------------
		Crea una consulta del maestro indicado la lista desplegable.
		Creado 2025.01.03
		Actualizado 2025.01.03
		Autor: 
	------------------------------------------- */
    
    -- ------------------------------------------------------------------------------------------------------------
    drop temporary table if exists js0 ;
    create temporary table js0
		select	JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.usuario')) AS usuario,
				JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.el_parametro')) AS parametro ;
	
    select 	usuario, parametro into @usuario, @parametro from js0 ;
    select	coalesce(u218, '') into @grupo from tb_musuario where u201 = @usuario ;
	
    -- ------------------------------------------------------------------------------------------------------------
	set @tabla = '' ;
	set @espacio = '''' ;
	set @clave = trim(coalesce(_clave, '')) ;
    
    if @clave <> '' then
		select 	tabla into @tabla
			from cfg_lista_formularios
			where formulario = _parametro ;
        
		set @estado_ciudad ='';
        set @sql_estados = concat('select estado_ciudad into @estado_ciudad from ',@tabla,' where codigo =  @clave');
			prepare sentencia from @sql_estados ;
			execute sentencia ;
            
		drop temporary table if exists sentencia;
		
		if coalesce(@tabla, '') <> '' then
			set @sql_select = concat('select codigo, nombre from ', @tabla, ' where estado_ciudad = ', @espacio, @estado_ciudad, @espacio) ;
			set @sql_sentencia = concat('create temporary table sentencia ', @sql_select, ' and codigo <> ', @espacio, @clave, @espacio, ' and estado = ', _status) ;
			set @sql_sentencia = concat(@sql_sentencia, ' and trim(coalesce(nombre,', @espacio,  @espacio, ')) <> ', @espacio, @espacio) ;
			set @sql_sentencia = concat(@sql_sentencia, ' union ') ;
			set @sql_sentencia = concat(@sql_sentencia, @sql_select, ' and codigo = ', @espacio, @clave, @espacio, ' ;' ) ;
		
			prepare sentencia from @sql_sentencia ;
			execute sentencia ;
			deallocate prepare sentencia ;
			
			select	sentencia.codigo,
					trim(sentencia.nombre) as nombre
				from sentencia
				order by sentencia.nombre ;
		else
			select 	'' collate utf8mb4_spanish_ci as codigo,
					'' collate utf8mb4_spanish_ci as nombre ;
		end if ;
    end if ;
END ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_lista_g_mestado_ciudad` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_lista_g_mestado_ciudad`(
	in _codemp varchar(2),
    in _sucursal varchar(3),
    in _status int, 
    in _clave varchar(5), 
    in json_data JSON
)
begin
	-- ------------------------------------------
	-- Consulta del maestro de paises
    -- Creado: 2024.12.01
	-- Actualizado 2024.12.01
	-- Autor: 
	-- -------------------------------------------
	
    -- ------------------------------------------------------------------------------------------------------------
    drop temporary table if exists js0 ;
    create temporary table js0
		select	JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.usuario')) AS usuario,
				JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.el_parametro')) AS parametro ;
	
    select 	usuario, parametro into @usuario, @parametro from js0 ;
    select	coalesce(u218, '') into @grupo from tb_musuario where u201 = @usuario ;
	
    -- ------------------------------------------------------------------------------------------------------------
	drop temporary table if exists sql_tabla ;
	create temporary table sql_tabla
		select	codigo, nombre, siglas
			from tb_g_mestado_ciudad
			where codigo <> trim(coalesce(_clave, ''))
				and _status <> 0
		union
		select	codigo, nombre, siglas
			from tb_g_mestado_ciudad
			where codigo = trim(coalesce(_clave, ''))
				and _status <> 0 
		union
		select	codigo, nombre, siglas
			from tb_g_mestado_ciudad
			where codigo = trim(coalesce(_clave, ''))
				and _status = 0 ;
	
    select *
		from sql_tabla
		order by nombre ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_lista_g_mpais` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_lista_g_mpais`(
	in _codemp varchar(2), 
    in _sucursal varchar(3), 
    in _status int, 
    in _codigo varchar(5), 
    in json_data JSON
)
begin
	-- ------------------------------------------
	-- Consulta del maestro de paises
    -- Creado: 2024.12.01
	-- Actualizado 2024.12.29
	-- Autor: 
	-- -------------------------------------------
	
    -- ------------------------------------------------------------------------------------------------------------
    drop temporary table if exists js0 ;
    create temporary table js0
		select	JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.usuario')) AS usuario,
				JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.el_parametro')) AS parametro ;
	
    select 	usuario, parametro into @usuario, @parametro from js0 ;
    select	coalesce(u218, '') into @grupo from tb_musuario where u201 = @usuario ;
	
    -- ------------------------------------------------------------------------------------------------------------
	drop temporary table if exists sql_tabla ;
	create temporary table sql_tabla
		select codigo, nombre
			from tb_g_mpais
			where codigo = coalesce(_codigo, '')
				and coalesce(_codigo, '') != '' 
                and estado = 1
		union
		select codigo, nombre
			from tb_g_mpais
			where codigo <> coalesce(_codigo, '')
				and coalesce(_codigo, '') = '' 
                and estado = 1 ;
	
    select *
		from sql_tabla
		order by nombre ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_lista_mestado` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_lista_mestado`(
	in _codemp varchar(2), 
    in _sucursal varchar(3), 
    in _status int, 
    in _codigo varchar(3),
	in json_data JSON
)
begin
	/* -- ------------------------------------------
		Consulta del maestro de estados, de acuerdo al tipo, para crear la lista esplegable.
		Actualizado 2025-01-21
					2025-09-27
		Autor: Iluminado
	-- ------------------------------------------- */
	
    -- ------------------------------------------------------------------------------------------------------------
    drop temporary table if exists js0 ;
    create temporary table js0
		select	JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.usuario')) AS usuario,
				JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.el_parametro')) AS parametro ;
	
    select 	usuario, parametro into @usuario, @parametro from js0 ;
    select	coalesce(u218, '') into @grupo from tb_musuario where u201 = @usuario ;
	
    -- ------------------------------------------------------------------------------------------------------------
	drop temporary table if exists a0;
	create temporary table a0
		select	codigo,
				nombre
			from cfg_mestado
			where tipo = @parametro
				and codigo <> trim(coalesce(_codigo, ''))
				and trim(coalesce(nombre, '')) <> ''
                and _status = 1
		union
		select	codigo,
				nombre
			from cfg_mestado
			where tipo = @parametro
				and codigo = trim(coalesce(_codigo, '')) ;
                
    select *
		from a0
		order by codigo ;
	
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_lista_mfecha_tipo` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_lista_mfecha_tipo`(
	in _codemp varchar(2), 
    in _sucursal varchar(3), 
    in _status int, 
    in _codigo varchar(3), 
    in json_data JSON
)
begin
	/* -- ------------------------------------------
		Consulta del maestro de grupo, para clasificar a los clientes
		Creado 2025-08-31
		Actualizado 2025-08-31
		Autor: 
	-- ------------------------------------------- */
    
    -- ------------------------------------------------------------------------------------------------------------
    drop temporary table if exists js0 ;
    create temporary table js0
		select	JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.usuario')) AS usuario,
				JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.el_parametro')) AS parametro ;
	
    select 	usuario, parametro into @usuario, @parametro from js0 ;
    select	coalesce(u218, '') into @grupo from tb_musuario where u201 = @usuario ;
	
    -- ------------------------------------------------------------------------------------------------------------
	select	codigo,
			nombre
		from cfg_mfecha_tipo
        where grupo = @parametro
		order by codigo ;
		
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_lista_mformulario_grupo` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_lista_mformulario_grupo`(
	in _codemp varchar(2), 
    in _sucursal varchar(3), 
    in _estado int(1), 
    in _codigo varchar(255), 
    in json_data JSON
)
begin
	-- ------------------------------------------
	-- consulta los diversos grupos del menú
	-- V 1.0
	-- Creado: 27/10/2014
	-- Actualizado 27/10/2014
	-- Autor: 
	-- -------------------------------------------
    
    -- ------------------------------------------------------------------------------------------------------------
    drop temporary table if exists js0 ;
    create temporary table js0
		select	JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.usuario')) AS usuario,
				JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.el_parametro')) AS parametro ;
	
    select 	usuario, parametro into @usuario, @parametro from js0 ;
    select	coalesce(u218, '') into @grupo from tb_musuario where u201 = @usuario ;
	
    -- ------------------------------------------------------------------------------------------------------------
	if (_codemp is null) OR (_sucursal is null) or (_tabla is null) or (_codigo is null) then
        signal sqlstate '45000'
            set message_text = 'Parámetros incompletos. Todos los campos deben estar especificados.';
    end if ;
	drop temporary table if exists a0 ;
	create temporary table a0
		select codigo, nombre
			from cfg_menu_grupo
			where codigo = _codigo 
		union
		select codigo, nombre
			from cfg_menu_grupo
			where codigo <> _codigo 
				and _codigo = '' ;
	
	select *
		from a0
		order by codigo ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_lista_mformulario_modulo` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_lista_mformulario_modulo`(
	in _codemp varchar(2), 
    in _sucursal varchar(3), 
    in _estado int(1), 
    in _codigo varchar(255), 
    in json_data JSON
)
begin
	-- ------------------------------------------
	-- Consulta los diversos módulos del menú
	-- V 1.0
	-- Creado: 27/10/2014
	-- Actualizado 27/10/2014
	-- Autor: 
	-- -------------------------------------------
	
    -- ------------------------------------------------------------------------------------------------------------
    drop temporary table if exists js0 ;
    create temporary table js0
		select	JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.usuario')) AS usuario,
				JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.el_parametro')) AS parametro ;
	
    select 	usuario, parametro into @usuario, @parametro from js0 ;
    select	coalesce(u218, '') into @grupo from tb_musuario where u201 = @usuario ;
	
    -- ------------------------------------------------------------------------------------------------------------
	drop temporary table if exists a0 ;
	create temporary table a0
		select codigo, nombre
			from cfg_menu_modulo
			where codigo = _codigo 
		union
		select codigo, nombre
			from cfg_menu_modulo
			where codigo <> _codigo
				and _codigo = '';
	
	select *
		from a0
		order by codigo ;

end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_lista_mmaestro_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_lista_mmaestro_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _status int, 
	in _clave varchar(255), 
	in json_data JSON
)
Begin
	/* ------------------------------------------
		Crea una consulta del maestro indicado la lista desplegable.
		Creado 2024.05.10
		Actualizado 2024.05.10
		Autor: 
	------------------------------------------- */
    
    -- ------------------------------------------------------------------------------------------------------------
    drop temporary table if exists js0 ;
    create temporary table js0
		select	JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.usuario')) AS usuario,
				JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.el_parametro')) AS parametro ;
	
    select 	usuario, parametro into @usuario, @parametro from js0 ;
    select	coalesce(u218, '') into @grupo from tb_musuario where u201 = @usuario ;
	
    -- ------------------------------------------------------------------------------------------------------------
	set @tabla = '' ;
	set @espacio = '''' ;
	set @clave = trim(coalesce(_clave, '')) ;

	select 	tabla into @tabla
		from cfg_lista_formularios
		where formulario = @parametro ;
	
	select 	filtra_sucursal into @filtra_sucursal
		from cfg_lista_formularios
		where formulario = @parametro ;
	
	set @sucursal = '' ;
	if @filtra_sucursal = 1 then 
		set @sucursal = concat(' and sucursal = ', @espacio, _sucursal, @espacio) ;
	end if ;
	drop temporary table if exists sentencia;
	
	if coalesce(@tabla, '') <> '' then
		set @sql_select = concat('select codigo, nombre from ', @tabla, ' where codemp = ', @espacio, _codemp, @espacio, @sucursal) ;
		set @sql_sentencia = concat('create temporary table sentencia ', @sql_select, ' and codigo <> ', @espacio, @clave, @espacio, ' and estado = ', _status) ;
		set @sql_sentencia = concat(@sql_sentencia, ' and trim(coalesce(nombre,', @espacio,  @espacio, ')) <> ', @espacio, @espacio) ;
		set @sql_sentencia = concat(@sql_sentencia, ' union ') ;
		set @sql_sentencia = concat(@sql_sentencia, @sql_select, ' and codigo = ', @espacio, @clave, @espacio, ' ;' ) ;
	
		prepare sentencia from @sql_sentencia ;
		execute sentencia ;
		deallocate prepare sentencia ;
		
		select	sentencia.codigo,
				trim(sentencia.nombre) as nombre
			from sentencia
			order by sentencia.nombre ;
	else
		select 	'' collate utf8mb4_spanish_ci as codigo,
				'' collate utf8mb4_spanish_ci as nombre ;
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_lista_mmaestro_c_nocodemp` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_lista_mmaestro_c_nocodemp`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _status int, 
	in _clave varchar(255), 
	in json_data JSON
)
BEGIN
	/* ------------------------------------------
		Crea una consulta del maestro indicado la lista desplegable.
		Creado 2024.05.10
		Actualizado 2024.05.10
		Autor: 
	------------------------------------------- */
    
    -- ------------------------------------------------------------------------------------------------------------
    drop temporary table if exists js0 ;
    create temporary table js0
		select	JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.usuario')) AS usuario,
				JSON_UNQUOTE(JSON_EXTRACT(json_data, '$.el_parametro')) AS parametro ;
	
    select 	usuario, parametro into @usuario, @parametro from js0 ;
    select	coalesce(u218, '') into @grupo from tb_musuario where u201 = @usuario ;
	
    -- ------------------------------------------------------------------------------------------------------------
	set @tabla = '' ;
	set @espacio = '''' ;
	set @clave = trim(coalesce(_clave, '')) ;
    
    -- Si la clave esta en blanco solo se carga la lista al seleccionar el estado
    -- Si pasa un valor en la clave, entonces filtra todas las ciudades que tengan el mismo estado
    if @clave <> '' then

		select 	tabla into @tabla
			from cfg_lista_formularios
			where formulario = @parametro ;
        
		set @estado_ciudad ='';
        set @sql_estados = concat('select estado_ciudad into @estado_ciudad from ',@tabla,' where codigo =  @clave');
			prepare sentencia from @sql_estados ;
			execute sentencia ;
            
		drop temporary table if exists sentencia;
		
		if coalesce(@tabla, '') <> '' then
			set @sql_select = concat('select codigo, nombre from ', @tabla, ' where estado_ciudad = ', @espacio, @estado_ciudad, @espacio) ;
			set @sql_sentencia = concat('create temporary table sentencia ', @sql_select, ' and codigo <> ', @espacio, @clave, @espacio, ' and estado = ', _status) ;
			set @sql_sentencia = concat(@sql_sentencia, ' and trim(coalesce(nombre,', @espacio,  @espacio, ')) <> ', @espacio, @espacio) ;
			set @sql_sentencia = concat(@sql_sentencia, ' union ') ;
			set @sql_sentencia = concat(@sql_sentencia, @sql_select, ' and codigo = ', @espacio, @clave, @espacio, ' ;' ) ;
		
        -- select @sql_sentencia;
        
			prepare sentencia from @sql_sentencia ;
			execute sentencia ;
			deallocate prepare sentencia ;
			
			select	sentencia.codigo,
					trim(sentencia.nombre) as nombre
				from sentencia
				order by sentencia.nombre ;
                
		else
			select 	'' collate utf8mb4_spanish_ci as codigo,
					'' collate utf8mb4_spanish_ci as nombre ;
		end if ;
	
    end if ;
END ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_musuario_acceso_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_musuario_acceso_c`(
	in _id_documento int(5), 
    in _id_grupo varchar(5)
)
begin
	if(trim(_id_documento)<>'')then
		select
			tb_musuario_acceso.id_acceso,
			tb_musuario_acceso.id_documento,
			tb_musuario_accion.id_accion,
			tb_musuario_accion.descripcion
		from tb_musuario_acceso
			left join tb_musuario_accion 
				on tb_musuario_accion.id_accion = tb_musuario_acceso.id_accion
		where
			tb_musuario_acceso.id_accion not in (select  u303 from tb_musuario_grupo_d where u301 = _id_grupo and u302 = _id_documento ) and tb_musuario_acceso.id_documento = _id_documento
		order by tb_musuario_accion.id_accion Asc;
	end if;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_musuario_dpermiso_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_musuario_dpermiso_c`(
	in _grupo varchar(5)
)
begin
	select
		tb_musuario_dpermiso.u201,
		tb_musuario_dpermiso.u202,
		tb_musuario_dpermiso.u203,
		tb_musuario_dpermiso.u204,
		tb_musuario_dpermiso.u205,
		tb_musuario_dpermiso.u206,
		tb_musuario_dpermiso.u207,
		tb_musuario_dpermiso.u208,
		tb_musuario_dpermiso.u209,
		tb_musuario_dpermiso.u210,
		tb_musuario_dpermiso.u211,
		coalesce(tb_mmaestros.Modulo, '') As nmodulo
	from tb_musuario_dpermiso
		inner join tb_mmaestros 
			on tb_mmaestros.id_documento = tb_musuario_dpermiso.u203
	where tb_musuario_dpermiso.u202 = _grupo
	order by tb_mmaestros.item asc;

end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_musuario_dpermiso_comprobacion_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_musuario_dpermiso_comprobacion_c`(
	in _codigo_usuario varchar(5), 
    in _modulo varchar(3)
)
begin
	if(trim(_modulo)='')then
		select 	tb_musuario.u201,
				tb_musuario_grupo.u201 as codigo_grupo,
				tb_musuario_dpermiso.u201 as usuario,
				tb_musuario_dpermiso.u203,
				tb_musuario_dpermiso.u204,
				tb_musuario_dpermiso.u205,
				tb_musuario_dpermiso.u206,
				tb_musuario_dpermiso.u207,
				tb_musuario_dpermiso.u208,
				tb_musuario_dpermiso.u209,
				tb_musuario_dpermiso.u210
		from tb_musuario
			left join tb_musuario_grupo 
				on tb_musuario_grupo.u201 = tb_musuario.u206
			left join tb_musuario_dpermiso 
				on tb_musuario_dpermiso.u202 = tb_musuario_grupo.u201
		where tb_musuario.u201 = _codigo_usuario;

	else
		select 	tb_musuario.u201,
				tb_musuario_grupo.u201 as codigo_grupo,
				tb_musuario_dpermiso.u201 as usuario,
				tb_musuario_dpermiso.u203,
				tb_musuario_dpermiso.u204,
				tb_musuario_dpermiso.u205,
				tb_musuario_dpermiso.u206,
				tb_musuario_dpermiso.u207,
				tb_musuario_dpermiso.u208,
				tb_musuario_dpermiso.u209,
				tb_musuario_dpermiso.u210
		from tb_musuario
			left join tb_musuario_grupo 
				on tb_musuario_grupo.u201 = tb_musuario.u206
			left join tb_musuario_dpermiso 
				on tb_musuario_dpermiso.u202 = tb_musuario_grupo.u201
		where tb_musuario.u201 = _codigo_usuario 
			and tb_musuario_dpermiso.u203 = _modulo;
	end if;

end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_musuario_dpermiso_edicion_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_musuario_dpermiso_edicion_c`(
	in _grupo varchar(5)
)
begin
	select *
		from tb_mmaestros
		where tb_mmaestros.id_documento not in(select u302 from tb_musuario_grupo_d where tb_musuario_grupo_d.u301 = _grupo )
		order by nivel,modulo;

end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_musuario_dpermiso_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_musuario_dpermiso_u`(
	in _usuario varchar(5), 
	in _grupo varchar(5), 
	in _modulo varchar(5), 
	in _permitir int(1), 
	in _nuevo int(1), 
	in _editar int(1), 
	in _aprobar int(1), 
	in _anular int(1), 
	in _imprimir int(1), 
	in _ver int(1), 
	in _item int(11), 
	in _accion varchar(1)
)
begin
	if (_accion = 'D') then
		delete 
			from tb_musuario_dpermiso 
            where u211 = _item ;
	else
		if _item = 0 then
			insert into tb_musuario_dpermiso (u201, u202, u203, u204, u205, u206, u207, u208, u209, u210 ) 
				values (_usuario, _grupo, _modulo, _permitir, _nuevo, _editar, _aprobar, _anular, _imprimir, _ver  );
		else
			update tb_musuario_dpermiso 
				set
					u201 = _usuario,
					u202 = _grupo,
					u203 = _modulo,
					u204 = _permitir,
					u205 = _nuevo,
					u206 = _editar,
					u207 = _aprobar,
					u208 = _anular,
					u209 = _imprimir,
					u210 = _ver
				where u211 = _item;
		end if;
	end if;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_musuario_grupos_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_musuario_grupos_c`(
	in _status varchar(1), 
    in _parametro varchar(255)
)
begin
	if trim(_status)='' then
		if Trim(_parametro)='' then
			select	tb_musuario.u201,
					tb_musuario.u202,
					tb_musuario.u203,
					tb_musuario.u204,
					tb_musuario.u205,
					tb_musuario.u206,
					tb_musuario.u207,
					tb_musuario.u208 As estado,
					tb_mestado.nombre AS nestado,
					tb_musuario.u209,
					tb_mprofesional.nombre AS nprofesional
			 from tb_musuario
				left join tb_mestado 
					on tb_musuario.u208 = tb_mestado.codigo
				left join tb_mprofesional 
					on tb_musuario.u209 = tb_mprofesional.codigo
 			order by tb_musuario.u202;

		else
			select	tb_musuario.u201,
					tb_musuario.u202,
					tb_musuario.u203,
					tb_musuario.u204,
					tb_musuario.u205,
					tb_musuario.u206,
					tb_musuario.u207,
					tb_musuario.u208 As estado,
					tb_mestado.nombre AS nestado,
					tb_musuario.u209,
					tb_mprofesional.nombre AS nprofesional
			 from tb_musuario
				left join tb_mestado 
					on tb_musuario.u208 = tb_mestado.codigo
				left join tb_mprofesional 
					on tb_musuario.u209 = tb_mprofesional.codigo
			where tb_musuario.u206 = _parametro
 			order by tb_musuario.u202;
		end if;
	else
		if Trim(_parametro)='' then
			select
				tb_musuario.u201,
				tb_musuario.u202,
				tb_musuario.u203,
				tb_musuario.u204,
				tb_musuario.u205,
				tb_musuario.u206,
				tb_musuario.u207,
				tb_musuario.u208 As estado,
				tb_mestado.nombre AS nestado,
				tb_musuario.u209,
				tb_mprofesional.nombre AS nprofesional
			 from tb_musuario
				left join tb_mestado 
					on tb_musuario.u208 = tb_mestado.codigo
				left join tb_mprofesional 
					on tb_musuario.u209 = tb_mprofesional.codigo
			where tb_musuario.u208 = _status
 			order by tb_musuario.u202;

		else
			select	tb_musuario.u201,
					tb_musuario.u202,
					tb_musuario.u203,
					tb_musuario.u204,
					tb_musuario.u205,
					tb_musuario.u206,
					tb_musuario.u207,
					tb_musuario.u208 As estado,
					tb_mestado.nombre AS nestado,
					tb_musuario.u209,
					tb_mprofesional.nombre AS nprofesional
			 from tb_musuario
				left join tb_mestado on tb_musuario.u208 = tb_mestado.codigo
				left join tb_mprofesional on tb_musuario.u209 = tb_mprofesional.codigo
			where tb_musuario.u208 = _status and
			            tb_musuario.u206 = _parametro
 			order by tb_musuario.u202;
		end if;
	end if;

end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_musuario_grupo_d` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_musuario_grupo_d`(
	in _grupo varchar(5), 
    in _modulo varchar(5), 
    in _accion_botones varchar(5), 
    in _item int(11), 
    in _accion varchar(1)
)
begin
	if(_accion = 'D')then
		delete 
			from tb_musuario_grupo_d 
            where u304 = _item;
	else
		if _item = 0 then
			insert into tb_musuario_grupo_d (u301, u302, u303 ) values (_grupo, _modulo, _accion_botones );
		else
			update tb_musuario_grupo_d 
				set
					u301 = _grupo,
					u302 = _modulo,
					u303 = _accion_botones
				where u304 = _item;
		end if;
	end if;

end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_musuario_grupo_d_accion_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_musuario_grupo_d_accion_c`(
	in _id_grupo varchar(5), 
    in _id_modulo varchar(5), 
    in _id_accion varchar(1)
)
begin
	select	tb_musuario_grupo_d.u301,
			tb_musuario_grupo_d.u302,
			tb_musuario_grupo_d.u303,
			tb_musuario_grupo_d.u304
		from tb_musuario_grupo_d
		where tb_musuario_grupo_d.u301 = _id_grupo 
			and tb_musuario_grupo_d.u302 = _id_modulo 
			and tb_musuario_grupo_d.u303 = _id_accion;

end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_musuario_grupo_d_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_musuario_grupo_d_c`(
	in _id_grupo varchar(5), 
	in _id_documento varchar(5), 
	in _accion varchar(1))
begin
	if(trim(_accion)='')then
		if((trim(_id_grupo)<> '' ) and (trim(_id_documento)<> '' ))then
			select	tb_musuario_grupo_d.u301,
					tb_musuario_grupo_d.u302,
					tb_musuario_grupo_d.u303,
					tb_musuario_grupo_d.u304,
					tb_musuario_accion.descripcion
			from tb_musuario_grupo_d
				left join tb_musuario_accion 
					on tb_musuario_accion.id_accion = tb_musuario_grupo_d.u303
			where tb_musuario_grupo_d.u301 = _id_grupo 
				and tb_musuario_grupo_d.u302 = _id_documento;
		end if;
	else
		select	tb_musuario_grupo_d.u301,
				tb_musuario_grupo_d.u302 as id_documento,
				tb_musuario_grupo_d.u303,
				tb_musuario_grupo_d.u304,
				tb_musuario_accion.descripcion,
				tb_mmaestros.Modulo,
				tb_mmaestros.nivel
		from tb_musuario_grupo_d
			left join tb_musuario_accion 
				on tb_musuario_accion.id_accion = tb_musuario_grupo_d.u303
			left join tb_mmaestros 
				on tb_mmaestros.id_documento = tb_musuario_grupo_d.u302
		where tb_musuario_grupo_d.u301 = _id_grupo 
			and tb_musuario_grupo_d.u303 = 0
		order by nivel,modulo;
	end if;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_musuario_grupo_d_comprobacion_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_musuario_grupo_d_comprobacion_c`(
	in _codigo_usuario varchar(5), 
	in _modulo varchar(5)
)
begin
	if(trim(_modulo)='' )then
		select 	tb_musuario.u201,
				tb_mmaestros.Modulo,
				tb_musuario_grupo.u201 as codigo_grupo,
				tb_musuario_grupo_d.u302,
				tb_musuario_grupo_d.u303,
				tb_musuario_grupo_d.u304
			from tb_musuario
				left join tb_musuario_grupo 
					on tb_musuario_grupo.u201 = tb_musuario.u206
				left join tb_musuario_grupo_d 
					on tb_musuario_grupo_d.u301 = tb_musuario_grupo.u201
				left join tb_mmaestros 
					on tb_mmaestros.id_documento = tb_musuario_grupo_d.u302
			where tb_musuario.u201 = _codigo_usuario 
				and tb_musuario_grupo_d.u303 = 0;
	else
		select 	tb_musuario.u201,
				tb_mmaestros.Modulo,
				tb_musuario_grupo.u201 as codigo_grupo,
				tb_musuario_grupo_d.u302,
				tb_musuario_grupo_d.u303,
				tb_musuario_grupo_d.u304
			from tb_musuario
				left join tb_musuario_grupo 
					on tb_musuario_grupo.u201 = tb_musuario.u206
				left join tb_musuario_grupo_d 
					on tb_musuario_grupo_d.u301 = tb_musuario_grupo.u201
				left join tb_mmaestros 
					on tb_mmaestros.id_documento = tb_musuario_grupo_d.u302
			where tb_musuario.u201 = _codigo_usuario 
				and tb_musuario_grupo_d.u302 = _modulo;
	end if;

end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_musuario_grupo_d_edicion_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_musuario_grupo_d_edicion_c`(
	in _id_grupo varchar(5)
)
begin
	if(trim(_id_grupo)<> '' )then
		select	tb_musuario_grupo_d.u301, 
				tb_musuario_grupo_d.u302, 
				tb_musuario_grupo_d.u303, 
				tb_musuario_grupo_d.u304, 
				tb_musuario_accion.descripcion,
				tb_mmaestros.Modulo
		from tb_musuario_grupo_d
			left join tb_musuario_accion 
				on tb_musuario_accion.id_accion = tb_musuario_grupo_d.u303
			left join tb_mmaestros 
				on tb_mmaestros.id_documento = tb_musuario_grupo_d.u302
		where
			tb_musuario_grupo_d.u301 = _id_grupo 
				and tb_musuario_grupo_d.u303 = 0;
	end if;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_musuario_grupo_d_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_musuario_grupo_d_u`(
	in _grupo varchar(5), 
	in _modulo varchar(5), 
	in _accion_botones varchar(5), 
	in _item int(11), 
	in _accion varchar(1)
)
begin
	if (_accion = 'D') then
		delete 
			from tb_musuario_grupo_d 
            where u304 = _item;
	else
		if _item = 0 then
			insert into tb_musuario_grupo_d (u301, u302, u303 ) 
				values (_grupo, _modulo, _accion_botones );
		else
			update tb_musuario_grupo_d 
				set
					u301 = _grupo,
					u302 = _modulo,
					u303 = _accion_botones
				where u304 = _item;
		end if;
	end if;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_rep_c_opurchase_orders_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_rep_c_opurchase_orders_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _desde varchar(10), 
	in _hasta varchar(10), 
    in _fecha_t smallint,
	in _proveedor varchar(15),
	in _cliente varchar(15),
    in _estatus char(1),
    in _estatus_plus char(1),
    in _usuario varchar(5)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Reporte de Sales Orders
		Versión 1.0
		Creado: 2025-08-31
		Actualizado: 2025-09-04
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
	set @desde = str_to_date(_desde , '%m/%d/%Y'); 
	set @hasta = str_to_date(_hasta, '%m/%d/%Y'); 
    select trim(coalesce(campo, 'fecha')) into @fecha_tipo
		from cfg_mfecha_tipo
        where codigo = coalesce(_fecha_t, 1) ;
        
	set @usuario = coalesce(_usuario) ;
		select	coalesce(u218, '') into @cliente
			from tb_musuario
			where u201 = @usuario ;
		
    set @estatus = concat(' and ', case when coalesce(_estatus_plus, '') = ''
							then 
								case when coalesce(_estatus, '') = ''
										then 'estado >= 1 ' 
										else concat('estado = ', _estatus)
									end
							else concat('estado >= ', case when _estatus = '' then 1 else _estatus end) 
						end );
                        
    set @cadena = concat(' where codemp = ', _codemp);
	if trim(_sucursal) <> '' then
		set @cadena = concat(@cadena, ' and sucursal = ', _sucursal);
	end if;
    
    set @cadena = concat(@cadena, ' and ', @fecha_tipo, ' between "',@desde,'" and "',@hasta,'"');
    if (coalesce(_proveedor, '') != '') then
		set @cadena = concat(@cadena, ' and proveedor = "',  trim(_proveedor), '"');
    end if ;
    if (coalesce(_cliente, '') != '') then
		set @cadena = concat(@cadena, ' and cliente = "',  trim(_cliente), '"');
    end if ;
    -- set @cadena = concat(@cadena, ' and estado between 4 and 5');
    set @cadena = concat(@cadena, @estatus) ;
    
	drop temporary table if exists c_opurchase_orders ;	
	set @cSentencia = concat('create temporary table c_opurchase_orders select * from tb_c_opurchase_orders ', @cadena );
	
    prepare c_opurchase_orders from @cSentencia ;
	execute c_opurchase_orders ;
	deallocate prepare c_opurchase_orders ;
	
    -- ----------------------------------------------------------------------------------------------------
    select	coalesce(tb_c_mvendors.nombre, '') as nvendor,
			coalesce(tb_f_mcustomers.nombre, '') as ncustomer,
			c_opurchase_orders.*,
            coalesce(cfg_mestado.nombre, '') as nestado
		from c_opurchase_orders
			left join tb_c_mvendors
				on c_opurchase_orders.codemp = tb_c_mvendors.codemp
					and c_opurchase_orders.sucursal = tb_c_mvendors.sucursal
					and c_opurchase_orders.proveedor = tb_c_mvendors.codigo			
			left join tb_f_mcustomers
				on c_opurchase_orders.codemp = tb_f_mcustomers.codemp
					and c_opurchase_orders.sucursal = tb_f_mcustomers.sucursal
                    and c_opurchase_orders.cliente = tb_f_mcustomers.codigo
			left join cfg_mestado
				on c_opurchase_orders.codemp = cfg_mestado.codemp
					and c_opurchase_orders.estado = cfg_mestado.codigo
                    and cfg_mestado.tipo = 'GEN'
		order by coalesce(tb_c_mvendors.nombre, ''), coalesce(tb_f_mcustomers.nombre, ''), c_opurchase_orders.numero ;
	
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_rep_c_opurchase_orders_d_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_rep_c_opurchase_orders_d_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _desde varchar(10), 
	in _hasta varchar(10), 
    in _fecha_t smallint,
	in _proveedor varchar(15),
	in _cliente varchar(15),
    in _estatus char(1),
    in _estatus_plus char(1),
    in _usuario varchar(5)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Reporte de Sales Orders
		Versión 1.0
		Creado: 2025-09-04
		Actualizado: 2025-09-04
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
	set @desde = str_to_date(_desde , '%m/%d/%Y'); 
	set @hasta = str_to_date(_hasta, '%m/%d/%Y'); 
    select trim(coalesce(campo, 'fecha')) into @fecha_tipo
		from cfg_mfecha_tipo
        where codigo = coalesce(_fecha_t, 1) ;
	
	set @usuario = coalesce(_usuario) ;
		select	coalesce(u218, '') into @cliente
			from tb_musuario
			where u201 = @usuario ;
            
    set @estatus = concat(' and ', case when coalesce(_estatus_plus, '') = ''
							then 
								case when coalesce(_estatus, 0) = ''
										then 'estado >= 1 ' 
										else concat('estado = ', coalesce(_estatus, 0))
									end
							else concat('estado >= ', case when _estatus = '' then 1 else _estatus end) 
						end );
                        
    set @cadena = concat(' where codemp = ', _codemp);
	if trim(_sucursal) <> '' then
		set @cadena = concat(@cadena, ' and sucursal = ', _sucursal);
	end if;
    
    set @cadena = concat(@cadena, ' and ', @fecha_tipo, ' between "',@desde,'" and "',@hasta,'"');
    if (coalesce(_proveedor, '') != '') then
		set @cadena = concat(@cadena, ' and proveedor = "',  trim(_proveedor), '"');
    end if ;
    if (coalesce(_cliente, '') != '') then
		set @cadena = concat(@cadena, ' and cliente = "',  trim(_cliente), '"');
    end if ;
    -- set @cadena = concat(@cadena, ' and estado between 4 and 5');
    set @cadena = concat(@cadena, @estatus) ;
    
	drop temporary table if exists c_opurchase_orders ;	
	set @cSentencia = concat('create temporary table c_opurchase_orders select * from tb_c_opurchase_orders ', @cadena );
	
    prepare c_opurchase_orders from @cSentencia ;
	execute c_opurchase_orders ;
	deallocate prepare c_opurchase_orders ;
	
    -- ----------------------------------------------------------------------------------------------------
    select	c_opurchase_orders.*,
            coalesce(tb_c_mvendors.nombre, '') as nvendor,
			coalesce(tb_f_mcustomers.nombre, '') as ncustomer,
			tb_c_opurchase_dproducts.producto, 
            coalesce(tb_a_mproducts.nombre, '') as nproducto,
            tb_c_opurchase_dproducts.precio_lista, 
            tb_c_opurchase_dproducts.precio_venta, 
            tb_c_opurchase_dproducts.precio_unitario, 
            tb_c_opurchase_dproducts.cantidad_backorder, 
            tb_c_opurchase_dproducts.cantidad_order, 
            round(tb_c_opurchase_dproducts.cantidad_order * tb_c_opurchase_dproducts.precio_unitario, 2) as total_orde,
            tb_c_opurchase_dproducts.cantidad_rec, 
            tb_c_opurchase_dproducts.fecha_shipdate, 
            tb_c_opurchase_dproducts.fecha_lastdate, 
            tb_c_opurchase_dproducts.fecha_nextdeli, 
            tb_c_opurchase_dproducts.envio_metodo, 
            tb_c_opurchase_dproducts.notas, 
            tb_c_opurchase_dproducts.nuevo_usado, 
            tb_c_opurchase_dproducts.unidad_medida,
            coalesce(cfg_mestado.nombre, '') nestado
		from c_opurchase_orders
			inner join tb_c_opurchase_dproducts
				on c_opurchase_orders.codemp = tb_c_opurchase_dproducts.codemp
					and c_opurchase_orders.sucursal = tb_c_opurchase_dproducts.sucursal
                    and c_opurchase_orders.numero = tb_c_opurchase_dproducts.numero
			left join tb_c_mvendors
				on c_opurchase_orders.codemp = tb_c_mvendors.codemp
					and c_opurchase_orders.sucursal = tb_c_mvendors.sucursal
					and c_opurchase_orders.proveedor = tb_c_mvendors.codigo			
			left join tb_f_mcustomers
				on c_opurchase_orders.codemp = tb_f_mcustomers.codemp
					and c_opurchase_orders.sucursal = tb_f_mcustomers.sucursal
                    and c_opurchase_orders.cliente = tb_f_mcustomers.codigo
			left join tb_a_mproducts
				on tb_c_opurchase_dproducts.codemp = tb_a_mproducts.codemp
					and tb_c_opurchase_dproducts.sucursal = tb_a_mproducts.sucursal
                    and tb_c_opurchase_dproducts.producto = tb_a_mproducts.codigo
			left join cfg_mestado
				on c_opurchase_orders.codemp = cfg_mestado.codemp
					and c_opurchase_orders.estado = cfg_mestado.codigo
                    and cfg_mestado.tipo = 'GEN'
		order by coalesce(tb_c_mvendors.nombre, ''), coalesce(tb_f_mcustomers.nombre, ''), c_opurchase_orders.numero ;
	
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_rep_f_osales_orders_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_rep_f_osales_orders_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _desde varchar(10), 
	in _hasta varchar(10), 
    in _fecha_t smallint,
	in _cliente varchar(15),
    in _estatus char(1),
    in _estatus_plus char(1),
    in _usuario varchar(5)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Reporte de Sales Orders
		Versión 1.0
		Creado: 2025-08-31
		Actualizado: 2025-09-27
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
	set @desde = str_to_date(_desde , '%m/%d/%Y'); 
	set @hasta = str_to_date(_hasta, '%m/%d/%Y'); 
    select trim(coalesce(campo, 'fecha')) into @fecha_tipo
		from cfg_mfecha_tipo
        where codigo = coalesce(_fecha_t, 8) ;
        
    set @estatus = concat(' and ', case when coalesce(_estatus_plus, '') = ''
							then 
								case when coalesce(_estatus, 0) = ''
										then 'estado >= 1 ' 
										else concat('estado = ', coalesce(_estatus, 0))
									end
							else concat('estado >= ', case when _estatus = '' then 1 else _estatus end) 
						end );
                        
    set @cadena = concat(' where codemp = ', _codemp);
	if trim(_sucursal) <> '' then
		set @cadena = concat(@cadena, ' and sucursal = ', _sucursal);
	end if;
    
    set @cadena = concat(@cadena, ' and ', @fecha_tipo, ' between "',@desde,'" and "',@hasta,'"');
    if (coalesce(_cliente, '') != '') then
		set @cadena = concat(@cadena, ' and cliente = "',  trim(_cliente), '"');
    end if ;
    -- set @cadena = concat(@cadena, ' and estado between 4 and 5');
    set @cadena = concat(@cadena, @estatus) ;
    
	drop temporary table if exists f_osales_orders ;	
	set @cSentencia = concat('create temporary table f_osales_orders select * from tb_f_osales_orders ', @cadena );
	
    prepare f_osales_orders from @cSentencia ;
	execute f_osales_orders ;
	deallocate prepare f_osales_orders ;
	
    -- ----------------------------------------------------------------------------------------------------
    select	coalesce(tb_f_mcustomers.nombre, '') as ncustomer,
			f_osales_orders.*,
            coalesce(cfg_mestado.nombre, '') as nestado
		from f_osales_orders
			left join tb_f_mcustomers
				on f_osales_orders.codemp = tb_f_mcustomers.codemp
					and f_osales_orders.sucursal = tb_f_mcustomers.sucursal
                    and f_osales_orders.cliente = tb_f_mcustomers.codigo
			left join cfg_mestado
				on f_osales_orders.codemp = cfg_mestado.codemp
					and f_osales_orders.estado = cfg_mestado.codigo
                    and cfg_mestado.tipo = 'GEN'
		order by coalesce(tb_f_mcustomers.nombre, ''), f_osales_orders.numero ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_rep_f_osales_orders_cliente_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_rep_f_osales_orders_cliente_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _desde varchar(10), 
	in _hasta varchar(10), 
    in _fecha_t smallint,
	in _cliente varchar(15),
    in _estatus char(1),
    in _estatus_plus char(1),
    in _usuario varchar(5)
    
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Reporte de Sales Orders
		Versión 1.0
		Creado: 2025-08-31
		Actualizado: 2025-09-27
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
	set @desde = str_to_date(_desde , '%m/%d/%Y') ;
	set @hasta = str_to_date(_hasta, '%m/%d/%Y') ;
    select trim(coalesce(campo, 'fecha')) into @fecha_tipo
		from cfg_mfecha_tipo
        where codigo = coalesce(_fecha_t, 8) ;
	
	set @usuario = coalesce(_usuario) ;
	select	coalesce(u218, '') into @grupo
		from tb_musuario
		where u201 = @usuario ;
	
	if coalesce(@grupo, '') <> '' then
		set @jointb = 'inner join tb_f_mcustomers_group_d' ;
		set @jointb = concat(@jointb, ' on tb_f_osales_orders.codemp = tb_f_mcustomers_group_d.codemp') ;
		set @jointb = concat(@jointb, ' and tb_f_osales_orders.sucursal = tb_f_mcustomers_group_d.sucursal') ;
		set @jointb = concat(@jointb, ' and tb_f_osales_orders.cliente = tb_f_mcustomers_group_d.cliente') ;
		set @jointb = concat(@jointb, ' and tb_f_mcustomers_group_d.codigo = ', @grupo) ;
	else
		set @jointb = '' ;
	end if ;
	
    set @estatus = concat(' and ', case when coalesce(_estatus_plus, '') = ''
							then
								case when coalesce(_estatus, '') = ''
										then 'tb_f_osales_orders.estado >= 1 '
										else concat('tb_f_osales_orders.estado = ', _estatus)
									end
							else concat('tb_f_osales_orders.estado >= ', case when _estatus = '' then 1 else _estatus end)
						end );
   
    set @cadena = concat(' where tb_f_osales_orders.codemp = ', _codemp) ;
	if trim(_sucursal) <> '' then
		set @cadena = concat(@cadena, ' and tb_f_osales_orders.sucursal = ', _sucursal) ;
	end if ;
    set @cadena = concat(@cadena, ' and tb_f_osales_orders.', @fecha_tipo, ' between "',@desde,'" and "',@hasta,'"') ;
	if (coalesce(_cliente, '') != '') then
		set @cadena = concat(@cadena, ' and tb_f_osales_orders.cliente = "',  trim(_cliente), '"');
    end if ;
    set @cadena = concat(@cadena, ' and tb_f_osales_orders.ocultar = 0') ;
    set @cadena = concat(@cadena, @estatus) ;
    
	drop temporary table if exists f_osales_orders ;	
	set @cSentencia = concat('create temporary table f_osales_orders select tb_f_osales_orders.* from tb_f_osales_orders ',  @jointb, @cadena ) ;
	
    prepare f_osales_orders from @cSentencia ;
	execute f_osales_orders ;
	deallocate prepare f_osales_orders ;
	
    -- ----------------------------------------------------------------------------------------------------
    select	coalesce(tb_f_mcustomers.nombre, '') as ncustomer,
			f_osales_orders.*,
            coalesce(cfg_mestado.nombre, '') as nestado
		from f_osales_orders
			left join tb_f_mcustomers
				on f_osales_orders.codemp = tb_f_mcustomers.codemp
					and f_osales_orders.sucursal = tb_f_mcustomers.sucursal
                    and f_osales_orders.cliente = tb_f_mcustomers.codigo
			left join cfg_mestado
				on f_osales_orders.codemp = cfg_mestado.codemp
					and f_osales_orders.estado = cfg_mestado.codigo
                    and cfg_mestado.tipo = 'GEN'
		order by coalesce(tb_f_mcustomers.nombre, ''), f_osales_orders.numero ;
	
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_rep_f_osales_orders_cliente_d_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_rep_f_osales_orders_cliente_d_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _desde varchar(10), 
	in _hasta varchar(10), 
    in _fecha_t smallint(1),
	in _cliente varchar(15),
    in _estatus char(1),
    in _estatus_plus char(1),
    in _usuario varchar(5)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Reporte de Sales Orders Detail
		Versión 1.0
		Creado: 2025-08-31
		Actualizado: (Iluminado) 2025-09-15, 2025-09-27
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
	set @desde = str_to_date(_desde , '%m/%d/%Y') ;
	set @hasta = str_to_date(_hasta, '%m/%d/%Y') ;
    select trim(coalesce(campo, 'fecha')) into @fecha_tipo
		from cfg_mfecha_tipo
        where codigo = coalesce(_fecha_t, 8) ;
	
	set @usuario = coalesce(_usuario) ;
	select	coalesce(u218, '') into @grupo
		from tb_musuario
		where u201 = @usuario ;
	
	if coalesce(@grupo, '') <> '' then
		set @jointb = 'inner join tb_f_mcustomers_group_d' ;
		set @jointb = concat(@jointb, ' on tb_f_osales_orders.codemp = tb_f_mcustomers_group_d.codemp') ;
		set @jointb = concat(@jointb, ' and tb_f_osales_orders.sucursal = tb_f_mcustomers_group_d.sucursal') ;
		set @jointb = concat(@jointb, ' and tb_f_osales_orders.cliente = tb_f_mcustomers_group_d.cliente') ;
		set @jointb = concat(@jointb, ' and tb_f_mcustomers_group_d.codigo = ', @grupo) ;
	else
		set @jointb = '';
	end if ;
    
    set @estatus = concat(' and ', case when coalesce(_estatus_plus, '') = ''
							then
								case when coalesce(_estatus, '') = ''
										then 'tb_f_osales_orders.estado >= 1 '
										else concat('tb_f_osales_orders.estado = ', _estatus)
									end
							else concat('tb_f_osales_orders.estado >= ', case when _estatus = '' then 1 else _estatus end)
						end );
	
    set @cadena = concat(' where tb_f_osales_orders.codemp = ', _codemp);
	if trim(_sucursal) <> '' then
		set @cadena = concat(@cadena, ' and tb_f_osales_orders.sucursal = ', _sucursal);
	end if;
    set @cadena = concat(@cadena, ' and tb_f_osales_orders.', @fecha_tipo, ' between "',@desde,'" and "',@hasta,'"') ;
    if (coalesce(_cliente, '') != '') then
		set @cadena = concat(@cadena, ' and tb_f_osales_orders.cliente = "',  trim(_cliente), '"');
    end if ;
    set @cadena = concat(@cadena, ' and tb_f_osales_orders.ocultar = 0') ;
    set @cadena = concat(@cadena, @estatus) ;
	
	drop temporary table if exists f_osales_orders ;
	set @cSentencia = concat('create temporary table f_osales_orders select tb_f_osales_orders.* from tb_f_osales_orders ', @jointb, @cadena ) ;
	
    prepare f_osales_orders from @cSentencia ;
	execute f_osales_orders ;
	deallocate prepare f_osales_orders ;
	
    -- ----------------------------------------------------------------------------------------------------
    select	coalesce(tb_f_mcustomers.nombre, '') as ncustomer,
			f_osales_orders.codemp, 
            f_osales_orders.sucursal, 
            f_osales_orders.numero, 
            f_osales_orders.fecha, 
            f_osales_orders.fecha_u, 
            f_osales_orders.cliente, 
            f_osales_orders.estatus, 
            f_osales_orders.estado,
            f_osales_orders.referencia,
            tb_f_osales_dproducts.producto, 
            coalesce(tb_a_mproducts.nombre, '') as nproducto,
            tb_f_osales_dproducts.cantidad_fac, 
            tb_f_osales_dproducts.cantidad_ord, 
            tb_f_osales_dproducts.cantidad_res, 
            tb_f_osales_dproducts.cantidad_env, 
            tb_f_osales_dproducts.fecha_ent, 
            tb_f_osales_dproducts.fecha_req, 
            tb_f_osales_dproducts.fecha_pfe,
            tb_f_osales_dproducts.fecha_env,  
            tb_f_osales_dproducts.nota, 
            tb_f_osales_dproducts.costo_unitario, 
            tb_f_osales_dproducts.unidad_medida,
            coalesce(cfg_mestado.nombre, '') as nestado
		from f_osales_orders
			inner join tb_f_osales_dproducts
				on f_osales_orders.codemp = tb_f_osales_dproducts.codemp
					and f_osales_orders.sucursal = tb_f_osales_dproducts.sucursal
                    and f_osales_orders.numero = tb_f_osales_dproducts.numero
			left join tb_f_mcustomers
				on f_osales_orders.codemp = tb_f_mcustomers.codemp
					and f_osales_orders.sucursal = tb_f_mcustomers.sucursal
                    and f_osales_orders.cliente = tb_f_mcustomers.codigo
			left join tb_a_mproducts
				on tb_f_osales_dproducts.codemp = tb_a_mproducts.codemp
					and tb_f_osales_dproducts.sucursal = tb_a_mproducts.sucursal
                    and tb_f_osales_dproducts.producto = tb_a_mproducts.codigo
			left join cfg_mestado
				on f_osales_orders.codemp = cfg_mestado.codemp
					and f_osales_orders.estado = cfg_mestado.codigo
                    and cfg_mestado.tipo = 'GEN'
		order by coalesce(tb_f_mcustomers.nombre, ''), f_osales_orders.numero, tb_f_osales_dproducts.producto ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_rep_f_osales_orders_d_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_rep_f_osales_orders_d_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _desde varchar(10), 
	in _hasta varchar(10), 
    in _fecha_t smallint(1),
	in _cliente varchar(15),
    in _estatus char(1),
    in _estatus_plus char(1),
    in _usuario varchar(5)
)
begin
	/* ----------------------------------------------------------------------------------------------------
		Reporte de Sales Orders Detail
		Versión 1.0
		Creado: 2025-08-31
		Actualizado: (Iluminado) 2025-09-15
		Autor: Custom Systems Solutions LLC
	---------------------------------------------------------------------------------------------------- */
    
	set @desde = str_to_date(_desde , '%m/%d/%Y'); 
	set @hasta = str_to_date(_hasta, '%m/%d/%Y'); 
    select trim(coalesce(campo, 'fecha')) into @fecha_tipo
		from cfg_mfecha_tipo
        where codigo = coalesce(_fecha_t, 8) ;
        
    set @estatus = concat(' and ', case when coalesce(_estatus_plus, '') = ''
							then 
								case when coalesce(_estatus, 0) = ''
										then 'estado >= 1 ' 
										else concat('estado = ', coalesce(_estatus, 0))
									end
							else concat('estado >= ', case when _estatus = '' then 1 else _estatus end) 
						end );
                        
    set @cadena = concat(' where codemp = ', _codemp);
	if trim(_sucursal) <> '' then
		set @cadena = concat(@cadena, ' and sucursal = ', _sucursal);
	end if;
    
    set @cadena = concat(@cadena, ' and ', @fecha_tipo, ' between "',@desde,'" and "',@hasta,'"');
    if (coalesce(_cliente, '') != '') then
		set @cadena = concat(@cadena, ' and cliente = "',  trim(_cliente), '"');
    end if ;
    -- set @cadena = concat(@cadena, ' and estado between 4 and 5');
    set @cadena = concat(@cadena, @estatus) ;
    
	drop temporary table if exists f_osales_orders ;	
	set @cSentencia = concat('create temporary table f_osales_orders select * from tb_f_osales_orders ', @cadena );
	
    prepare f_osales_orders from @cSentencia ;
	execute f_osales_orders ;
	deallocate prepare f_osales_orders ;
	
    -- ----------------------------------------------------------------------------------------------------
    select	coalesce(tb_f_mcustomers.nombre, '') as ncustomer,
			f_osales_orders.codemp, 
            f_osales_orders.sucursal, 
            f_osales_orders.numero, 
            f_osales_orders.fecha, 
            f_osales_orders.fecha_u, 
            f_osales_orders.cliente, 
            f_osales_orders.estatus, 
            f_osales_orders.estado,
            f_osales_orders.referencia,
            tb_f_osales_dproducts.producto, 
            coalesce(tb_a_mproducts.nombre, '') as nproducto,
            tb_f_osales_dproducts.cantidad_fac, 
            tb_f_osales_dproducts.cantidad_ord, 
            tb_f_osales_dproducts.cantidad_res, 
            tb_f_osales_dproducts.cantidad_env, 
            tb_f_osales_dproducts.fecha_ent, 
            tb_f_osales_dproducts.fecha_req, 
            tb_f_osales_dproducts.fecha_pfe,
            tb_f_osales_dproducts.fecha_env,  
            tb_f_osales_dproducts.nota, 
            tb_f_osales_dproducts.costo_unitario, 
            -- round(tb_f_osales_dproducts.costo_unitario * tb_f_osales_dproducts.cantidad_ord, 2) as total_ord,
            -- round(tb_f_osales_dproducts.costo_unitario * tb_f_osales_dproducts.cantidad_env, 2) as total_env,
            -- round(tb_f_osales_dproducts.costo_unitario * tb_f_osales_dproducts.cantidad_fac, 2) as total_fac,
            tb_f_osales_dproducts.unidad_medida,
            coalesce(cfg_mestado.nombre, '') as nestado
		from f_osales_orders
			inner join tb_f_osales_dproducts
				on f_osales_orders.codemp = tb_f_osales_dproducts.codemp
					and f_osales_orders.sucursal = tb_f_osales_dproducts.sucursal
                    and f_osales_orders.numero = tb_f_osales_dproducts.numero
			left join tb_f_mcustomers
				on f_osales_orders.codemp = tb_f_mcustomers.codemp
					and f_osales_orders.sucursal = tb_f_mcustomers.sucursal
                    and f_osales_orders.cliente = tb_f_mcustomers.codigo
			left join tb_a_mproducts
				on tb_f_osales_dproducts.codemp = tb_a_mproducts.codemp
					and tb_f_osales_dproducts.sucursal = tb_a_mproducts.sucursal
                    and tb_f_osales_dproducts.producto = tb_a_mproducts.codigo
			left join cfg_mestado
				on f_osales_orders.codemp = cfg_mestado.codemp
					and f_osales_orders.estado = cfg_mestado.codigo
                    and cfg_mestado.tipo = 'GEN'
		order by coalesce(tb_f_mcustomers.nombre, ''), f_osales_orders.numero, tb_f_osales_dproducts.producto ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_rep_g_dfecha_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_rep_g_dfecha_c`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
	in _fecha_desde varchar(10), 
	in _fecha_hasta varchar(10), 
	in _nulo varchar(1),
	in _nulo1 varchar(1)
)
begin
	-- ----------------------------------------------------
	-- consulta reporte de presupuestos
	-- Versión 1.0
	-- Creado: 11/07/2017
	-- Actualizado: 2024.04.13, 11/07/2017
	-- Autor: 
	-- ----------------------------------------------------
	    
	select 	_codemp as codemp,
			_sucursal as sucursal,
            @nusuario as nsuaurio,
            _fecha_desde as desde,
            _fecha_hasta as hasta ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_s_log_sync_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_s_log_sync_u`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
	in _origen varchar(50), 
	in _operacion varchar(1),
	in _descripcion varchar(255),
    in _numero varchar(25)
)
begin
	-- ----------------------------------------------------
	-- actualiza los datos del log
	-- versión 1.0
	-- Creado: 2025-09-10
	-- Actualizado: 2025-09-10
	-- Autor: 
	-- ----------------------------------------------------
	
	insert into tb_s_log_sync (codemp, sucursal, origen, fecha, operacion, descripcion, numero)
    select _codemp, _sucursal, _origen, now(), _operacion, _descripcion, _numero;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_s_log_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_s_log_u`(
	in _codemp varchar(2), 
	in _sucursal varchar(3),
	in _formulario varchar(10),
	in _usuario varchar(10),
	in _referencia varchar(50), 
	in _operacion varchar(1),
	in _descripcion varchar(255),
	in _ip varchar(50), 
	in _browser varchar(50), 
	in _browser_version varchar(50), 
	in _os varchar(100),
	in _ciudad varchar(100),
	in _estado_ciudad varchar(100),
	in _pais varchar(100),
	in _latitud varchar(45),
	in _longitud varchar(45),
	in _vpn varchar(5)    
)
begin
	-- ----------------------------------------------------
	-- actualiza los datos del log
	-- versión 1.0
	-- Creado: 13/08/2015
	-- Actualizado: 2024.04.13, 20/02/2017, 2024.12.21, 2025-05-16
	-- Autor: 
	-- ----------------------------------------------------
	
	insert into tb_s_log (codemp, sucursal, formulario, usuario, referencia, fecha, operacion, descripcion, ip, browser, browser_version, os, ciudad, estado_ciudad, pais, latitud, longitud, vpn) 
		select _codemp, _sucursal, _formulario, _usuario, _referencia, now(), _operacion, _descripcion, _ip, _browser, _browser_version, _os, _ciudad, _estado_ciudad, _pais, _latitud, _longitud, _vpn;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sp_tdocumento_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sp_tdocumento_u`(
	in _tabla varchar(50), 
    in _repetir int(10), 
    in _tipo int(1), 
    out _valor varchar(11)
)
begin
	/* ---------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2024.12.16
		Autor: 
	--------------------------------------------------- */
    
	declare _largo int(10);
	declare _ultimo int(10);
	declare _codigo varchar(10);
	declare _year varchar(4) ;
	set _year = '' ;
    
	if coalesce(_tipo, 0) = 2 then
		set _year = concat(substring(curdate(), 1, 4), '/') ;
		set _tabla = concat(_tabla, '-', substring(_year, 1, 4)) ;
	end if;
	if (select coAlesCE(CoUnT(*), 0) from tb_tdocumento where nombre = _tabla) = 0 then
		insert into tb_tdocumento (nombre, numero) ValueS (_tabla, 0);
	end if;

    update tb_tdocumento 
		set 
			numero = numero + 1 
		where nombre = _tabla;
        
    select coaLEsce(numero, 0) into _ultimo 
		from tb_tdocumento 
        where nombre = _tabla;
        
	set _valor = concat(_year, repEAT('0',  _repetir - LENgth(Trim(_ultimo))), trim(_ultimo));
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `sql_prepare` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `sql_prepare`(
	in _tabla varchar(50),
	in _sql_query varchar(8000)
)
begin
	/* ---------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2024.12.16, 2024.12.26, 2024.12.29
		Autor: 
	--------------------------------------------------- */
    
	-- Validación de parámetros
    if (_tabla is not null) or (_sql_query is not null) then
		-- Preparar y ejecutar la consulta dinámica
		set @tabla = coalesce(_tabla, '') ; 
		set @sql_where = coalesce(_sql_query, '') ; 
		set @sql_query = concat('create temporary table sql_tabla select * from ', trim(@tabla), @sql_where);
		
		-- ---------------------------------------------------
		drop temporary table if exists sql_tabla ;
		prepare sql_tabla from @sql_query;
		execute sql_tabla;
		deallocate prepare sql_tabla;
        set @sql_query = null ;
	else
		select -1 ;
	end if ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `str_cadena` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `str_cadena`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _tabla varchar(100), 
	in _tablaBA varchar(25), 
	in _jointb varchar(2000),
	in _camposA varchar(1000), 
	in _camposB varchar(1000),
	in _ordenado varchar(50), 
	in _bCampos varchar(1000), 
	in _operador varchar(6), 
	in _valor varchar(100), 
	in _pagina int, 
	in _regpp int, 
	in _adicional varchar(5000), 
	in _tipo_estado varchar(3),
	in _estado int,
	in _desde varchar(10),
	in _hasta varchar(10),
	in _tipoBusq int(1),
	out _cResultado Varchar(5000)
)
begin
	/* ------------------------------------------------------------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2024.12.16, 2024.12.29, 2025.01.21, 2025-05-06
		Autor: 
	------------------------------------------------------------------------------------------------------ */
    
	-- Validación de parámetros
	set @iLimite = coalesce(_regpp, 25) ;
	set @iPagina = coalesce(_pagina, 1) ;
	set @iLimiteInicio = ((@iPagina - 1) * @iLimite) ;
	set @nRowTotal = 0 ;
	set @Fila = 0 ;
	
	set @cResultadoA = '' ;
	set @cResultadoB = '' ;
	set @cResultadoC = '' ;
	set @cResultadoI = '' ;
	set @cResultadoT = '' ;
	set @parent = ')' ;
	
	set @sucursal = '' ;
	set @tabla = concat(trim(_tabla), '.') ;
	set @tablaBA = concat(trim(_tablaBA), '.') ;
	set @valor = coalesce(trim(_valor), '') ;
	set @bCampos = coalesce(trim(_bCampos), '') ;
	set @operador = coalesce(_operador, '') ;
	set @tipoBusq = coalesce(_tipoBusq, 0) ;
    set @jointb = coalesce(trim(_jointb), '') ;
    set @adicional = coalesce(trim(_adicional), '') ;
	set @cJoinOrdenB = '' ;
	set @cJoinCampoO = '' ;
    
	-- ----------------------------------------------------------------------------------------------
	-- Proceso para Ordenar la consulta de la tabla
	
	if coalesce(_ordenado, '') = 'ncliente' then
		set @cJoinOrdenB = concat(' left join tb_f_mcliente on ', @tabla, 'codemp = tb_f_mcliente.codemp and ', @tabla, 'sucursal = tb_f_mcliente.sucursal and ', @tabla, 'cliente = tb_f_mcliente.codigo ') ; 
		set @cJoinCampoO = concat(', tb_f_mcliente.nombre') ; 
		set @cOrdenado = concat(' order by tb_f_mcliente.nombre') ;
	elseif coalesce(_ordenado, '') = 'ncustomer' then
		set @cJoinOrdenB = concat(' left join tb_f_mcustomers on ', @tabla, 'codemp = tb_f_mcustomers.codemp and ', @tabla, 'sucursal = tb_f_mcustomers.sucursal and ', @tabla, 'cliente = tb_f_mcustomers.codigo ') ; 
		set @cJoinCampoO = concat(', tb_f_mcustomers.nombre') ; 
		set @cOrdenado = concat(' order by tb_f_mcliente.nombre') ;
	elseif coalesce(_ordenado, '') = 'nplantilla' then
		set @cJoinOrdenB = concat(' left join tb_f_mplantilla on ', @tabla, 'codemp = tb_f_mplantilla.codemp and ', @tabla, 'sucursal = tb_f_mplantilla.sucursal and ', @tabla, 'plantilla = tb_f_mplantilla.codigo ') ; 
		set @cJoinCampoO = concat(', tb_f_mplantilla.codigo') ; 
		set @cOrdenado = concat(' order by tb_f_mplantilla.nombre') ;
	elseif coalesce(_ordenado, '') = 'ngrupo' then
		set @cJoinOrdenB = concat(' left join tb_f_mgrupo on ', @tabla, 'codemp = tb_f_mgrupo.codemp and ', @tabla, 'sucursal = tb_f_mgrupo.sucursal and ', @tabla, 'grupo = tb_f_mgrupo.codigo ') ; 
		set @cJoinCampoO = concat(', tb_f_mgrupo.nombre') ; 
		set @cOrdenado = concat(' order by tb_f_mgrupo.nombre') ;
	elseif coalesce(_ordenado, '') = 'npersonal' then
		set @cJoinOrdenB = concat(' left join tb_f_mpersonal on ', @tabla, 'codemp = tb_f_mpersonal.codemp and ', @tabla, 'sucursal = tb_f_mpersonal.sucursal and ', @tabla, 'personal = tb_f_mpersonal.codigo ') ; 
		set @cJoinCampoO = concat(', tb_f_mpersonal.nombre') ; 
		set @cOrdenado = concat(' order by tb_f_mpersonal.nombre') ;
	elseif coalesce(_ordenado, '') = 'nrole' then
		set @cJoinOrdenB = concat(' left join tb_f_mrole on ', @tabla, 'codemp = tb_f_mrole.codemp and ', @tabla, 'sucursal = tb_f_mrole.sucursal and ', @tabla, 'role = tb_f_mrole.codigo ') ; 
		set @cJoinCampoO = concat(', tb_f_mrole.nombre') ; 
		set @cOrdenado = concat(' order by tb_f_mrole.nombre') ;
	elseif coalesce(_ordenado, '') = 'nproyecto' then
		set @cJoinOrdenB = concat(' left join tb_f_mproyecto on ', @tabla, 'codemp = tb_f_mproyecto.codemp and ', @tabla, 'sucursal = tb_f_mproyecto.sucursal and ', @tabla, 'proyecto = tb_f_mproyecto.codigo ') ; 
		set @cJoinCampoO = concat(', tb_f_mproyecto.nombre') ; 
		set @cOrdenado = concat(' order by tb_f_mproyecto.nombre') ;
	elseif coalesce(_ordenado, '') = 'nsupervisor' then
		set @cJoinOrdenB = concat(' left join tb_f_msupervisor on ', @tabla, 'codemp = tb_f_msupervisor.codemp and ', @tabla, 'sucursal = tb_f_msupervisor.sucursal and ', @tabla, 'supervisor = tb_f_msupervisor.codigo ') ; 
		set @cJoinCampoO = concat(', tb_f_msupervisor.nombre') ; 
		set @cOrdenado = concat(' order by tb_f_msupervisor.nombre') ;
	else 
		set @cOrdenado = concat(' order by ',  @tabla, _ordenado) ;
		set @cJoinCampoO = concat(', ', @tabla, _ordenado) ; 
	end if ;
	set @cJoinCampoO = concat(@cJoinCampoO, '  as xOrdenado') ; 
	-- ----------------------------------------------------------------------------------------------
	-- Se crea una cadena para filtral por empresa y sucursal
	set @empresa = concat(' where ', @tabla, 'codemp = ', _codemp);
	if trim(_sucursal) <> '' then
		set @sucursal = concat(' and ', @tabla, 'sucursal = ', _sucursal);
	end if;
	
	-- ----------------------------------------------------------------------------------------------
	-- Crea dos cadena: 
	-- 		cResultadoIniciar: 	realizar la búsqueda de los registros que se mostraran como resultado final segun los parametros indicados
	-- 		cResultadoTotales: 	realiza una consulta para obtener el total de registro en la consulta por medio de un COUNT(*)
	-- 		COUNT(*):			sustituye la funcion SQL_CALC_FOUND_ROWS, dado que el FOUND_ROWS() no funciona ahora con el prepare y deallocate prepare
	--
	
	set @cResultadoIniciar = concat('create temporary table sentencia select ', @tabla, '*, (@fila:= @fila + 1) as RegFila',  @cJoinCampoO) ;
	set @cResultadoTotales = concat('create temporary table sentencia select COUNT(*) total_filas ');
	if coalesce(_camposB, '') <> '' then
		set @cResultadoA = concat(@cResultadoA, _camposB) ;
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	set @cResultadoA = concat(@cResultadoA, '  from ', _tabla) ;
	if coalesce(@jointb, '') <> '' then
		set @cResultadoA = concat(@cResultadoA, ' ', coalesce(@jointb, ''), ' ');
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Agrega el LEFT JOIN de la Tabla por la que ordenara la busqueda.
	set @cResultadoA = concat(@cResultadoA, ' ', coalesce(@cJoinOrdenB, '') ) ;
	
	-- ----------------------------------------------------------------------------------------------
	set @cResultadoA = concat(@cResultadoA, @empresa, @sucursal) ;
	if trim(coalesce(@adicional, '')) <> '' then
		set @cResultadoA = concat(@cResultadoA, ' and ', @tablaBA, trim(@adicional));
	end if;
	
	if coalesce(_estado, 0) > 0 then
		set @cResultadoA = concat(@cResultadoA, ' and ', @tabla, 'estado = ', coalesce(_estado, 0));
	else 
		set @cResultadoA = concat(@cResultadoA, ' and ', @tabla, 'estado > 0 ');
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	-- De pasar la fecha como parametro, se incluye la opción para el rango de fecha
	--
	if trim(coalesce(_desde, '')) <> '' and _tipoBusq = 1 then
		set @desde = STR_TO_DATE(Trim(_desde), '%m/%d/%Y');
		set @hasta = STR_TO_DATE(Trim(_hasta), '%m/%d/%Y');
        if (@tabla = 'tb_f_otimesheet.') then
			set @cResultadoA = CONCAT(@cResultadoA, ' and ', @tabla, 'fecha_d between ', QUOTE(@desde), ' and ', QUOTE(@hasta));
        else
			set @cResultadoA = CONCAT(@cResultadoA, ' and ', @tabla, 'fecha between ', QUOTE(@desde), ' and ', QUOTE(@hasta));
		end if ;
	end if ;
	
	if trim(@valor) <> '' then
		if @tipoBusq = 1 then
			-- ----------------------------------------------------------------------------------------------
			-- Según el campo por el que se realizará la búsqueda, se anexará a la cadena validado por la tabla del maestro que lo rige
			-- es importante que el campo a validar en la búsqueda se encuentre dentro de las siguientes opciones, de lo contrario se deberá anexar
			-- para que se incorpore a la cadena.
			--
			if @bCampos = 'numero' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'numero ') ;
				set @parent = '' ;
			elseif @bCampos = 'referencia' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'referencia ') ;
				set @parent = '' ;
			elseif @bCampos = 'seguimiento' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'seguimiento ') ;
				set @parent = '' ;
			elseif @bCampos = 'contacto' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'contacto ') ;
				set @parent = '' ;
			elseif @bCampos = 'zcode' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'zcode ') ;
				set @parent = '' ;
			elseif @bCampos = 'email' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'email ') ;
				set @parent = '' ;
			elseif @bCampos = 'telefono' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'telefono ') ;
				set @parent = '' ;
			elseif @bCampos = 'usuario' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'usuario in (select u201 from tb_musuario where u202 ') ;
			elseif @bCampos = 'nusuario' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'usuario in (select u201 from tb_musuario where u202 ') ;
			elseif @bCampos = 'cliente' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' cliente in (select codigo from tb_f_mcliente ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'ncliente' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' cliente in (select codigo from tb_f_mcliente ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'ncustomer' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' cliente in (select codigo from tb_f_mcustomers ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'nvendor' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' proveedor in (select codigo from tb_f_mvendors ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'plantilla' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' plantilla in (select codigo from tb_f_mplantilla ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'nplantilla' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' plantilla in (select codigo from tb_f_mplantilla ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'grupo' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' grupo in (select codigo from tb_f_mgrupo ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'ngrupo' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' grupo in (select codigo from tb_f_mgrupo ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'personal' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' personal in (select codigo from tb_f_mpersonal ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'npersonal' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' personal in (select codigo from tb_f_mpersonal ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'proyecto' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' proyecto in (select codigo from tb_f_mproyecto ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'nproyecto' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' proyecto in (select codigo from tb_f_mproyecto ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'role' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' role in (select codigo from tb_f_mrole ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'nrole' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' role in (select codigo from tb_f_mrole ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'supervisor' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' supervisor in (select codigo from tb_f_msupervisor ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'nsupervisor' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' supervisor in (select codigo from tb_f_msupervisor ', @empresa, @sucursal,' and nombre ') ;
			else
				set @cResultadoB = @cResultadoB ;
			end if ;
		else	
			set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, @bCampos) ;
			set @parent = '' ;
		end if ;
		
		-- ----------------------------------------------------------------------------------------------
		-- Valida el operador a utilizar para comparar el campo vs el valor
		if @operador = 'LIKE' then
			set @cResultadoB = concat(@cResultadoB, ' LIKE ', '''', '%', trim(@valor), '%', '''') ;
		elseif @operador = 'REGEXP' then
			set @cResultadoB = concat(@cResultadoB, ' REGEXP ', '''', trim(@valor), '''') ;
		else
			set @cResultadoB = concat(@cResultadoB, trim(@operador), '''', trim(@valor), '''') ;
		end if;
	else
		-- ----------------------------------------------------------------------------------------------
		-- En caso que no se requiera validar con un maestro, la variable pasa a ser en blanco y un ')' como valor predeterminado
		set @parent = '' ;
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Integra todas las cadenas armadas para construir el cursor.
	--
	set @cResultadoB = concat(@cResultadoB, @parent) ;
	if coalesce(_regpp, 0) <> 0 then
		set @cResultadoC = concat(' LIMIT ', @iLimiteInicio, ', ',  @iLimite) ;
	else
		set @cResultadoC = '' ;
	end if ;
	-- set @cResultado = concat(@cResultadoA, @cResultadoB, @cOrdenado, @cResultadoC) ;
	set @cResultado = concat(@cResultadoA, @cResultadoB, @cOrdenado, @cResultadoC) ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Se construye la cadena para obtener el Total de Registros.
	set @cResultadoT = concat(@cResultadoTotales, @cResultadoA, @cResultadoB, @cOrdenado);
	
    drop temporary table if exists sentencia ;
	prepare sentencia from @cResultadoT ;
	execute sentencia ;
	deallocate prepare sentencia;
	
	-- ----------------------------------------------------------------------------------------------
	-- Se construye la cadena para obtener los registros, y se anexa la variable con el total de registros de
	-- @cResultadoT
	select total_filas into @iNumeroFila from sentencia;
	set @iPaginaUltima =  round((@iNumeroFila/@iLimite), 0) ;
	if coalesce(@iPaginaUltima, 0) = 0 then
		set @iPaginaUltima = 1 ;
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Se construye la cadena para realizar la consulta de los registros a mostrar en la Lista Formulario
	-- segun los parametros indicados.
	-- Se agrega la variable @iPaginaUltima a la cadena antes de realizar la consulta a través del Prepare.
	set @cResultadoI = concat(@cResultadoIniciar, ', @iPagina as PagAct, @iNumeroFila as Filas, round(@iPaginaUltima,0) as PagUltima ', @cResultado);
    -- select @cResultadoI ;
    
	drop temporary table if exists sentencia ;
	prepare sentencia from @cResultadoI ;
	execute sentencia ;
	deallocate prepare sentencia;
	
    -- ----------------------------------------------------------------------------------------------
    -- La Cadena de consulta que se devolvera estara vacia, dado que ya no se requiere.
    -- ----------------------------------------------------------------------------------------------
    -- set _cResultado = '';
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `str_cadena_ba` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `str_cadena_ba`(
	in _codemp varchar(2),
	in _sucursal varchar(3),
	in _tabla varchar(25),
	in _bcampos varchar(25),
	in _operador varchar(25),
	in _valor varchar(100),
	in _tipoBusq int(1),
	out _cresultado varchar(1500)
)
begin
	/* ---------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2024.12.16
		Autor: 
	--------------------------------------------------- */
    
	-- Validación de parámetros
    if (_codemp is null) OR (_sucursal is null) or (_tabla is null) or (_bcampos is null)  or (_operador is null) then
        signal sqlstate '45000'
            set message_text = 'Parámetros incompletos. Todos los campos deben estar especificados.';
    end if ;
    
	set @cResultado = '' ;
	set @parent = ')' ;
	set @tabla = concat(trim(_tabla), '.') ;
	set @valor = coalesce(_valor, '') ;
	set @bCampos = coalesce(_bCampos, '') ;
	set @operador = coalesce(_operador, '') ;
	set @tipoBusq = coalesce(_tipoBusq, 0) ;
	set @sucursal = '' ;
	
	set @empresa = concat(' where codemp = ', coalesce(_codemp, '')) ;
	if trim(coalesce(_sucursal, '')) <> '' then
		set @sucursal = concat(' and sucursal = ', coalesce(_sucursal, '')) ;
	end if ;
	
	if trim(@valor) <> '' then
		if @tipoBusq = 1 then
			-- ----------------------------------------------------------------------------------------------
			-- según el campo que pasamos como parámetro, se anexará a la cadena la búsqueda según el maestro o campo indicado.
			if @bCampos = 'apellido' then
				set @cResultado = concat(@cResultado, ' and ', @tabla, 'historia in (select historia from tb_m_mpaciente ', @empresa, @sucursal, ' and apellido ' ) ;
			end if ;
			if @bCampos = 'nombre' then
				set @cResultado = concat(@cResultado, ' and ', @tabla, 'historia in (select historia from tb_m_mpaciente ', @empresa, @sucursal,' and nombre ' ) ;
			end if ;
			if @bCampos = 'cedula' then
				set @cResultado = concat(@cResultado, ' and ', @tabla, 'historia in (select historia from tb_m_mpaciente ', @empresa, @sucursal,' and cedula ' ) ;
			end if ;
			if @bCampos = 'medico' then
				set @cResultado = concat(@cResultado, ' and ', @tabla,' medico in (select codigo from tb_m_mprofesional ', @empresa, @sucursal,' and nombre ') ;
			end if ;
			if @bCampos = 'nmedico' then
				set @cResultado = concat(@cResultado, ' and ', @tabla,' medico in (select codigo from tb_m_mprofesional ', @empresa, @sucursal,' and nombre ') ;
			end if ;
			if @bCampos = 'procedimiento' then
				set @cResultado = concat(@cResultado, ' and ', @tabla, 'procedimiento in (select codigo from tb_m_mprocedimiento ', @empresa, @sucursal,' and nombre ') ;
			end if ;
			if @bCampos = 'nprocedimiento' then
				set @cResultado = concat(@cResultado, ' and ', @tabla, 'procedimiento in (select codigo from tb_m_mprocedimiento ', @empresa, @sucursal,' and nombre ') ;
			end if ;
			if @bCampos = 'servicio_ntipo' then
				set @cResultado = concat(@cResultado, ' and ', @tabla, 'tipo in (select codigo from tb_m_mservicio_tipo ', @empresa, @sucursal,' and nombre ') ;
			end if ;
			if @bCampos = 'numero' then
				set @cResultado = concat(@cResultado, ' and ', @tabla, 'numero ') ;
				set @parent = '' ;
			end if ;
			if @bCampos = 'presupuesto' then
				set @cResultado = concat(@cResultado, ' and ', @tabla, 'presupuesto ') ;
				set @parent = '' ;
			end if ;
			if @bCampos = 'historia' then
				set @cResultado = concat(@cResultado, ' and ', @tabla, 'historia ') ;
				set @parent = '' ;
			end if ;
		else
			set @cResultado = concat(@cResultado, ' and ', @tabla, @bCampos) ;
			set @parent = '' ;
		end if ;
		-- ----------------------------------------------------------------------------------------------
		-- Valida el operador a utilizar para comparar el campo vs el valor
		if @operador = 'LIKE' then
			set @cResultado = concat(@cResultado, ' LIKE ', '''', '%', trim(@valor), '%', '''') ;
		elseif @operador = 'REGEXP' then
			set @cResultado = concat(@cResultado, ' REGEXP ', '''', trim(@valor), '''') ;
		else
			set @cResultado = concat(@cResultado, trim(@operador), '''', trim(@valor), '''') ;
		end if;
	else
		set @parent = '' ;
	end if ;
	
	set @cResultado = concat(@cResultado, @parent) ;
	set _cResultado = @cResultado ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `str_cadena_campo_extra` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `str_cadena_campo_extra`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _tabla varchar(100), 
	in _tablaBA varchar(25), 
	in _jointb varchar(2000),
	in _camposA varchar(1000), 
	in _camposB varchar(1000),
	in _ordenado varchar(50), 
	in _bCampos varchar(1000), 
	in _operador varchar(6), 
	in _valor varchar(100), 
	in _pagina int, 
	in _regpp int, 
	in _adicional varchar(5000), 
    in _campoextra varchar(5000), 
	in _tipo_estado varchar(3),
	in _estado int,
	in _desde varchar(10),
	in _hasta varchar(10),
	in _tipoBusq int(1),
	out _cResultado Varchar(5000)
)
begin
	/* ------------------------------------------------------------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2024.12.16, 2024.12.29, 2025.01.21, 2025-05-06
		Autor: 
	------------------------------------------------------------------------------------------------------ */
    
	-- Validación de parámetros
	set @iLimite = coalesce(_regpp, 25) ;
	set @iPagina = coalesce(_pagina, 1) ;
	set @iLimiteInicio = ((@iPagina - 1) * @iLimite) ;
	set @nRowTotal = 0 ;
	set @Fila = 0 ;
	
	set @cResultadoA = '' ;
	set @cResultadoB = '' ;
	set @cResultadoC = '' ;
	set @cResultadoI = '' ;
	set @cResultadoT = '' ;
	set @parent = ')' ;
	
	set @sucursal = '' ;
	set @tabla = concat(trim(_tabla), '.') ;
	set @tablaBA = concat(trim(_tablaBA), '.') ;
	set @valor = coalesce(trim(_valor), '') ;
	set @bCampos = coalesce(trim(_bCampos), '') ;
	set @operador = coalesce(_operador, '') ;
	set @tipoBusq = coalesce(_tipoBusq, 0) ;
    set @jointb = coalesce(trim(_jointb), '') ;
    set @adicional = coalesce(trim(_adicional), '') ;
    set @campoextra = coalesce(trim(_campoextra), '') ;
	set @cJoinOrdenB = '' ;
	set @cJoinCampoO = '' ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Proceso para Ordenar la consulta de la tabla
	
	if coalesce(_ordenado, '') = 'ncliente' then
		set @cJoinOrdenB = concat(' left join tb_f_mcliente on ', @tabla, 'codemp = tb_f_mcliente.codemp and ', @tabla, 'sucursal = tb_f_mcliente.sucursal and ', @tabla, 'cliente = tb_f_mcliente.codigo ') ; 
		set @cJoinCampoO = concat(', tb_f_mcliente.nombre') ; 
		set @cOrdenado = concat(' order by tb_f_mcliente.nombre') ;
	elseif coalesce(_ordenado, '') = 'nplantilla' then
		set @cJoinOrdenB = concat(' left join tb_f_mplantilla on ', @tabla, 'codemp = tb_f_mplantilla.codemp and ', @tabla, 'sucursal = tb_f_mplantilla.sucursal and ', @tabla, 'plantilla = tb_f_mplantilla.codigo ') ; 
		set @cJoinCampoO = concat(', tb_f_mplantilla.codigo') ; 
		set @cOrdenado = concat(' order by tb_f_mplantilla.nombre') ;
	elseif coalesce(_ordenado, '') = 'ngrupo' then
		set @cJoinOrdenB = concat(' left join tb_f_mgrupo on ', @tabla, 'codemp = tb_f_mgrupo.codemp and ', @tabla, 'sucursal = tb_f_mgrupo.sucursal and ', @tabla, 'grupo = tb_f_mgrupo.codigo ') ; 
		set @cJoinCampoO = concat(', tb_f_mgrupo.nombre') ; 
		set @cOrdenado = concat(' order by tb_f_mgrupo.nombre') ;
	elseif coalesce(_ordenado, '') = 'npersonal' then
		set @cJoinOrdenB = concat(' left join tb_f_mpersonal on ', @tabla, 'codemp = tb_f_mpersonal.codemp and ', @tabla, 'sucursal = tb_f_mpersonal.sucursal and ', @tabla, 'personal = tb_f_mpersonal.codigo ') ; 
		set @cJoinCampoO = concat(', tb_f_mpersonal.nombre') ; 
		set @cOrdenado = concat(' order by tb_f_mpersonal.nombre') ;
	elseif coalesce(_ordenado, '') = 'nrole' then
		set @cJoinOrdenB = concat(' left join tb_f_mrole on ', @tabla, 'codemp = tb_f_mrole.codemp and ', @tabla, 'sucursal = tb_f_mrole.sucursal and ', @tabla, 'role = tb_f_mrole.codigo ') ; 
		set @cJoinCampoO = concat(', tb_f_mrole.nombre') ; 
		set @cOrdenado = concat(' order by tb_f_mrole.nombre') ;
	elseif coalesce(_ordenado, '') = 'nproyecto' then
		set @cJoinOrdenB = concat(' left join tb_f_mproyecto on ', @tabla, 'codemp = tb_f_mproyecto.codemp and ', @tabla, 'sucursal = tb_f_mproyecto.sucursal and ', @tabla, 'proyecto = tb_f_mproyecto.codigo ') ; 
		set @cJoinCampoO = concat(', tb_f_mproyecto.nombre') ; 
		set @cOrdenado = concat(' order by tb_f_mproyecto.nombre') ;
	elseif coalesce(_ordenado, '') = 'nsupervisor' then
		set @cJoinOrdenB = concat(' left join tb_f_msupervisor on ', @tabla, 'codemp = tb_f_msupervisor.codemp and ', @tabla, 'sucursal = tb_f_msupervisor.sucursal and ', @tabla, 'supervisor = tb_f_msupervisor.codigo ') ; 
		set @cJoinCampoO = concat(', tb_f_msupervisor.nombre') ; 
		set @cOrdenado = concat(' order by tb_f_msupervisor.nombre') ;
	else 
		set @cOrdenado = concat(' order by ',  @tabla, _ordenado) ;
		set @cJoinCampoO = concat(', ', @tabla, _ordenado) ; 
	end if ;
	set @cJoinCampoO = concat(@cJoinCampoO, '  as xOrdenado') ; 
	-- ----------------------------------------------------------------------------------------------
	-- Se crea una cadena para filtral por empresa y sucursal
	set @empresa = concat(' where ', @tabla, 'codemp = ', _codemp);
	if trim(_sucursal) <> '' then
		set @sucursal = concat(' and ', @tabla, 'sucursal = ', _sucursal);
	end if;
	
	-- ----------------------------------------------------------------------------------------------
	-- Crea dos cadena: 
	-- 		cResultadoIniciar: 	realizar la búsqueda de los registros que se mostraran como resultado final segun los parametros indicados
	-- 		cResultadoTotales: 	realiza una consulta para obtener el total de registro en la consulta por medio de un COUNT(*)
	-- 		COUNT(*):			sustituye la funcion SQL_CALC_FOUND_ROWS, dado que el FOUND_ROWS() no funciona ahora con el prepare y deallocate prepare
	--
	
	set @cResultadoIniciar = concat('create temporary table sentencia select ', @tabla, '*, ', @campoextra, '(@fila:= @fila + 1) as RegFila',  @cJoinCampoO) ;
	set @cResultadoTotales = concat('create temporary table sentencia select COUNT(*) total_filas ');
	if coalesce(_camposB, '') <> '' then
		set @cResultadoA = concat(@cResultadoA, _camposB) ;
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	set @cResultadoA = concat(@cResultadoA, '  from ', _tabla) ;
	if coalesce(@jointb, '') <> '' then
		set @cResultadoA = concat(@cResultadoA, ' ', coalesce(@jointb, ''), ' ');
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Agrega el LEFT JOIN de la Tabla por la que ordenara la busqueda.
	set @cResultadoA = concat(@cResultadoA, ' ', coalesce(@cJoinOrdenB, '') ) ;
	
	-- ----------------------------------------------------------------------------------------------
	set @cResultadoA = concat(@cResultadoA, @empresa, @sucursal) ;
	if trim(coalesce(@adicional, '')) <> '' then
		set @cResultadoA = concat(@cResultadoA, ' and ', @tablaBA, trim(@adicional));
	end if;
	
	if coalesce(_estado, 0) > 0 then
		set @cResultadoA = concat(@cResultadoA, ' and ', @tabla, 'estado = ', coalesce(_estado, 0));
	else 
		set @cResultadoA = concat(@cResultadoA, ' and ', @tabla, 'estado > 0 ');
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	-- De pasar la fecha como parametro, se incluye la opción para el rango de fecha
	--
	if trim(coalesce(_desde, '')) <> '' and _tipoBusq = 1 then
		set @desde = STR_TO_DATE(Trim(_desde), '%m/%d/%Y');
		set @hasta = STR_TO_DATE(Trim(_hasta), '%m/%d/%Y');
        if (@tabla = 'tb_f_otimesheet.') then
			set @cResultadoA = CONCAT(@cResultadoA, ' and ', @tabla, 'fecha_d between ', QUOTE(@desde), ' and ', QUOTE(@hasta));
        else
			set @cResultadoA = CONCAT(@cResultadoA, ' and ', @tabla, 'fecha between ', QUOTE(@desde), ' and ', QUOTE(@hasta));
		end if ;
	end if ;
	
	if trim(@valor) <> '' then
		if @tipoBusq = 1 then
			-- ----------------------------------------------------------------------------------------------
			-- Según el campo por el que se realizará la búsqueda, se anexará a la cadena validado por la tabla del maestro que lo rige
			-- es importante que el campo a validar en la búsqueda se encuentre dentro de las siguientes opciones, de lo contrario se deberá anexar
			-- para que se incorpore a la cadena.
			--
			if @bCampos = 'numero' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'numero ') ;
				set @parent = '' ;
			elseif @bCampos = 'referencia' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'referencia ') ;
				set @parent = '' ;
			elseif @bCampos = 'seguimiento' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'seguimiento ') ;
				set @parent = '' ;
			elseif @bCampos = 'contacto' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'contacto ') ;
				set @parent = '' ;
			elseif @bCampos = 'zcode' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'zcode ') ;
				set @parent = '' ;
			elseif @bCampos = 'email' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'email ') ;
				set @parent = '' ;
			elseif @bCampos = 'telefono' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'telefono ') ;
				set @parent = '' ;
			elseif @bCampos = 'usuario' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'usuario in (select u201 from tb_musuario where u202 ') ;
			elseif @bCampos = 'nusuario' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'usuario in (select u201 from tb_musuario where u202 ') ;
			elseif @bCampos = 'cliente' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' cliente in (select codigo from tb_f_mcliente ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'ncliente' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' cliente in (select codigo from tb_f_mcliente ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'plantilla' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' plantilla in (select codigo from tb_f_mplantilla ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'nplantilla' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' plantilla in (select codigo from tb_f_mplantilla ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'grupo' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' grupo in (select codigo from tb_f_mgrupo ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'ngrupo' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' grupo in (select codigo from tb_f_mgrupo ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'personal' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' personal in (select codigo from tb_f_mpersonal ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'npersonal' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' personal in (select codigo from tb_f_mpersonal ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'proyecto' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' proyecto in (select codigo from tb_f_mproyecto ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'nproyecto' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' proyecto in (select codigo from tb_f_mproyecto ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'role' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' role in (select codigo from tb_f_mrole ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'nrole' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' role in (select codigo from tb_f_mrole ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'supervisor' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' supervisor in (select codigo from tb_f_msupervisor ', @empresa, @sucursal,' and nombre ') ;
			elseif @bCampos = 'nsupervisor' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA,' supervisor in (select codigo from tb_f_msupervisor ', @empresa, @sucursal,' and nombre ') ;
			else
				set @cResultadoB = @cResultadoB ;
			end if ;
		else	
			set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, @bCampos) ;
			set @parent = '' ;
		end if ;
		
		-- ----------------------------------------------------------------------------------------------
		-- Valida el operador a utilizar para comparar el campo vs el valor
		if @operador = 'LIKE' then
			set @cResultadoB = concat(@cResultadoB, ' LIKE ', '''', '%', trim(@valor), '%', '''') ;
		elseif @operador = 'REGEXP' then
			set @cResultadoB = concat(@cResultadoB, ' REGEXP ', '''', trim(@valor), '''') ;
		else
			set @cResultadoB = concat(@cResultadoB, trim(@operador), '''', trim(@valor), '''') ;
		end if;
	else
		-- ----------------------------------------------------------------------------------------------
		-- En caso que no se requiera validar con un maestro, la variable pasa a ser en blanco y un ')' como valor predeterminado
		set @parent = '' ;
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Integra todas las cadenas armadas para construir el cursor.
	--
	set @cResultadoB = concat(@cResultadoB, @parent) ;
	if coalesce(_regpp, 0) <> 0 then
		set @cResultadoC = concat(' LIMIT ', @iLimiteInicio, ', ',  @iLimite) ;
	else
		set @cResultadoC = '' ;
	end if ;
	-- set @cResultado = concat(@cResultadoA, @cResultadoB, @cOrdenado, @cResultadoC) ;
	set @cResultado = concat(@cResultadoA, @cResultadoB, @cOrdenado, @cResultadoC) ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Se construye la cadena para obtener el Total de Registros.
	set @cResultadoT = concat(@cResultadoTotales, @cResultadoA, @cResultadoB, @cOrdenado);
	drop temporary table if exists sentencia ;
	prepare sentencia from @cResultadoT ;
	execute sentencia ;
	deallocate prepare sentencia;
	
	-- ----------------------------------------------------------------------------------------------
	-- Se construye la cadena para obtener los registros, y se anexa la variable con el total de registros de
	-- @cResultadoT
	select total_filas into @iNumeroFila from sentencia;
	set @iPaginaUltima =  round((@iNumeroFila/@iLimite), 0) ;
	if coalesce(@iPaginaUltima, 0) = 0 then
		set @iPaginaUltima = 1 ;
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Se construye la cadena para realizar la consulta de los registros a mostrar en la Lista Formulario
	-- segun los parametros indicados.
	-- Se agrega la variable @iPaginaUltima a la cadena antes de realizar la consulta a través del Prepare.
	set @cResultadoI = concat(@cResultadoIniciar, ', @iPagina as PagAct, @iNumeroFila as Filas, round(@iPaginaUltima,0) as PagUltima ', @cResultado);
    
	drop temporary table if exists sentencia ;
	prepare sentencia from @cResultadoI ;
	execute sentencia ;
	deallocate prepare sentencia;
	
    -- ----------------------------------------------------------------------------------------------
    -- La Cadena de consulta que se devolvera estara vacia, dado que ya no se requiere.
    -- ----------------------------------------------------------------------------------------------
    -- set _cResultado = '';
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `str_cadena_codigo` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `str_cadena_codigo`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _tabla varchar(100), 
	in _tablaBA varchar(25), 
	in _jointb varchar(1000),
	in _camposA varchar(1000), 
	in _camposB varchar(1000),
	in _ordenado varchar(50), 
	in _bCampos varchar(1000), 
	in _operador varchar(6), 
	in _valor varchar(100), 
	in _pagina int, 
	in _regpp int, 
	in _adicional varchar(5000), 
	in _tipo_estado varchar(3),
	in _estado int,
	in _desde varchar(10),
	in _hasta varchar(10),
	in _tipoBusq int(1),
	out _cResultado Varchar(5000)
)
begin
	/* ---------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2024.12.16, 2024.12.29
		Autor: 
	--------------------------------------------------- */
    
	-- Validación de parámetros
	set @iLimite = coalesce(_regpp, 25) ;
	set @iPagina = coalesce(_pagina, 1) ;
	set @iLimiteInicio = ((@iPagina - 1) * @iLimite) ;
	set @nRowTotal = 0 ;
	set @Fila = 0 ;
	
	set @cResultadoA = '' ;
	set @cResultadoB = '' ;
	set @cResultadoC = '' ;
	set @cResultadoI = '' ;
	set @cResultadoT = '' ;
	set @parent = ')' ;
	
	set @sucursal = '' ;
	set @tabla = concat(trim(_tabla), '.') ;
	set @tablaBA = concat(trim(_tablaBA), '.') ;
	set @valor = coalesce(trim(_valor), '') ;
	set @bCampos = coalesce(trim(_bCampos), '') ;
	set @operador = coalesce(_operador, '') ;
	set @tipoBusq = coalesce(_tipoBusq, 0) ;
	set @cJoinOrdenB = '' ;
	set @cJoinCampoO = '' ;
	
	set @cOrdenado = concat(' order by ', _ordenado) ;
	set @cJoinCampoO = concat(', ', @tabla, _ordenado) ; 
	set @cJoinCampoO = concat(@cJoinCampoO, '  as xOrdenado') ; 
	-- ----------------------------------------------------------------------------------------------
	-- Se crea una cadena para filtral por empresa y sucursal
	set @empresa = concat(' where ', @tabla, 'codigo = ', _codemp);
	
	
	-- ----------------------------------------------------------------------------------------------
	-- Crea dos cadena: 
	-- 		cResultadoIniciar: 	realizar la búsqueda de los registros que se mostraran como resultado final segun los parametros indicados
	-- 		cResultadoTotales: 	realiza una consulta para obtener el total de registro en la consulta por medio de un COUNT(*)
	-- 		COUNT(*):			sustituye la funcion SQL_CALC_FOUND_ROWS, dado que el FOUND_ROWS() no funciona ahora con el prepare y deallocate prepare
	--
	
	set @cResultadoIniciar = concat('create temporary table sentencia select ', @tabla, '*, (@fila:= @fila + 1) as RegFila',  @cJoinCampoO) ;
	set @cResultadoTotales = concat('create temporary table sentencia select COUNT(*) total_filas ');
	if coalesce(_camposB, '') <> '' then
		set @cResultadoA = concat(@cResultadoA, _camposB) ;
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	set @cResultadoA = concat(@cResultadoA, '  from ', _tabla) ;
	if coalesce(_jointb, '') <> '' then
		set @cResultadoA = concat(@cResultadoA, ' ', coalesce(_jointb, ''));
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Agrega el LEFT JOIN de la Tabla por la que ordenara la busqueda.
	set @cResultadoA = concat(@cResultadoA, ' ', coalesce(@cJoinOrdenB, '') ) ;
	
	-- ----------------------------------------------------------------------------------------------
	set @cResultadoA = concat(@cResultadoA, @empresa, @sucursal) ;
	if trim(coalesce(_adicional, '')) <> '' then
		set @cResultadoA = concat(@cResultadoA, ' and ', @tabla, trim(_adicional));
	end if;
	
	if coalesce(_estado, 0) > 0 then
		set @cResultadoA = concat(@cResultadoA, ' and ', @tabla, 'estado = ', coalesce(_estado, 0));
	else 
		set @cResultadoA = concat(@cResultadoA, ' and ', @tabla, 'estado > 0 ');
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	-- De pasar la fecha como parametro, se incluye la opción para el rango de fecha
	--
	if trim(coalesce(_desde, '')) <> '' and _tipoBusq = 1 then
		set @desde = STR_TO_DATE(Trim(_desde), '%m/%d/%Y');
		set @hasta = STR_TO_DATE(Trim(_hasta), '%m/%d/%Y');
		set  @cResultadoA = CONCAT(@cResultadoA, ' and ', @tabla, 'fecha between ', QUOTE(@desde), ' and ', QUOTE(@hasta));
	end if ;
	
	if trim(@valor) <> '' then
		set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, @bCampos) ;
		set @parent = '' ;
		
		-- ----------------------------------------------------------------------------------------------
		-- Valida el operador a utilizar para comparar el campo vs el valor
		if @operador = 'LIKE' then
			set @cResultadoB = concat(@cResultadoB, ' LIKE ', '''', '%', trim(@valor), '%', '''') ;
		elseif @operador = 'REGEXP' then
			set @cResultadoB = concat(@cResultadoB, ' REGEXP ', '''', trim(@valor), '''') ;
		else
			set @cResultadoB = concat(@cResultadoB, trim(@operador), '''', trim(@valor), '''') ;
		end if;
	else
		-- ----------------------------------------------------------------------------------------------
		-- En caso que no se requiera validar con un maestro, la variable pasa a ser en blanco y un ')' como valor predeterminado
		set @parent = '' ;
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Integra todas las cadenas armadas para construir el cursor.
	--
	set @cResultadoB = concat(@cResultadoB, @parent) ;
	if coalesce(_regpp, 0) <> 0 then
		set @cResultadoC = concat(' LIMIT ', @iLimiteInicio, ', ',  @iLimite) ;
	else
		set @cResultadoC = '' ;
	end if ;
	-- set @cResultado = concat(@cResultadoA, @cResultadoB, @cOrdenado, @cResultadoC) ;
	set @cResultado = concat(@cResultadoA, @cResultadoB, @cOrdenado, @cResultadoC) ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Se construye la cadena para obtener el Total de Registros.
	set @cResultadoT = concat(@cResultadoTotales, @cResultadoA, @cResultadoB, @cOrdenado);
	drop temporary table if exists sentencia ;
	prepare sentencia from @cResultadoT ;
	execute sentencia ;
	deallocate prepare sentencia;
	
	-- ----------------------------------------------------------------------------------------------
	-- Se construye la cadena para obtener los registros, y se anexa la variable con el total de registros de
	-- @cResultadoT
	select total_filas into @iNumeroFila from sentencia;
	set @iPaginaUltima =  round((@iNumeroFila/@iLimite), 0) ;
	if coalesce(@iPaginaUltima, 0) = 0 then
		set @iPaginaUltima = 1 ;
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Se construye la cadena para realizar la consulta de los registros a mostrar en la Lista Formulario
	-- segun los parametros indicados.
	-- Se agrega la variable @iPaginaUltima a la cadena antes de realizar la consulta a través del Prepare.
	set @cResultadoI = concat(@cResultadoIniciar, ', @iPagina as PagAct, @iNumeroFila as Filas, round(@iPaginaUltima,0) as PagUltima ', @cResultado);
	drop temporary table if exists sentencia ;
	prepare sentencia from @cResultadoI ;
	execute sentencia ;
	deallocate prepare sentencia;
	
    -- ----------------------------------------------------------------------------------------------
    -- La Cadena de consulta que se devolvera estara vacia, dado que ya no se requiere.
    -- ----------------------------------------------------------------------------------------------
    -- set _cResultado = '';
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `str_cadena_dbexternal_c` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `str_cadena_dbexternal_c`(
	in _tablaT varchar(25), 
	in _tablaP varchar(25), 
	in _campo varchar(500), 
	in _jointb varchar(500),
	in _condicion varchar(500),
	in _groupby varchar(500), 
	in _orderby varchar(500)
)
begin
	/* ------------------------------------------------------------------------------------------------------
		Crea una tabla temporal, basada en una DB y tabla pasada como parametro
		Versión 1.0
		Creado: 2025-08-04
		Actualizado: 2025-08-04
		Autor: Custom Systems Solutions LLC
	------------------------------------------------------------------------------------------------------ */
    
	set @tablaT = coalesce(trim(_tablaT), 'tablaTMP') ;
    set @tablaP = coalesce(trim(_tablaP), '') ;
    set @campo = coalesce(trim(_campo), concat(@tablaT, '.*')) ;
    set @jointb = coalesce(_jointb, '') ;
    set @condicion = coalesce(_condicion, '') ;
    set @groupby = coalesce(_groupby, '') ;
    set @orderby = coalesce(_orderby, 'nombre') ;
    
    -- ------------------------------------------------------------------------------------------------------
    set @dropT = concat('drop temporary table if exists ', @tablaT) ;
  	drop temporary table if exists sentencia ;
	prepare sentencia from @dropT ;
	execute sentencia ;  
    
    -- ------------------------------------------------------------------------------------------------------
    set @sentencia = case when (@tablaP != '') 
							then concat('create temporary table ', @tablaT, ' select ', @campo, ' from ', @tablaP, @jointb, @condicion, @groupby, @orderby)
                            else 'select null as nombre, -1 as codigo, 0 as estado'
						end ;
	
	prepare sentencia from @sentencia ;
	execute sentencia ;
	deallocate prepare sentencia;
    
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `str_cadena_group_by` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `str_cadena_group_by`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
    in _tabla varchar(20),
	in _campos varchar(1000),
    in _jointb varchar(1000),
    in _condicion varchar(1000),
    in _group_by varchar(1000),
    in _ordenado varchar(500),
	in _bCampos varchar(500), 
	in _operador varchar(5), 
	in _valor varchar(100), 
	in _pagina int, 
	in _regpp int, 
	in _tipoBusq int(1),
	out _cResultado Varchar(5000)
)
begin
	/* ------------------------------------------------------------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 2025-07-23
		Actualizado: 2025-07-23
		Autor: 
	------------------------------------------------------------------------------------------------------ */
    
	-- Validación de parámetros
	set @iLimite = coalesce(_regpp, 25) ;
	set @iPagina = coalesce(_pagina, 1) ;
	set @iLimiteInicio = ((@iPagina - 1) * @iLimite) ;
	set @nRowTotal = 0 ;
	set @Fila = 0 ;
	
	set @cResultadoA = '' ;
	set @cResultadoB = '' ;
	set @cResultadoC = '' ;
	set @cResultadoI = '' ;
	set @cResultadoT = '' ;
    set @parent = '' ;
	-- set @parent = ')' ;
	
 	set @campos = _campos ;
    set @tabla = trim(_tabla) ;
	set @tablaBA = '_tablaTMP.' ;
    set @jointb = case when coalesce(_jointb, '') = '' then '' else concat(' ',  trim(_jointb)) end ;
    set @condicion = case when coalesce(_condicion, '') = '' then '' else concat(' where ', trim(_condicion)) end ;
    set @group_by = case when coalesce(_group_by, '') = '' then '' else concat(' group by ', trim(_group_by)) end ; 
    
	set @bCampos = coalesce(trim(_bCampos), '') ;
	set @operador = coalesce(_operador, '') ;
	set @valor = coalesce(trim(_valor), '') ;
	set @tipoBusq = coalesce(_tipoBusq, 0) ;
    
	set @cResultado = concat('create temporary table _tablaTMP select ', @campos, ', 4 as estado from ', @tabla, ' ', @jointb, @condicion, @group_by) ;
    
	-- ----------------------------------------------------------------------------------------------
	-- Se construye la cadena para obtener el Total de Registros.
	drop temporary table if exists _tablaTMP ;
	prepare _tablaTMP from @cResultado ;
	execute _tablaTMP ;
	deallocate prepare _tablaTMP;
    
	-- ----------------------------------------------------------------------------------------------
    -- ----------------------------------------------------------------------------------------------
	-- Proceso que realiza una subconsulta según la condición a filtrar
    -- 
	set @cResultado = '' ;
	set @cResultadoIniciar = concat('create temporary table sentencia select _tablaTMP.*, (@fila:= @fila + 1) as RegFila') ;
	set @cResultadoTotales = concat('create temporary table sentencia select COUNT(*) total_filas from _tablaTMP');
    
	-- ----------------------------------------------------------------------------------------------
	-- Integra todas las cadenas armadas para construir el cursor.
	--
	set @cResultadoB = concat(@cResultadoB, @parent) ;
	set @cResultadoC = case when coalesce(_regpp, 0) <> 0 then concat(' LIMIT ', @iLimiteInicio, ', ',  @iLimite) else '' end ;
	set @cResultado = concat(@cResultadoA, @cJoinCampoO, ' from _tablaTMP ', @cResultadoB, @cJoinOrdenB, @cOrdenado, @cResultadoC) ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Se construye la cadena para obtener el Total de Registros.
	set @cResultadoT = concat(@cResultadoTotales, ' ',  @cResultadoB);
	drop temporary table if exists sentencia ;
	prepare sentencia from @cResultadoT ;
	execute sentencia ;
	deallocate prepare sentencia;
	
	-- ----------------------------------------------------------------------------------------------
	-- Se construye la cadena para obtener los registros, y se anexa la variable con el total de registros de
	-- @cResultadoT
	select total_filas into @iNumeroFila from sentencia;
	set @iPaginaUltima =  round((@iNumeroFila/@iLimite), 0) ;
	if coalesce(@iPaginaUltima, 0) = 0 then
		set @iPaginaUltima = 1 ;
	end if ;
	-- ----------------------------------------------------------------------------------------------
	-- Se construye la cadena para realizar la consulta de los registros a mostrar en la Lista Formulario
	-- segun los parametros indicados.
	-- Se agrega la variable @iPaginaUltima a la cadena antes de realizar la consulta a través del Prepare.
	set @cResultadoI = concat(@cResultadoIniciar, ', @iPagina as PagAct, @iNumeroFila as Filas, round(@iPaginaUltima,0) as PagUltima ', @cResultado, '; ');
    
	drop temporary table if exists sentencia ;
	prepare sentencia from @cResultadoI ;
	execute sentencia ;
	deallocate prepare sentencia;
	
    -- ----------------------------------------------------------------------------------------------
    -- La Cadena de consulta que se devolvera estara vacia, dado que ya no se requiere.
    -- ----------------------------------------------------------------------------------------------
    -- set _cResultado = '';
    
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `str_cadena_log` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `str_cadena_log`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _tabla varchar(100), 
	in _tablaBA varchar(25), 
	in _jointb varchar(2000),
	in _camposA varchar(1000), 
	in _camposB varchar(1000),
	in _ordenado varchar(50), 
	in _bCampos varchar(1000), 
	in _operador varchar(6), 
	in _valor varchar(100), 
	in _pagina int, 
	in _regpp int, 
	in _adicional varchar(5000), 
	in _tipo_estado varchar(3),
	in _estado int,
	in _desde varchar(10),
	in _hasta varchar(10),
	in _tipoBusq int(1),
	out _cResultado Varchar(5000)
)
begin
	/* ------------------------------------------------------------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2024.12.16, 2024.12.29, 2025.01.21
		Autor: 
	------------------------------------------------------------------------------------------------------ */
    
	-- Validación de parámetros
	set @iLimite = coalesce(_regpp, 25) ;
	set @iPagina = coalesce(_pagina, 1) ;
	set @iLimiteInicio = ((@iPagina - 1) * @iLimite) ;
	set @nRowTotal = 0 ;
	set @Fila = 0 ;
	
	set @cResultadoA = '' ;
	set @cResultadoB = '' ;
	set @cResultadoC = '' ;
	set @cResultadoI = '' ;
	set @cResultadoT = '' ;
	set @parent = ')' ;
	
	set @sucursal = '' ;
	set @tabla = concat(trim(_tabla), '.') ;
	set @tablaBA = concat(trim(_tablaBA), '.') ;
	set @valor = coalesce(trim(_valor), '') ;
	set @bCampos = coalesce(trim(_bCampos), '') ;
    
	set @operador = coalesce(_operador, '') ;
	set @tipoBusq = coalesce(_tipoBusq, 0) ;
    set @jointb = coalesce(trim(_jointb), '') ;
    set @adicional = coalesce(trim(_adicional), '') ;
	set @cJoinOrdenB = '' ;
	set @cJoinCampoO = '' ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Proceso para Ordenar la consulta de la tabla
	
	if coalesce(_ordenado, '') = 'usuario' then
		set @cJoinOrdenB = concat(' left join tb_musuario on ', @tabla, 'usuario = tb_musuario.u201 ') ; 
		set @cJoinCampoO = concat(', tb_musuario.u202') ; 
		set @cOrdenado = concat(' order by tb_musuario.u202') ;
	elseif coalesce(_ordenado, '') = 'nusuario' then
		set @cJoinOrdenB = concat(' left join tb_musuario on ', @tabla, 'usuario = tb_musuario.u201 ') ; 
		set @cJoinCampoO = concat(', tb_musuario.u202') ; 
		set @cOrdenado = concat(' order by tb_musuario.u202') ;
	elseif coalesce(_ordenado, '') = 'nformulario' then
		set @cJoinOrdenB = concat(' left join cfg_lista_formularios on ', @tabla, 'formulario = cfg_lista_formularios.formulario ') ; 
		set @cJoinCampoO = concat(', cfg_lista_formularios.titulo') ; 
		set @cOrdenado = concat(' order by cfg_lista_formularios.titulo') ;
	elseif coalesce(_ordenado, '') = 'noperacion' then
		set @cOrdenado = concat(' order by ',  @tabla, 'operacion') ;
		set @cJoinCampoO = concat(', ', @tabla, 'operacion') ; 
	else 
		set @cOrdenado = concat(' order by ',  @tabla, _ordenado, ' desc') ;
		set @cJoinCampoO = concat(', ', @tabla, _ordenado) ; 
	end if ;
	set @cJoinCampoO = concat(@cJoinCampoO, '  as xOrdenado') ; 
	-- ----------------------------------------------------------------------------------------------
	-- Se crea una cadena para filtral por empresa y sucursal
	set @empresa = concat(' where ', @tabla, 'codemp = ', _codemp);
	if trim(_sucursal) <> '' then
		set @sucursal = concat(' and ', @tabla, 'sucursal = ', _sucursal);
	end if;
	
	-- ----------------------------------------------------------------------------------------------
	-- Crea dos cadena: 
	-- 		cResultadoIniciar: 	realizar la búsqueda de los registros que se mostraran como resultado final segun los parametros indicados
	-- 		cResultadoTotales: 	realiza una consulta para obtener el total de registro en la consulta por medio de un COUNT(*)
	-- 		COUNT(*):			sustituye la funcion SQL_CALC_FOUND_ROWS, dado que el FOUND_ROWS() no funciona ahora con el prepare y deallocate prepare
	--
	
	set @cResultadoIniciar = concat('create temporary table sentencia select ', @tabla, '*, (@fila:= @fila + 1) as RegFila',  @cJoinCampoO) ;
	set @cResultadoTotales = concat('create temporary table sentencia select COUNT(*) total_filas ');
    /*
	if coalesce(_camposB, '') <> '' then
		set @cResultadoA = concat(@cResultadoA, _camposB) ;
	end if ;
	*/
	-- ----------------------------------------------------------------------------------------------
	set @cResultadoA = concat(@cResultadoA, '  from ', _tabla) ;
	if coalesce(@jointb, '') <> '' then
		set @cResultadoA = concat(@cResultadoA, ' ', coalesce(@jointb, ''), ' ');
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Agrega el LEFT JOIN de la Tabla por la que ordenara la busqueda.
	set @cResultadoA = concat(@cResultadoA, ' ', coalesce(@cJoinOrdenB, '') ) ;
	
	-- ----------------------------------------------------------------------------------------------
	set @cResultadoA = concat(@cResultadoA, @empresa, @sucursal) ;
	if trim(coalesce(@adicional, '')) <> '' then
		set @cResultadoA = concat(@cResultadoA, ' and ', @tablaBA, trim(@adicional));
	end if;
    
	/*
	if coalesce(_estado, 0) > 0 then
		set @cResultadoA = concat(@cResultadoA, ' and ', @tabla, 'estado = ', coalesce(_estado, 0));
	else 
		set @cResultadoA = concat(@cResultadoA, ' and ', @tabla, 'estado > 0 ');
	end if ;
	*/
    
	-- ----------------------------------------------------------------------------------------------
	-- De pasar la fecha como parametro, se incluye la opción para el rango de fecha
	--
	if trim(coalesce(_desde, '')) <> '' and _tipoBusq = 1 then
		set @desde = STR_TO_DATE(Trim(_desde), '%m/%d/%Y');
		set @hasta = STR_TO_DATE(Trim(_hasta), '%m/%d/%Y');
		set @cResultadoA = CONCAT(@cResultadoA, ' and date(', @tabla, 'fecha) between ', QUOTE(@desde), ' and ', QUOTE(@hasta));
	end if ;
	
	if trim(@valor) <> '' then
		if @tipoBusq = 1 then
			-- ----------------------------------------------------------------------------------------------
			-- Según el campo por el que se realizará la búsqueda, se anexará a la cadena validado por la tabla del maestro que lo rige
			-- es importante que el campo a validar en la búsqueda se encuentre dentro de las siguientes opciones, de lo contrario se deberá anexar
			-- para que se incorpore a la cadena.
			--
			if @bCampos = 'numero' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'numero ') ;
				set @parent = '' ;
			elseif @bCampos = 'usuario' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'usuario in (select u201 from tb_musuario where u202 ') ;
			elseif @bCampos = 'nusuario' then
				set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, 'usuario in (select u201 from tb_musuario where u202 ') ;
			else
				set @cResultadoB = @cResultadoB ;
			end if ;
		else	
			set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, @bCampos) ;
			set @parent = '' ;
		end if ;
		
		-- ----------------------------------------------------------------------------------------------
		-- Valida el operador a utilizar para comparar el campo vs el valor
		if @operador = 'LIKE' then
			set @cResultadoB = concat(@cResultadoB, ' LIKE ', '''', '%', trim(@valor), '%', '''') ;
		elseif @operador = 'REGEXP' then
			set @cResultadoB = concat(@cResultadoB, ' REGEXP ', '''', trim(@valor), '''') ;
		else
			set @cResultadoB = concat(@cResultadoB, trim(@operador), '''', trim(@valor), '''') ;
		end if;
	else
		-- ----------------------------------------------------------------------------------------------
		-- En caso que no se requiera validar con un maestro, la variable pasa a ser en blanco y un ')' como valor predeterminado
		set @parent = '' ;
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Integra todas las cadenas armadas para construir el cursor.
	--
	set @cResultadoB = concat(@cResultadoB, @parent) ;
	if coalesce(_regpp, 0) <> 0 then
		set @cResultadoC = concat(' LIMIT ', @iLimiteInicio, ', ',  @iLimite) ;
	else
		set @cResultadoC = '' ;
	end if ;
	-- set @cResultado = concat(@cResultadoA, @cResultadoB, @cOrdenado, @cResultadoC) ;
	set @cResultado = concat(@cResultadoA, @cResultadoB, @cOrdenado, @cResultadoC) ;
    
	-- ----------------------------------------------------------------------------------------------
	-- Se construye la cadena para obtener el Total de Registros.
	set @cResultadoT = concat(@cResultadoTotales, @cResultadoA, @cResultadoB, @cOrdenado);
	drop temporary table if exists sentencia ;
	prepare sentencia from @cResultadoT ;
	execute sentencia ;
	deallocate prepare sentencia;
	
	-- ----------------------------------------------------------------------------------------------
	-- Se construye la cadena para obtener los registros, y se anexa la variable con el total de registros de
	-- @cResultadoT
	select total_filas into @iNumeroFila from sentencia;
	set @iPaginaUltima =  round((@iNumeroFila/@iLimite), 0) ;
	if coalesce(@iPaginaUltima, 0) = 0 then
		set @iPaginaUltima = 1 ;
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Se construye la cadena para realizar la consulta de los registros a mostrar en la Lista Formulario
	-- segun los parametros indicados.
	-- Se agrega la variable @iPaginaUltima a la cadena antes de realizar la consulta a través del Prepare.
	set @cResultadoI = concat(@cResultadoIniciar, ', @iPagina as PagAct, @iNumeroFila as Filas, round(@iPaginaUltima,0) as PagUltima ', @cResultado);
    -- select @cResultadoI ;
    
    
    drop temporary table if exists sentencia ;
	prepare sentencia from @cResultadoI ;
	execute sentencia ;
	deallocate prepare sentencia;
    
    -- ----------------------------------------------------------------------------------------------
    -- La Cadena de consulta que se devolvera estara vacia, dado que ya no se requiere.
    -- ----------------------------------------------------------------------------------------------
    -- set _cResultado = '';
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `str_cadena_nocode` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `str_cadena_nocode`(
	in _codemp varchar(2), 
	in _sucursal varchar(3), 
	in _tabla varchar(100), 
	in _tablaBA varchar(25), 
	in _jointb varchar(1000),
	in _camposA varchar(1000), 
	in _camposB varchar(1000),
	in _ordenado varchar(50), 
	in _bCampos varchar(1000), 
	in _operador varchar(6), 
	in _valor varchar(100), 
	in _pagina int, 
	in _regpp int, 
	in _adicional varchar(5000), 
	in _tipo_estado varchar(3),
	in _estado int,
	in _desde varchar(10),
	in _hasta varchar(10),
	in _tipoBusq int(1),
	out _cResultado Varchar(5000)
)
begin
	/* ---------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2024.12.29
		Autor: 
	--------------------------------------------------- */
    
	-- Validación de parámetros
	set @iLimite = coalesce(_regpp, 25) ;
	set @iPagina = coalesce(_pagina, 1) ;
	set @iLimiteInicio = ((@iPagina - 1) * @iLimite) ;
	set @nRowTotal = 0 ;
	set @Fila = 0 ;
	
	set @cResultadoA = '' ;
	set @cResultadoB = '' ;
	set @cResultadoC = '' ;
	set @cResultadoI = '' ;
	set @cResultadoT = '' ;
	set @parent = ')' ;
	
	set @sucursal = '' ;
	set @tabla = concat(trim(_tabla), '.') ;
	set @tablaBA = concat(trim(_tablaBA), '.') ;
	set @valor = coalesce(trim(_valor), '') ;
	set @bCampos = coalesce(trim(_bCampos), '') ;
	set @operador = coalesce(_operador, '') ;
	set @tipoBusq = coalesce(_tipoBusq, 0) ;
	set @cJoinOrdenB = '' ;
	set @cJoinCampoO = '' ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Proceso para Ordenar la consulta de la tabla
	set @cOrdenado = concat(' order by ', @tabla, _ordenado) ;
	set @cJoinCampoO = concat(', ', @tabla, _ordenado) ; 
	set @cJoinCampoO = concat(@cJoinCampoO, '  as xOrdenado') ; 
	-- ----------------------------------------------------------------------------------------------
	-- Se crea una cadena para filtral por empresa y sucursal
	set @empresa = concat(' where ', @tabla, 'codigo <> ''', _codemp, '''');
	
	
	-- ----------------------------------------------------------------------------------------------
	-- Crea dos cadena: 
	-- 		cResultadoIniciar: 	realizar la búsqueda de los registros que se mostraran como resultado final segun los parametros indicados
	-- 		cResultadoTotales: 	realiza una consulta para obtener el total de registro en la consulta por medio de un COUNT(*)
	-- 		COUNT(*):			sustituye la funcion SQL_CALC_FOUND_ROWS, dado que el FOUND_ROWS() no funciona ahora con el prepare y deallocate prepare
	--
	
	set @cResultadoIniciar = concat('create temporary table sentencia select ', @tabla, '*, (@fila:= @fila + 1) as RegFila',  @cJoinCampoO) ;
	set @cResultadoTotales = concat('create temporary table sentencia select COUNT(*) total_filas ');
	if coalesce(_camposB, '') <> '' then
		set @cResultadoA = concat(@cResultadoA, _camposB) ;
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	set @cResultadoA = concat(@cResultadoA, '  from ', _tabla) ;
	if coalesce(_jointb, '') <> '' then
		set @cResultadoA = concat(@cResultadoA, ' ', coalesce(_jointb, ''));
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Agrega el LEFT JOIN de la Tabla por la que ordenara la busqueda.
	set @cResultadoA = concat(@cResultadoA, ' ', coalesce(@cJoinOrdenB, '') ) ;
	
	-- ----------------------------------------------------------------------------------------------
	set @cResultadoA = concat(@cResultadoA, @empresa, @sucursal) ;
	
	-- ----------------------------------------------------------------------------------------------
	-- De pasar la fecha como parametro, se incluye la opción para el rango de fecha
	--
	if trim(coalesce(_desde, '')) <> '' and _tipoBusq = 1 then
		set @desde = STR_TO_DATE(Trim(_desde), '%m/%d/%Y');
		set @hasta = STR_TO_DATE(Trim(_hasta), '%m/%d/%Y');
		set  @cResultadoA = CONCAT(@cResultadoA, ' and ', @tabla, 'fecha between ', QUOTE(@desde), ' and ', QUOTE(@hasta));
	end if ;
	
	if trim(@valor) <> '' then
		set @cResultadoB = concat(@cResultadoB, ' and ', @tablaBA, @bCampos) ;
		set @parent = '' ;
		
		-- ----------------------------------------------------------------------------------------------
		-- Valida el operador a utilizar para comparar el campo vs el valor
		if @operador = 'LIKE' then
			set @cResultadoB = concat(@cResultadoB, ' LIKE ', '''', '%', trim(@valor), '%', '''') ;
		elseif @operador = 'REGEXP' then
			set @cResultadoB = concat(@cResultadoB, ' REGEXP ', '''', trim(@valor), '''') ;
		else
			set @cResultadoB = concat(@cResultadoB, trim(@operador), '''', trim(@valor), '''') ;
		end if;
	else
		-- ----------------------------------------------------------------------------------------------
		-- En caso que no se requiera validar con un maestro, la variable pasa a ser en blanco y un ')' como valor predeterminado
		set @parent = '' ;
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Integra todas las cadenas armadas para construir el cursor.
	--
	set @cResultadoB = concat(@cResultadoB, @parent) ;
	if coalesce(_regpp, 0) <> 0 then
		set @cResultadoC = concat(' LIMIT ', @iLimiteInicio, ', ',  @iLimite) ;
	else
		set @cResultadoC = '' ;
	end if ;
	-- set @cResultado = concat(@cResultadoA, @cResultadoB, @cOrdenado, @cResultadoC) ;
	set @cResultado = concat(@cResultadoA, @cResultadoB, @cOrdenado, @cResultadoC) ;
    
	-- ----------------------------------------------------------------------------------------------
	-- Se construye la cadena para obtener el Total de Registros.
	set @cResultadoT = concat(@cResultadoTotales, @cResultadoA, @cResultadoB, @cOrdenado);
    
	drop temporary table if exists sentencia ;
	prepare sentencia from @cResultadoT ;
	execute sentencia ;
	deallocate prepare sentencia;
	
	-- ----------------------------------------------------------------------------------------------
	-- Se construye la cadena para obtener los registros, y se anexa la variable con el total de registros de
	-- @cResultadoT
	select total_filas into @iNumeroFila from sentencia;
	set @iPaginaUltima =  round((@iNumeroFila/@iLimite), 0) ;
	if coalesce(@iPaginaUltima, 0) = 0 then
		set @iPaginaUltima = 1 ;
	end if ;
	
	-- ----------------------------------------------------------------------------------------------
	-- Se construye la cadena para realizar la consulta de los registros a mostrar en la Lista Formulario
	-- segun los parametros indicados.
	-- Se agrega la variable @iPaginaUltima a la cadena antes de realizar la consulta a través del Prepare.
	set @cResultadoI = concat(@cResultadoIniciar, ', @iPagina as PagAct, @iNumeroFila as Filas, round(@iPaginaUltima,0) as PagUltima ', @cResultado);
    
	drop temporary table if exists sentencia ;
	prepare sentencia from @cResultadoI ;
	execute sentencia ;
	deallocate prepare sentencia;

    -- ----------------------------------------------------------------------------------------------
    -- La Cadena de consulta que se devolvera estara vacia, dado que ya no se requiere.
    -- ----------------------------------------------------------------------------------------------
    -- set _cResultado = '';
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `str_cadena_operacional` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `str_cadena_operacional`(
	in _codemp varchar(2),
	in _sucursal varchar(3),
	in _tabla varchar(25),
	in _adicional varchar(5000), 
	in _estado int,
	in _desde varchar(10),
	in _hasta varchar(10),
	Out _cresultado varchar(1500)
)
begin
	/* ---------------------------------------------------
		Busqueda y paginador generico de formularios listas
		Versión 1.0
		Creado: 2024.12.01
		Actualizado: 2024.12.16
		Autor: 
	--------------------------------------------------- */
    
	-- Validación de parámetros
    if (_codemp is null) OR (_sucursal is null) or (_tabla is null) or (_bcampos is null)  or (_operador is null) then
        signal sqlstate '45000'
            set message_text = 'Parámetros incompletos. Todos los campos deben estar especificados.';
    end if ;
    
	-- ----------------------------------------------------------------------------------------------
	-- se crea una cadena para filtral por empresa y sucursal
	-- ----------------------------------------------------------------------------------------------
	-- Se crea una cadena para filtral por empresa y sucursal
	set @Fila = 0 ;
	set @sucursal = '' ;
	
	set @empresa = concat(' where codemp = ', _codemp);
	if trim(_sucursal) <> '' then
		set @sucursal = concat(' and sucursal = ', _sucursal);
	end if;
	
	-- ----------------------------------------------------------------------------------------------
	-- crea la cadena para realizar la búsqueda de los números de presupuesto que se mostraran como resultado final
	set @cSentencia = concat('create temporary table sentencia select SQL_CALC_FOUND_ROWS *, (@fila:= @fila + 1) as RegFila from ', _tabla, @empresa, @sucursal) ;
	if trim(coalesce(_adicional, '')) <> '' then
		set @cSentencia = concat(@cSentencia, ' and ', _adicional);
	end if; 
	
	-- ----------------------------------------------------------------------------------------------
	-- De pasar la fecha como parametro, se incluye la opción para el rango de fecha
	if trim(coalesce(_desde, '')) <> '' then
		set @desde = STR_TO_DATE(Trim(_desde), '%m/%d/%Y');
		set @hasta = STR_TO_DATE(Trim(_hasta), '%m/%d/%Y');
		set @cSentencia = concat(@cSentencia, ' and fecha between ', '''', @desde, '''', ' and ', '''', @hasta, '''');
	end if ;
	
	if coalesce(_estado, 0) <> 0 then
	 	set @cSentencia = concat(@cSentencia, ' and estado = ', _estado);
	end if;
	set _cResultado = @cSentencia ;
end ;;
DELIMITER ;
/*!50003 DROP PROCEDURE IF EXISTS `str_cfg_alter_autoincremental_u` */;
DELIMITER ;;
CREATE DEFINER=`dbuser`@`%` PROCEDURE `str_cfg_alter_autoincremental_u`(
	in _tabla varchar(50),
    in _orden varchar(50)
)
begin
	set @tabla = coalesce(trim(_tabla), '') ;
    set @orderby = coalesce(trim(_orden), '') ;
    set @item = 0;
	set @valor = 0 ;
    
	-- ----------------------------------------------------------------------------------------------
    set @sql = concat('select max(item)+1 into @item from ', @tabla) ;
    prepare	sentencia from @sql ;
    execute sentencia ;
    deallocate prepare sentencia ;
    
    -- ----------------------------------------------------------------------------------------------
    set @sql = concat('update ', @tabla, ' set item = (@item := @item + 1) ') ;
    prepare	sentencia from @sql ;
    execute sentencia ;
    deallocate prepare sentencia ;
    
    -- ----------------------------------------------------------------------------------------------
    set @sql = concat('update ', @tabla, ' set item = (@valor := @valor + 1) order by ', @orderby) ;
    prepare	sentencia from @sql ;
    execute sentencia ;
    deallocate prepare sentencia ;
    
    -- ----------------------------------------------------------------------------------------------
    set @sql = concat('alter table ', @tabla, ' auto_increment = ', @valor) ;
    prepare	sentencia from @sql ;
    execute sentencia ;
    deallocate prepare sentencia ;
end ;;
DELIMITER ;


