create or replace PROCEDURE P_Migracion_O47_AD74A
AS
    usuarioMigracion VARCHAR2(10) := 'Mig_O47';
    
    numAux integer := 0;
    strAux varchar2(1000);

    -- Zonas
    numeroZonasProcesadas INTEGER := 0;
    numeroZonasProcesadasConExito INTEGER := 0;
    numeroZonasProcesadasConError INTEGER := 0;

    zonaId NUMBER(5);
    zonaThId VARCHAR2(2);
    zonaMuId VARCHAR2(3);
    zonaNomES VARCHAR2(100);
    zonaNomEU VARCHAR2(100);

    -- Usuarios
    cuUsuariosId VARCHAR2(15);
    cuUsuariosNombre VARCHAR2(30);
    cuUsuariosApellidos VARCHAR2(111);
    cuUsuariosEMail VARCHAR2(50);
    cuUsuariosTelefono VARCHAR2(25);
	cuUsuariosPuesto VARCHAR2(50);
    
    numeroUsuariosTeleasistencia INTEGER;
    
    numeroUsuariosProcesados INTEGER;
    numeroUsuariosProcesadosConExito INTEGER;
    numeroUsuariosProcesadosConError INTEGER;
    
    errorProcesamientoUsuarios INTEGER;

    -- UsuariosEntidades
    cuUsuarioEntidadesEntidadId NUMBER(6);

    numeroRelacionesUsuariosEntidadesTeleasistencia INTEGER;
    numeroEntidadesTeleasistencia INTEGER;

    numeroUsuariosEntidadesProcesados INTEGER;
    numeroUsuariosEntidadesProcesadosConExito INTEGER;
    numeroUsuariosEntidadesProcesadosConError INTEGER;

	entidadTerritorioHistoricoId VARCHAR2(2);
	entidadMunicipioId VARCHAR2(3);
	entidadNombreES VARCHAR2(100);

    idAyuntamiento NUMBER;
	numeroAyuntamientosThYMunicipio INTEGER;
	numeroAyuntamientosThMunicipioYNombre INTEGER;
    
    numeroUsuariosAyuntamientosCreados INTEGER;

    -- UsuariosZonas
    cuUsuariosZonasTerritorioHistoricoId VARCHAR2(2);
    cuUsuariosZonasMunicipioId VARCHAR2(3);
    cuUsuariosZonasZonaId NUMBER(5);

    numeroRelacionesUsuariosZonasTeleasistencia INTEGER;
    numeroZonasTeleasistencia INTEGER;
    numeroZonas INTEGER;

    numeroUsuariosZonasProcesadas INTEGER;
    numeroUsuariosZonasProcesadasConExito INTEGER;
    numeroUsuariosZonasProcesadasConError INTEGER;

    maxUsuariosZonasId NUMBER;
    nuevoUsuariosZonasId NUMBER;

    unidadBaseIdRelacionZona NUMBER;
    
    -- Solo vamos a migrar ZONAs de O47 que tengan una relación con DATOSUSUARIOS en ZONASUSUARIOS de los usuarios de teleasistencia
    CURSOR curZonas IS
        SELECT ZONA.ZOTHID, ZONA.ZOMUID, ZONA.ZOID, ZONA.ZONOMBES, ZONA.ZONOMBEU
        FROM O47.O47I8T00@O47_DBL0 ZONA;
        /*
        WHERE 
        (
            (EXISTS (
                        SELECT ZONAUSUARIO.* 
                        FROM O47.O47I9T00@O47_DBL0 ZONAUSUARIO
                        WHERE 
                        (
                            (ZONAUSUARIO.ZUZOTHID = ZONA.ZOTHID) AND 
                            (ZONAUSUARIO.ZUZOMUID = ZONA.ZOMUID) AND 
                            (ZONAUSUARIO.ZUZOID = ZONA.ZOID) AND
                            (ZONAUSUARIO.ZUUSID IN (SELECT DATOSUSUARIOS.DUUSID FROM O47.O47ABT00@O47_DBL0 DATOSUSUARIOS WHERE (DATOSUSUARIOS.DUPERFILES LIKE '%X87A-PF-0001%')))                    
                        )
                    )
            )
        )
        ORDER BY ZONA.ZOTHID, ZONA.ZOMUID, ZONA.ZOID;
        */

    -- Se migrarán todos los DATOSUSUARIOS que tengan el perfil 'X87A-PF-0001' definido en DUPERFILES (usuarios de teleasistencia)
    CURSOR curUsuarios IS    
        SELECT
            DATOSUSUARIOS.DUUSID AS UsuarioId,
            DATOSUSUARIOS.DUNOMBRE AS UsuarioNombre,
            TRIM(DATOSUSUARIOS.DUAPELLIDO1) || ' ' || TRIM(DATOSUSUARIOS.DUAPELLIDO2) AS UsuarioApellidos,
            DATOSUSUARIOS.DUEMAIL AS UsuarioEMail,
            DATOSUSUARIOS.DUTELEFONO AS UsuarioTelefono,
			DATOSUSUARIOS.DUUID AS UsuarioPuesto
        FROM O47.O47ABT00@O47_DBL0 DATOSUSUARIOS
        WHERE (DATOSUSUARIOS.DUPERFILES LIKE '%X87A-PF-0001%');

    -- Entidades de usuarios
    CURSOR curUsuariosEntidades (idUsuario VARCHAR2) IS
        SELECT USUARIOS.USENID FROM O47.O4713T00@O47_DBL0 USUARIOS WHERE (USID = idUsuario);
   
    -- Zonas de usuarios
    CURSOR curUsuariosZonas (idUsuario VARCHAR2) IS
        SELECT ZUZOID, ZUZOTHID, ZUZOMUID
        FROM O47.O47I9T00@O47_DBL0 ZONAUSUARIO INNER JOIN O47.O47I8T00@O47_DBL0 ZONA ON ((ZONAUSUARIO.ZUZOID = ZONA.ZOID) AND (ZONAUSUARIO.ZUZOTHID = ZONA.ZOTHID) AND (ZONAUSUARIO.ZUZOMUID = ZONA.ZOMUID))
        -- WHERE ((ZONAUSUARIO.ZUUSID = idUsuario) AND (ZONAUSUARIO.ZUZOID = 0) AND (ZONAUSUARIO.ZUZOMUID <> '-1'));
        WHERE (ZONAUSUARIO.ZUUSID = idUsuario);

