create or replace PROCEDURE FCT_COPIA_FORM_PRECO(
 P_NRFORMPRECOSERVICO IN NUMBER,
 P_NRORG IN NUMBER,
 P_OPERADOR IN VARCHAR2)
AS

V_NRFORMPRECOSERVICO NUMBER;
V_NRCALCFORMPRECSERV NUMBER;
V_IDITEMCALCULOPAI VARCHAR2(20);
V_REFERENCIA VARCHAR2(500);
V_PAI NUMBER;

BEGIN
    /* 1 - Copia a capa da formação de Preços*/     
   	FOR C_FORM IN (SELECT NRFORMPRECOSERVICO, NMFORMPRECOSERVICO, CDSERVORCA, NRPARCNEGOCIO, NRESTRUTURAM
				     FROM  FCT_FORMPRECOSERVICO
				    WHERE  NRFORMPRECOSERVICO = P_NRFORMPRECOSERVICO
				      AND NRORG = P_NRORG) LOOP
    
   		NOVO_CODIGO_NT('FCT_FORMPRECOSERVICO', V_NRFORMPRECOSERVICO,1,P_NRORG);
   
	    INSERT INTO FCT_FORMPRECOSERVICO (NRFORMPRECOSERVICO, NMFORMPRECOSERVICO, CDSERVORCA, NRPARCNEGOCIO, NRESTRUTURAM, NRORG,DTINCLUSAO, NRORGINCLUSAO, CDOPERINCLUSAO, IDATIVO)
	    VALUES (V_NRFORMPRECOSERVICO, C_FORM.NMFORMPRECOSERVICO, C_FORM.CDSERVORCA, C_FORM.NRPARCNEGOCIO,C_FORM.NRESTRUTURAM, P_NRORG,SYSDATE, P_NRORG, P_OPERADOR, 'S');

        /* 2 - copia os cálculos da formação de preços */ 
        FOR C_CALC IN (SELECT NRCALCFORMPRECSERV, NRFORMPRECOSERVICO, IDORDENACAO, IDITEMCALCULO, IDELEMENTO,
						       NRCALCFORMPRECSERVPAI, DSREFECALCULO, CDHABILITSERV, IDTIPOCALCULO,
						       DSEXPRESSAOCALC, VRPERCCALCULO, VRUNITARIO, QTCALCULO, IDUSAMEDIDA,  
						       CDTPMEDIDASERV, QTMEDIDACALC, VRTOTAL
						  FROM FCT_CALCFORMPRECSERV
						 WHERE NRFORMPRECOSERVICO = P_NRFORMPRECOSERVICO
						   AND NRORG = P_NRORG
						   ORDER BY IDORDENACAO) LOOP

		    
		    /* verifica se o elemento é inferior a outro. Caso seja, copia o IDITEMCALCULO do pai para a referencia, a fim de subtituir futuramente o código do pai realizado na cópia para o c´´odio do pai correto.*/
            BEGIN
	            SELECT IDITEMCALCULO 
	              INTO V_IDITEMCALCULOPAI
	              FROM FCT_CALCFORMPRECSERV 
	             WHERE NRCALCFORMPRECSERV = C_CALC.NRCALCFORMPRECSERVPAI
	               AND NRFORMPRECOSERVICO = P_NRFORMPRECOSERVICO
	               AND NRORG = P_NRORG;
	        EXCEPTION
	        	WHEN NO_DATA_FOUND THEN
	        	  V_IDITEMCALCULOPAI := NULL;
	        END;       
            
            IF V_IDITEMCALCULOPAI IS NOT NULL THEN 
            
            	V_REFERENCIA := C_CALC.DSREFECALCULO||'_PAI_'||V_IDITEMCALCULOPAI;
            
            ELSE

            	V_REFERENCIA := C_CALC.DSREFECALCULO;

            END IF;

		  	NOVO_CODIGO_NT('FCT_CALCFORMPRECSERV', V_NRCALCFORMPRECSERV,1,P_NRORG);

		  	INSERT INTO FCT_CALCFORMPRECSERV (NRCALCFORMPRECSERV, NRFORMPRECOSERVICO, IDORDENACAO, IDITEMCALCULO, IDELEMENTO, NRCALCFORMPRECSERVPAI, DSREFECALCULO, CDHABILITSERV, IDTIPOCALCULO, DSEXPRESSAOCALC, VRPERCCALCULO, VRUNITARIO, QTCALCULO, IDUSAMEDIDA, CDTPMEDIDASERV, QTMEDIDACALC, VRTOTAL, NRORG, DTINCLUSAO, NRORGINCLUSAO, CDOPERINCLUSAO, IDATIVO)
		    VALUES (V_NRCALCFORMPRECSERV, V_NRFORMPRECOSERVICO, C_CALC.IDORDENACAO, C_CALC.IDITEMCALCULO, C_CALC.IDELEMENTO, C_CALC.NRCALCFORMPRECSERVPAI, V_REFERENCIA, C_CALC.CDHABILITSERV, C_CALC.IDTIPOCALCULO, C_CALC.DSEXPRESSAOCALC, C_CALC.VRPERCCALCULO, C_CALC.VRUNITARIO, C_CALC.QTCALCULO,  C_CALC.IDUSAMEDIDA,  C_CALC.CDTPMEDIDASERV, C_CALC.QTMEDIDACALC, C_CALC.VRTOTAL, 
		    	P_NRORG, SYSDATE, P_NRORG, P_OPERADOR, 'S');

  		END LOOP;

        /* 3 - Substitui os pais dos elementos do cálculo para o código certo */
  		FOR C_CALCPAI IN (SELECT NRCALCFORMPRECSERV, NRFORMPRECOSERVICO,
	  							 SUBSTR(DSREFECALCULO, INSTR(DSREFECALCULO, '_PAI_')+5) AS IDPAI,
	  							 SUBSTR(DSREFECALCULO, 0, INSTR(DSREFECALCULO, '_PAI_')-1) AS REFERENCIA
							  FROM FCT_CALCFORMPRECSERV
							 WHERE NRFORMPRECOSERVICO = V_NRFORMPRECOSERVICO
							   AND NRORG = P_NRORG
							   AND NRCALCFORMPRECSERVPAI IS NOT NULL
							   ORDER BY IDORDENACAO) LOOP

						SELECT NRCALCFORMPRECSERV
						  INTO V_PAI
						  FROM FCT_CALCFORMPRECSERV 
						 WHERE IDITEMCALCULO = C_CALCPAI.IDPAI
						   AND NRFORMPRECOSERVICO = V_NRFORMPRECOSERVICO
						   AND NRORG = P_NRORG;

						UPDATE FCT_CALCFORMPRECSERV
						   SET NRCALCFORMPRECSERVPAI  =  V_PAI,
						       DSREFECALCULO = C_CALCPAI.REFERENCIA
						 WHERE NRCALCFORMPRECSERV = C_CALCPAI.NRCALCFORMPRECSERV
						   AND NRFORMPRECOSERVICO = V_NRFORMPRECOSERVICO
						   AND NRORG = P_NRORG;
		END LOOP; 
	END LOOP;
  COMMIT;
END;