BEGIN
    -- ----------------------------------------------------------
	-- Comprobar que los AYUNTAMIENTOS estén migrados (INICIO) --
    -- ----------------------------------------------------------
	-- Compobaremos que estén migrados las AYUNTAMIENTOS correspondientes a las ENTIDAD (o47) de los USUARIOS de los DATOSUSUARIO que vayamos a migrar
	SELECT COUNT(*) INTO numAux
	FROM (
            SELECT ENTIDAD.ENTHID, ENTIDAD.ENMUID
            FROM o47.o4705t00@O47_DBL0 ENTIDAD
            WHERE 
            (
                (ENTIDAD.ENID IN (
                                    SELECT DISTINCT USENID 
                                    FROM O47.O4713T00@O47_DBL0 USUARIOS 
                                    WHERE 
                                    (
                                        (USUARIOS.USID IN (
                                                            SELECT DATOSUSUARIOS.DUUSID 
                                                            FROM O47.O47ABT00@O47_DBL0 DATOSUSUARIOS 
                                                            WHERE (DATOSUSUARIOS.DUPERFILES LIKE '%X87A-PF-0001%')
                                                          )
                                        )
                                    )
                                  )
                )
            )            
		 ) ENTIDAD
	WHERE (NOT EXISTS (SELECT AYUNTAMIENTOS.* FROM AD74A31T00 AYUNTAMIENTOS WHERE ((AYUNTAMIENTOS.ID_PROVINCIA_31 = ENTIDAD.ENTHID) AND (AYUNTAMIENTOS.ID_MUNICIPIO_31 = ENTIDAD.ENMUID) AND (AYUNTAMIENTOS.BAJA_31 = '0'))));

    if (numAux > 0) then
		dbms_output.put_line('ADVERTENCIA: Se han detectado ' || numAux || ' ENTIDADes de O47 con usuarios definidos que no tienen el AYUNTAMIENTOS definido en AD74A');
		
		-- TODO: ¿Finalizar o continuar?
    end if;    
    -- -------------------------------------------------------
	-- Comprobar que los AYUNTAMIENTOS estén migrados (FIN) --
    -- -------------------------------------------------------
	
	-- -------------------------------------------------------------------
    -- CONTEO DE DATOS INICIALES DE USUARIOS DE TELEASISTENCIA (INICIO) --
    -- -------------------------------------------------------------------
    -- USUARIOS DE TELEASISTENCIA
    SELECT COUNT(*) INTO numeroUsuariosTeleasistencia FROM O47.O47ABT00@O47_DBL0 DATOSUSUARIOS WHERE (DATOSUSUARIOS.DUPERFILES LIKE '%X87A-PF-0001%');
    dbms_output.put_line('Se han encontrado ' || NVL(numeroUsuariosTeleasistencia, 0) || ' USUARIOS de Teleasistencia, perfil LIKE %X87A-PF-0001%'); 
    
    -- Numero de relaciones USUARIOS y ZONAS de USUARIOS de teleasistencia
    SELECT COUNT(*) INTO numeroRelacionesUsuariosZonasTeleasistencia
    FROM O47.O47I9T00@O47_DBL0 ZONAUSUARIO
    WHERE (ZONAUSUARIO.ZUUSID IN (SELECT DATOSUSUARIOS.DUUSID FROM O47.O47ABT00@O47_DBL0 DATOSUSUARIOS WHERE (DATOSUSUARIOS.DUPERFILES LIKE '%X87A-PF-0001%')));
    dbms_output.put_line('Se han encontrado ' || NVL(numeroRelacionesUsuariosZonasTeleasistencia, 0) || ' relaciones de USUARIOS y ZONAS de USUARIOS de teleasistencia'); 
    
    -- Numero de ZONAs de USUARIOS de teleasistencia
    SELECT COUNT(*) INTO numeroZonasTeleasistencia
    FROM O47.O47I8T00@O47_DBL0 ZONA
    WHERE 
    (
        (EXISTS (
                    SELECT ZONAUSUARIO.* 
                    FROM O47.O47I9T00@O47_DBL0 ZONAUSUARIO
                    WHERE 
                    (
                        (ZONAUSUARIO.ZUZOTHID = ZONA.ZOTHID) AND 
                        (ZONAUSUARIO.ZUZOMUID = ZONA.ZOMUID) AND 
                        (ZONAUSUARIO.ZUZOID = ZONA.ZOID) AND
                        (ZONAUSUARIO.ZUUSID IN (SELECT DATOSUSUARIOS.DUUSID FROM O47.O47ABT00@O47_DBL0 DATOSUSUARIOS WHERE (DATOSUSUARIOS.DUPERFILES LIKE '%X87A-PF-0001%')))                    
                    )
                )
        )
    );
    dbms_output.put_line('Se han encontrado ' || NVL(numeroZonasTeleasistencia, 0) || ' ZONAS de USUARIOS de teleasistencia'); 

    -- Numero de ZONAs
    SELECT COUNT(*) INTO numeroZonas
    FROM O47.O47I8T00@O47_DBL0 ZONA;
    dbms_output.put_line('Se han encontrado ' || NVL(numeroZonas, 0) || ' ZONAS'); 
    
    -- Numero de relaciones USUARIOS y ENTIDAD de USUARIOS de teleasistencia
    SELECT COUNT(*) INTO numeroRelacionesUsuariosEntidadesTeleasistencia
    FROM O47.O4713T00@O47_DBL0 USUARIOS
    WHERE (USUARIOS.USID IN (SELECT DATOSUSUARIOS.DUUSID FROM O47.O47ABT00@O47_DBL0 DATOSUSUARIOS WHERE (DATOSUSUARIOS.DUPERFILES LIKE '%X87A-PF-0001%')));
    dbms_output.put_line('Se han encontrado ' || NVL(numeroRelacionesUsuariosEntidadesTeleasistencia, 0) || ' relaciones USUARIOS y ENTIDAD de USUARIOS de teleasistencia'); 
    
    -- Numero de ENTIDADES de USUARIOS de teleasistencia
    SELECT COUNT(*) INTO numeroEntidadesTeleasistencia
    FROM O47.O4705T00@O47_DBL0 ENTIDAD
    WHERE 
    (
        (EXISTS (
                    SELECT USUARIOS.* 
                    FROM O47.O4713T00@O47_DBL0 USUARIOS
                    WHERE 
                    (
                        (USUARIOS.USID IN (SELECT DATOSUSUARIOS.DUUSID FROM O47.O47ABT00@O47_DBL0 DATOSUSUARIOS WHERE (DATOSUSUARIOS.DUPERFILES LIKE '%X87A-PF-0001%'))) AND 
                        (USUARIOS.USENID = ENTIDAD.ENID)
                    )
                )
        )
    );
    dbms_output.put_line('Se han encontrado ' || NVL(numeroEntidadesTeleasistencia, 0) || ' ENTIDADes de USUARIOS de teleasistencia'); 
	-- ----------------------------------------------------------------
    -- CONTEO DE DATOS INICIALES DE USUARIOS DE TELEASISTENCIA (FIN) --
    -- ----------------------------------------------------------------
    
    
    -- -----------------------------------------------------------------------------------------
	-- Migrar las ZONAS de O47 a UNIDADES_BASE de AD74A guardando la relación de Ids (INICIO) --
    -- -----------------------------------------------------------------------------------------
    -- Solo vamos a migrar ZONAs de O47 que cumplan:
    --  * Exista una relación con DATOSUSUARIOS en ZONASUSUARIOS de los usuarios de teleasistencia
    -- Partimos de que no existe ningún dato previo de UNIDADES_BASE (la tabla ha sido borrada)
    
    -- Se guardarán las relaciones entre las ZONAS de O47 migradas y las UNIDADES_BASE creadas:
    --  * ZOID, ZOTHID, ZOMUID
    --  * ID_UNIDAD_BASE_92
	
    dbms_output.put_line('INICIO de migración de ZONA -> UNIDADES'); 
    
    -- Inicializamos la tabla temporal para guardar la relacion de Ids creados en la migracion
    DELETE FROM RELACION_ZONA_UNIDADES_BASE;
    
    -- Procesamos el cursor de ZONA
    OPEN curZonas;

    numeroZonasProcesadas := 0;
    numeroZonasProcesadasConExito := 0;
    numeroZonasProcesadasConError := 0;

    LOOP
        FETCH curZonas INTO zonaThId, zonaMuId, zonaId, zonaNomES, zonaNomEU;
        EXIT WHEN curZonas%NOTFOUND;
        
        BEGIN
            numeroZonasProcesadas := numeroZonasProcesadas + 1;
            
            -- Insertamos la UNIDADES_BASE
            INSERT INTO AD74A92T00(ID_UNIDAD_BASE_92, ID_PROVINCIA_92, ID_MUNICIPIO_92, DESC_ES_92, DESC_EU_92, USU_ALTA_92, F_ALTA_92) VALUES (SEQ_UNIDADES_BASE.NEXTVAL, zonaThId, zonaMuId, zonaNomES, zonaNomEU, usuarioMigracion, SYSDATE);
            
            -- Insertamos la relación RELACION_ZONA_UNIDADES_BASE
            INSERT INTO RELACION_ZONA_UNIDADES_BASE (ZoId, ZonaThId, ZonaMuId, UnidadBaseId) VALUES (zonaId, zonaThId, zonaMuId, SEQ_UNIDADES_BASE.CURRVAL);
            
            numeroZonasProcesadasConExito := numeroZonasProcesadasConExito + 1;
            COMMIT;
            
            EXCEPTION
                WHEN OTHERS THEN
                    BEGIN
                        numeroZonasProcesadasConError := numeroZonasProcesadasConError + 1;                        
                        -- dbms_output.put_line('Error no esperado procesando la ENTIDAD de Id ' || curEntidadesId || ', THId: ' || curEntidadesTHId || ', MunId: ' || curEntidadesMunId || ': (' || SQLCODE || ') ' || SQLERRM);
                        dbms_output.put_line('ERROR NO ESPERADO PROCESANDO LA ZONA ' || zonaThId || zonaMuId || ' - ' || zonaId || ': ' || zonaNomES || ' (' || SQLCODE || ') ' || SQLERRM);

                        ROLLBACK;
                        -- dbms_output.put_line('ROLLBACK');                        
                    END;            
        END;
    END LOOP;
    
    dbms_output.put_line('Se han proceso ' || numeroZonasProcesadas || ' ZONAs: ' || numeroZonasProcesadasConExito || ' con éxito y ' || numeroZonasProcesadasConError || ' con ERROR' );

    -- El número de RELACION_ZONA_UNIDADES_BASE creadas debería coincider con las zonas procesadas con éxito
    SELECT COUNT(*) INTO numAux FROM RELACION_ZONA_UNIDADES_BASE;
    dbms_output.put_line('Se han generado ' || numAux || ' relaciones de Ids de ENTIDAD y UNIDADES_BASE'); 

    dbms_output.put_line('FIN de migración de ZONA -> UNIDADES');
    -- --------------------------------------------------------------------------------------
	-- Migrar las ZONAS de O47 a UNIDADES_BASE de AD74A guardando la relación de Ids (FIN) --
    -- --------------------------------------------------------------------------------------
    
    -- --------------------------------------------------------------------------------------------------------------------------------------
	-- CURSOR DE USUARIOS - migrar los USUARIOS de O47 a USUARIOS de AD74A incluyendo relaciones con AYUNTAMIENTO y UNIDADES_BASE (INICIO) --
    -- --------------------------------------------------------------------------------------------------------------------------------------
    
    -- ------------------------------
    -- CURSOR DE USUARIOS (INICIO) --
    -- ------------------------------
    -- Crear el CURSOR de Usuarios a migrar:
    --  * Migrar los datos de usuario
    --  * Migrar la relación de AYUNTAMIENTOS
    --  * Migrar la relación de ENTIDADES
    --  * COMMIT POR USUARIO
    -- ---------------------------
    -- CURSOR DE USUARIOS (FIN) --
    -- ---------------------------
    
    dbms_output.put_line('INICIO de migración de USUARIOS'); 
    
    OPEN curUsuarios;
    
    numeroUsuariosProcesados := 0;
    numeroUsuariosProcesadosConExito := 0;
    numeroUsuariosProcesadosConError := 0;
    
    numeroUsuariosZonasProcesadas := 0;
    numeroUsuariosZonasProcesadasConExito := 0;
    numeroUsuariosZonasProcesadasConError := 0;
    
    numeroUsuariosEntidadesProcesados := 0;
    numeroUsuariosEntidadesProcesadosConExito := 0;
    numeroUsuariosEntidadesProcesadosConError := 0;
    
    LOOP    
        FETCH curUsuarios into cuUsuariosId, cuUsuariosNombre, cuUsuariosApellidos, cuUsuariosEMail, cuUsuariosTelefono, cuUsuariosPuesto;
        EXIT WHEN curUsuarios%NOTFOUND;

        BEGIN
            BEGIN
                -- dbms_output.put_line('Procesando el USUARIO DE 047 de Id ' || cuUsuariosId || ', Nombre: ' || NVL(cuUsuariosNombre, '-') || ', Apellidos: ' || NVL(cuUsuariosApellidos, '-') || ', EMail: ' || NVL(cuUsuariosEMail, '-') || ', Telefono: ' || NVL(curUsuariosTelefono, '-'));
                numeroUsuariosProcesados := numeroUsuariosProcesados + 1;
                errorProcesamientoUsuarios := 0;
                
                -- En principio todos los usuarios son válidos
                
                -- Creamos el usuario
                INSERT INTO AD74A80T00(ID_USUARIO_80, IDENTIFICADOR_80, NOMBRE_80, APELLIDOS_80, USU_XLNETS_80, EMAIL_80, TLFNO_80, F_ALTA_80, USU_ALTA_80, PUESTO_80)
                VALUES(SEQ_USUARIOS.NEXTVAL, cuUsuariosId, cuUsuariosNombre, cuUsuariosApellidos, cuUsuariosId, cuUsuariosEMail, SUBSTR(cuUsuariosTelefono, 1, 20), SYSDATE, usuarioMigracion, SUBSTR(cuUsuariosPuesto, 1, 20));  
                -- dbms_output.put_line('Creado el nuevo usuario de Id ' || SEQ_USUARIOS.CURRVAL);
                
                -- Intentamos crear las relaciones de UNIDADES_BASE_USUARIO en AD74A correspondientes a las relaciones de los usuarios del cursor curUsuariosZonas con ZONAs en O47
                BEGIN
                    -- Abrimos el cursor de la ZONAs relacionadas con el usuario en O47
                    OPEN curUsuariosZonas(cuUsuariosId);
                    
                    LOOP
                        FETCH curUsuariosZonas INTO cuUsuariosZonasZonaId, cuUsuariosZonasTerritorioHistoricoId, cuUsuariosZonasMunicipioId;
                        EXIT WHEN curUsuariosZonas%NOTFOUND;
                    
                        numeroUsuariosZonasProcesadas := numeroUsuariosZonasProcesadas + 1;                   
                        -- DBMS_OUTPUT.PUT_LINE('Encontrada la relación entre el USUARIO de Id ' || cuUsuariosId || ' y la ZONA del TH ' || cuUsuariosZonasTerritorioHistoricoId || ' del municipio ' || cuUsuariosZonasMunicipioId || ' de ZonaId ' || cuUsuariosZonasZonaId);
                        
                        -- Recuperamos la UNIDADES_BASE correspondiente a la ENTIDAD del usuario que estamos procesando y creamos la relación correspondiente
                        BEGIN
                            SELECT UnidadBaseId INTO unidadBaseIdRelacionZona FROM RELACION_ZONA_UNIDADES_BASE WHERE((ZonaThId = cuUsuariosZonasTerritorioHistoricoId) AND (ZonaMuId = cuUsuariosZonasMunicipioId) AND (ZoId = cuUsuariosZonasZonaId));
                            -- DBMS_OUTPUT.PUT_LINE('Encontrado la UNIDADES_BASE de Id ' || unidadBaseIdEntidad || ' relacionada con la ENTIDAD del usuario de Id ' || usuarioEntidadId);
                           
                            -- Creamos la nueva UNIDADES_BASE_USUARIO
                            INSERT INTO AD74A93T00(ID_UNIDAD_BASE_93, ID_USUARIO_93, F_ALTA_93, USU_ALTA_93) VALUES (unidadBaseIdRelacionZona, SEQ_USUARIOS.CURRVAL, SYSDATE, usuarioMigracion);
                            -- DBMS_OUTPUT.PUT_LINE('Creada la UNIDADES_BASE_USUARIO de la UNIDADES_BASE de Id ' || unidadBaseIdEntidad || ' y el USUARIOS de Id ' || nuevoUsuarioId);
                            
                            numeroUsuariosZonasProcesadasConExito := numeroUsuariosZonasProcesadasConExito + 1;
                            
                            EXCEPTION 
                                WHEN NO_DATA_FOUND THEN
                                    BEGIN
                                        dbms_output.put_line('ADVERTENCIA: No se ha encontrado la UNIDADES_BASE relacionada con la ZONA del TH ' || cuUsuariosZonasTerritorioHistoricoId || ' del municipio ' || cuUsuariosZonasMunicipioId || ' de ZonaId ' || cuUsuariosZonasZonaId || ' del usuario de Id ' || cuUsuariosId);
                                        
                                        numeroUsuariosZonasProcesadasConError := numeroUsuariosZonasProcesadasConError + 1;
                                        errorProcesamientoUsuarios := 1;
                                        EXIT;
                                    END;

                                WHEN OTHERS THEN
                                    BEGIN
                                        dbms_output.put_line('ERROR NO ESPERADO creando la relación UNIDADES_BASE_USUARIO de la UNIDADES_BASE de Id ' || unidadBaseIdRelacionZona || ' (' || cuUsuariosZonasTerritorioHistoricoId || ' - ' || cuUsuariosZonasMunicipioId || ' - ' || cuUsuariosZonasZonaId || ') y el USUARIOS de Id ' || SEQ_USUARIOS.CURRVAL || ': (' || SQLCODE || ') ' || SQLERRM);
                                        
                                        numeroUsuariosZonasProcesadasConError := numeroUsuariosZonasProcesadasConError + 1;
                                        errorProcesamientoUsuarios := 1;
                                        EXIT;
                                    END;
                        END;
                    END LOOP;   
                    CLOSE curUsuariosZonas;

                    IF (errorProcesamientoUsuarios <> 0) THEN
                        DBMS_OUTPUT.PUT_LINE('Se ha producido error procesado las ZONAS del usuario de Id ' || cuUsuariosId);                    
                        errorProcesamientoUsuarios := 1;
                    END IF;      
  
                    EXCEPTION
                        WHEN OTHERS THEN
                            BEGIN
                                -- errorProcesamientoUsuarios := 1;
                                -- numeroUsuariosProcesadosConError := numeroUsuariosProcesadosConError + 1;                        
                                DBMS_OUTPUT.PUT_LINE('Error no esperado procesando las ZONAS del nuevo USUARIO de Id ' || SEQ_USUARIOS.CURRVAL || ': (' || SQLCODE || ') ' || SQLERRM);
                                errorProcesamientoUsuarios := 1;

                                /*        
                                ROLLBACK;
                                dbms_output.put_line('ROLLBACK');
                                
                                -- Finalizamos la iteración del usuario y continuamos con el siguiente usuario
                                CONTINUE;
                                */
                            END;                                
                END;
                
                IF (errorProcesamientoUsuarios <> 0) THEN
                    numeroUsuariosProcesadosConError := numeroUsuariosProcesadosConError + 1;
                    
                    ROLLBACK;
                    -- dbms_output.put_line('ROLLBACK');
                    
                    -- Finalizamos la iteración del usuario y continuamos con el siguiente usuario
                    CONTINUE;
                END IF;
                
                -- Intentamos crear las relaciones de USUARIOS_AYUNTAMIENTOS en AD74A correspondientes a las relaciones de los usuarios del cursor curUsuariosEntidades con ENTIDAD en O47 
                BEGIN
                    -- Abrimos el cursor de la entidades relacionadas con el usuario en O47
                    OPEN curUsuariosEntidades(cuUsuariosId);

                    LOOP                    
                        FETCH curUsuariosEntidades INTO cuUsuarioEntidadesEntidadId;
                        EXIT WHEN curUsuariosEntidades%NOTFOUND;
                        
                        numeroUsuariosEntidadesProcesados := numeroUsuariosEntidadesProcesados + 1;
                        
                        BEGIN
                            -- Recuperamos los datos de la ENTIDAD
                            SELECT ENTIDAD.ENTHID, ENTIDAD.ENMUID, ENTIDAD.ENNOMBES INTO entidadTerritorioHistoricoId, entidadMunicipioId, entidadNombreES 
                            FROM O47.O4705T00@O47_DBL0 ENTIDAD 
                            WHERE (ENTIDAD.ENID = cuUsuarioEntidadesEntidadId);

                            EXCEPTION                                   
                                WHEN NO_DATA_FOUND THEN
                                    BEGIN
                                        dbms_output.put_line('ADVERTENCIA: No se ha encontrado la ENTIDAD de Id ' || cuUsuarioEntidadesEntidadId || ' relacionada con el DATOSUSUARIOS de Id ' || cuUsuariosId);
                                        
                                        errorProcesamientoUsuarios := 1;
                                        EXIT;
                                    END;

                                WHEN TOO_MANY_ROWS THEN
                                    BEGIN
                                        dbms_output.put_line('ERROR: Se ha encontrado mas de una ENTIDAD de Id ' || cuUsuarioEntidadesEntidadId || ' relacionada con el DATOSUSUARIOS de Id ' || cuUsuariosId);
                                        
                                        errorProcesamientoUsuarios := 1;
                                        EXIT;
                                    END;

                                WHEN OTHERS THEN
                                    BEGIN
                                        dbms_output.put_line('ERROR NO ESPERADO recuperando los datos de la ENTIDAD de Id ' || cuUsuarioEntidadesEntidadId || ' relacionada con el DATOSUSUARIOS de Id ' || cuUsuariosId || ': (' || SQLCODE || ') ' || SQLERRM);

                                        errorProcesamientoUsuarios := 1;
                                        EXIT;
                                    END;
                        END;

                        BEGIN
                            -- Buscamos el AYUNTAMIENTOS correspondiente a la ENTIDAD
                            idAyuntamiento := 0;
                            
                            SELECT COUNT(*) INTO numeroAyuntamientosThYMunicipio 
                            FROM AD74A31T00 AYUNTAMIENTOS 
                            WHERE ((AYUNTAMIENTOS.ID_PROVINCIA_31 = entidadTerritorioHistoricoId) AND (AYUNTAMIENTOS.ID_MUNICIPIO_31 = entidadMunicipioId) AND (AYUNTAMIENTOS.BAJA_31 = 0));
                            
                            IF (NVL(numeroAyuntamientosThYMunicipio, 0) = 0) THEN
                                DBMS_OUTPUT.PUT_LINE('AVISO: No se ha encontrado el AYUNTAMIENTOS el TH ' || entidadTerritorioHistoricoId || ' y municipio ' || entidadMunicipioId || ' de la ENTIDAD de nombre ' || entidadNombreES);
                            
                                -- numeroUsuariosEntidadesProcesadosConError := numeroUsuariosEntidadesProcesadosConError + 1;
                                -- CONTINUE;
                            ELSIF (NVL(numeroAyuntamientosThYMunicipio, 0) = 1) THEN
                                SELECT ID_AYUNTAMIENTO_31 INTO idAyuntamiento FROM AD74A31T00 AYUNTAMIENTOS WHERE ((AYUNTAMIENTOS.ID_PROVINCIA_31 = entidadTerritorioHistoricoId) AND (AYUNTAMIENTOS.ID_MUNICIPIO_31 = entidadMunicipioId) AND (AYUNTAMIENTOS.BAJA_31 = 0));
                            ELSE
                                -- Hemos encontrado mas de 1 ayuntamiento
                                DBMS_OUTPUT.PUT_LINE('AVISO: Se han encontrado ' || NVL(numeroAyuntamientosThYMunicipio, 0) || ' AYUNTAMIENTOS del TH ' || entidadTerritorioHistoricoId || ' y municipio ' || entidadMunicipioId);
    
                                SELECT COUNT(*) INTO numeroAyuntamientosThMunicipioYNombre 
                                FROM AD74A31T00 AYUNTAMIENTOS 
                                WHERE ((AYUNTAMIENTOS.ID_PROVINCIA_31 = entidadTerritorioHistoricoId) AND (AYUNTAMIENTOS.ID_MUNICIPIO_31 = entidadMunicipioId) AND (AYUNTAMIENTOS.DESC_ES_31 = entidadNombreES) AND (AYUNTAMIENTOS.BAJA_31 = 0));
                                
                                IF (NVL(numeroAyuntamientosThMunicipioYNombre, 0) = 0) THEN
                                    DBMS_OUTPUT.PUT_LINE('ERROR: No se han encontrado AYUNTAMIENTOS del TH ' || entidadTerritorioHistoricoId || ', municipio ' || entidadMunicipioId || ' y nombre ' || entidadNombreES);
                                ELSIF (NVL(numeroAyuntamientosThMunicipioYNombre, 0) = 1) THEN
                                    -- Se ha encontrado el AYUNTAMIENTOS que coincide con el Th, Municipio y nombre
                                    SELECT ID_AYUNTAMIENTO_31 INTO idAyuntamiento FROM AD74A31T00 AYUNTAMIENTOS WHERE ((AYUNTAMIENTOS.ID_PROVINCIA_31 = entidadTerritorioHistoricoId) AND (AYUNTAMIENTOS.ID_MUNICIPIO_31 = entidadMunicipioId) AND (AYUNTAMIENTOS.DESC_ES_31 = entidadNombreES) AND (AYUNTAMIENTOS.BAJA_31 = 0));
                                    DBMS_OUTPUT.PUT_LINE('INFORMACION: Se han encontrado AYUNTAMIENTOS del TH ' || entidadTerritorioHistoricoId || ', municipio ' || entidadMunicipioId || ' y nombre ' || entidadNombreES);
                                ELSE
                                    DBMS_OUTPUT.PUT_LINE('AVISO: Se han encontrado ' || NVL(numeroAyuntamientosThMunicipioYNombre, 0) || ' AYUNTAMIENTOS del TH ' || entidadTerritorioHistoricoId || ', municipio ' || entidadMunicipioId || ' y nombre ' || entidadNombreES);
                                END IF;                            
                            END IF;
                            
                            IF (idAyuntamiento = 0) THEN
                                numeroUsuariosEntidadesProcesadosConError := numeroUsuariosEntidadesProcesadosConError + 1;
                                CONTINUE;
                            END IF;
                            
                            -- Creamos USUARIOS_AYUNTAMIENTOS del usuario y el ayuntamiento encontrado
                            
                            INSERT INTO AD74A81T00(ID_USUARIO_AYTO_81, ID_USUARIO_81, ID_AYUNTAMIENTO_81, F_ALTA_81, USU_ALTA_81) VALUES (SEQ_USUARIOS_AYUNTAMIENTO.NEXTVAL, SEQ_USUARIOS.CURRVAL, idAyuntamiento, SYSDATE, usuarioMigracion);
                            
                            numeroUsuariosEntidadesProcesadosConExito := numeroUsuariosEntidadesProcesadosConExito + 1;
                            
                                EXCEPTION                                   
                                    WHEN OTHERS THEN
                                        BEGIN
                                            dbms_output.put_line('ERROR NO ESPERADO creando la USUARIOS_AYUNTAMIENTOS del AYUNTAMIENTOS de Id ' || SEQ_USUARIOS_AYUNTAMIENTO.CURRVAL || ' y el USUARIOS de Id ' || SEQ_USUARIOS.CURRVAL || ': (' || SQLCODE || ') ' || SQLERRM);
    
                                            errorProcesamientoUsuarios := 1;
                                            EXIT;
                                        END;
                        END;
                                                
                    END LOOP;   
                    CLOSE curUsuariosEntidades;

                    IF (errorProcesamientoUsuarios <> 0) THEN
                        DBMS_OUTPUT.PUT_LINE('Se ha producido error procesado las ENTIDADES del usuario de Id ' || cuUsuariosId);                    
                    END IF;      

                    /*  
                    IF (errorProcesamientoZonasUsuarios = 0) THEN
                        DBMS_OUTPUT.PUT_LINE('Se han procesado ' || numeroZonasUsuariosProcesadas || ' ZONASUSUARIO del usuario de Id ' || cuUsuariosId);
                    ELSE
                        DBMS_OUTPUT.PUT_LINE('Se ha producido error procesado ZONASUSUARIO del usuario de Id ' || cuUsuariosId);                    
                        errorProcesamientoUsuarios := 1;
                    END IF;
                    */
                    IF (errorProcesamientoUsuarios <> 0) THEN
                        DBMS_OUTPUT.PUT_LINE('Se ha producido error procesado ZONASUSUARIO del usuario de Id ' || cuUsuariosId);                    
                        errorProcesamientoUsuarios := 1;
                    END IF;
  
                    EXCEPTION
                        WHEN OTHERS THEN
                            BEGIN
                                DBMS_OUTPUT.PUT_LINE('Error no esperado procesando los USUARIOS_AYUNTAMIENTOS del nuevo USUARIO de Id ' || SEQ_USUARIOS.CURRVAL || ': (' || SQLCODE || ') ' || SQLERRM);
                                errorProcesamientoUsuarios := 1;
                            END;

                END;

                IF (errorProcesamientoUsuarios <> 0) THEN
                    numeroUsuariosProcesadosConError := numeroUsuariosProcesadosConError + 1;
                    
                    ROLLBACK;
                    -- dbms_output.put_line('ROLLBACK');
                    
                    -- Finalizamos la iteración del usuario y continuamos con el siguiente usuario
                    CONTINUE;
                ELSE
                    numeroUsuariosProcesadosConExito := numeroUsuariosProcesadosConExito + 1;
                    
                    COMMIT;
                END IF;
            END;

            EXCEPTION
                WHEN OTHERS THEN
                    BEGIN
                        errorProcesamientoUsuarios := 1;
                        numeroUsuariosProcesadosConError := numeroUsuariosProcesadosConError + 1;                        
                        dbms_output.put_line('Error no esperado procesando el USUARIO DE 047 de Id ' || cuUsuariosId || ', Nombre: ' || cuUsuariosNombre || ', Apellidos: ' || cuUsuariosApellidos || ', EMail: ' || cuUsuariosEMail || ', Telefono: ' || cuUsuariosTelefono || ': (' || SQLCODE || ') ' || SQLERRM);
                        -- dbms_output.put_line('ERROR NO ESPERADO: (' || SQLCODE || ') ' || SQLERRM);

                        ROLLBACK;
                        -- dbms_output.put_line('ROLLBACK');                        
                    END;            

        END;
    END LOOP;
    
    DBMS_OUTPUT.PUT_LINE('FIN de migración de USUARIOS'); 

    DBMS_OUTPUT.PUT_LINE('Se han procesado ' || numeroUsuariosProcesados || ' USUARIOS: ' || numeroUsuariosProcesadosConExito || ' con éxito y ' || numeroUsuariosProcesadosConError || ' erroneos');
    DBMS_OUTPUT.PUT_LINE('Se han procesado ' || numeroUsuariosEntidadesProcesados || ' relaciones de DATOSUSUARIOS y ENTIDADes: ' || numeroUsuariosEntidadesProcesadosConExito || ' con éxito y ' || numeroUsuariosEntidadesProcesadosConError || ' erroneos');
    DBMS_OUTPUT.PUT_LINE('Se han procesado ' || numeroUsuariosZonasProcesadas || ' relaciones de DATOSUSUARIOS y ZONAes: ' || numeroUsuariosZonasProcesadasConExito || ' con éxito y ' || numeroUsuariosZonasProcesadasConError || ' erroneos');

    -- -----------------------------------------------------------------------------------------------------------------------------------
	-- CURSOR DE USUARIOS - migrar los USUARIOS de O47 a USUARIOS de AD74A incluyendo relaciones con AYUNTAMIENTO y UNIDADES_BASE (FIN) --
    -- -----------------------------------------------------------------------------------------------------------------------------------
END;

/