create or replace PROCEDURE ESTIMA_META
  (
	V_CDFILIAL IN VARCHAR2,  V_NRORG IN NUMBER, V_PERCACRES IN FLOAT,
	V_PERIODO IN VARCHAR2 DEFAULT 'N', V_DTINI IN VARCHAR2 DEFAULT NULL, V_DTFIN IN VARCHAR2 DEFAULT NULL,
	P_CDANO IN NUMBER DEFAULT 0
  )
AS
  TYPE tDias  IS VARRAY(7) OF FLOAT;
  TYPE tHoras IS VARRAY(24) OF FLOAT;
  V_NRDIA           NUMBER;
  V_CDMES           NUMBER;
  V_CDANO           NUMBER;
  V_CONTHORA        NUMBER;
  V_CONTADOR        NUMBER;
  V_VNDREALIZADAS   NUMBER;
  V_DIASDASEMANA	NUMBER;
  V_DIASDASEMANAANT	NUMBER;
  V_TOT_VND_DIA     FLOAT;
  V_EST_CMD         FLOAT;
  V_EST_TAA         FLOAT;
  V_EST_DLV         FLOAT;
  V_EST_BAL         FLOAT;
  V_EST_MES         FLOAT;
  V_EST_OUT         FLOAT;
  V_VND_PROV        FLOAT;
  V_VND_PROV2       FLOAT;
  V_VENDASEMANA		FLOAT;
  V_TOTVENDAMES     FLOAT;
  V_TICKETMEDIO     FLOAT;
  V_VALORES		    tDias;
  V_HORAS           tHoras;
BEGIN

	IF (P_CDANO < TO_NUMBER(TO_CHAR(sysdate, 'YYYY')-1))  THEN
		V_CDANO := TO_NUMBER(TO_CHAR(sysdate, 'YYYY'));
	ELSE
		V_CDANO := P_CDANO;
	END IF;

	DELETE FROM METAHORA WHERE CDFILIAL = V_CDFILIAL AND CDANO = V_CDANO;

	DELETE FROM METAMODALIDADEDIA WHERE CDFILIAL = V_CDFILIAL AND CDANO = V_CDANO;

	DELETE FROM METADIA WHERE CDFILIAL = V_CDFILIAL AND CDANO = V_CDANO;

	DELETE FROM METAMES WHERE CDFILIAL = V_CDFILIAL AND CDANO = V_CDANO;

	FOR C_FERIADO IN
		(SELECT DSFERIFILI, DTFERIFILI FROM FERIFILI WHERE CDFILIAL = V_CDFILIAL AND NRORG = V_NRORG AND TO_NUMBER(TO_CHAR(DTFERIFILI, 'YYYY')) =  V_CDANO) LOOP

		BEGIN
				SELECT COUNT(CDFILIAL) INTO V_CONTADOR FROM METADIAESPECIAL
				WHERE CDFILIAL = V_CDFILIAL AND NRORG = V_NRORG AND TRUNC(DATAESP) = TRUNC(C_FERIADO.DTFERIFILI);
		EXCEPTION
		WHEN NO_DATA_FOUND THEN
			V_CONTADOR := 0;
		END;

		IF V_CONTADOR = 0 THEN

			INSERT INTO METADIAESPECIAL (CDFILIAL, DATAESP, PERCCORRECAO, DSMETAESP, NRORG)
			VALUES (V_CDFILIAL, C_FERIADO.DTFERIFILI, V_PERCACRES, C_FERIADO.DSFERIFILI, V_NRORG);

		END IF;
	/* END FOR */
	END LOOP;

	FOR k IN 1..12 LOOP
		V_CDMES 	:= k;
		V_VALORES   := tDias(0, 0, 0, 0, 0, 0, 0);
		V_VENDASEMANA := 0;
		V_TOTVENDAMES := 0;

		INSERT INTO METAMES (CDFILIAL, CDMES, CDANO, VRMES, VRSEM, NRORG)
		VALUES (V_CDFILIAL, V_CDMES, V_CDANO, 0, 0, V_NRORG);

		FOR j IN 1..7 LOOP
			V_NRDIA     := j;

			V_HORAS := tHoras(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);

			V_CONTADOR  := 0;

			V_VNDREALIZADAS := 0;
			V_DIASDASEMANA := 0;
			V_VND_PROV2 := 0;

			V_TICKETMEDIO := 0;
			V_VND_PROV := 0;
			V_EST_CMD  := 0;
			V_EST_TAA  := 0;
			V_EST_DLV  := 0;
			V_EST_BAL  := 0;
			V_EST_MES  := 0;
			V_EST_OUT  := 0;

			/* Calcula previsao de venda para o dia (Geral) */
			FOR C_VENDA IN
				(   SELECT CDFILIAL, NMFILIAL, IDORIGEMVENDA, DTENTRVENDA, NRORG,
						 NVL(SUM(TOTALVEND), 0) TOTALVEND, HORAVEND,
						 NVL(TRUNC(SUM(TICKETMEDIO) / SUM(DECODE(VRQTVENDACONC, 0, 1, VRQTVENDACONC)), 2), 0) TICKETMEDIO,
						 SUM(VRQTVENDACONC) VRQTVENDACONC, SUM(VRQTVENDACANC) VRQTVENDACANC
					FROM  (SELECT PARCIAL.CDFILIAL, PARCIAL.NMFILIAL, PARCIAL.IDORIGEMVENDA, PARCIAL.DTENTRVENDA, PARCIAL.NRORG,
								  SUM(DECODE(PARCIAL.IDSITUVENDA, 'C', 0, PARCIAL.TOTALVEND)) TOTALVEND, PARCIAL.HORAVEND,
								  TRUNC(SUM(PARCIAL.TICKETMEDIO)) AS TICKETMEDIO,
								  SUM(COUNT(DISTINCT VRQTVENDACONC)) OVER (PARTITION BY CDFILIAL, IDORIGEMVENDA) VRQTVENDACONC,
								  SUM(COUNT(DISTINCT VRQTVENDACANC)) OVER (PARTITION BY CDFILIAL, IDORIGEMVENDA) VRQTVENDACANC
							 FROM (SELECT X.CDFILIAL, X.NMFILIAL, CASE X.IDORIGEMVENDA WHEN 'BAL_AUT' THEN 'TAA' ELSE SUBSTR(X.IDORIGEMVENDA, 0, 3) END AS IDORIGEMVENDA, X.DTENTRVENDA, X.NRORG,
										  DECODE(IDSITUVENDA, 'C', 0, TRUNC(IT.QTPRODVEND*(IT.VRUNITVEND+NVL(IT.VRUNITVENDCL,0)),2) - NVL(IT.VRDESITVEND,0) + NVL(IT.VRACRITVEND,0)) AS TOTALVEND,
										  DECODE(IDSITUVENDA, 'C', 0, TRUNC(IT.QTPRODVEND*(IT.VRUNITVEND+NVL(IT.VRUNITVENDCL,0)),2) - NVL(IT.VRDESITVEND,0) + NVL(IT.VRACRITVEND,0)) AS TICKETMEDIO,
										  X.IDSITUVENDA, X.HORAVEND,
										  DECODE(IDSITUVENDA, 'O', X.CDFILIAL||X.CDCAIXA||X.NRSEQVENDA) VRQTVENDACONC,
										  DECODE(IDSITUVENDA, 'C', X.CDFILIAL||X.CDCAIXA||X.NRSEQVENDA) VRQTVENDACANC
								  FROM (SELECT DISTINCT V.CDFILIAL, V.CDCAIXA, V.NRSEQVENDA, FLC.NMFILIAL, TO_NUMBER(TO_CHAR(DTVENDA, 'HH24')) HORAVEND,
												  V.IDORIGEMVENDA, V.NRORG, V.DTENTRVENDA, V.IDSITUVENDA
											 FROM VENDA V, (SELECT DISTINCT CDFILIAL, NMFILIAL, CDLOJA, CDCAIXA
															  FROM V_FILIALLOJACAIXA WHERE CDFILIAL = V_CDFILIAL) FLC
											WHERE V.CDCAIXA   = FLC.CDCAIXA
											  AND V.CDLOJA    = FLC.CDLOJA
											  AND V.CDFILIAL  = FLC.CDFILIAL
											  AND V_NRDIA     = TO_CHAR(V.DTENTRVENDA,'D')
											  AND (V_CDMES     = TO_NUMBER(TO_CHAR(V.DTENTRVENDA, 'MM')) OR V_PERIODO = 'S')
											  AND ((V_CDANO-1) = TO_NUMBER(TO_CHAR(V.DTENTRVENDA, 'YYYY')) OR V_PERIODO = 'S')
											  AND (V.DTENTRVENDA BETWEEN TO_DATE(V_DTINI, 'DD/MM/YYYY') AND TO_DATE(V_DTFIN, 'DD/MM/YYYY') OR V_PERIODO = 'N')
											  AND V.IDSITUVENDA IN ('O', 'C')
											  ORDER BY 1, 2, 3) X
									LEFT JOIN ITEMVENDA IT
									ON X.CDFILIAL = IT.CDFILIAL
								  AND X.CDCAIXA    = IT.CDCAIXA
								  AND X.NRORG      = IT.NRORG
								  AND X.NRSEQVENDA = IT.NRSEQVENDA
                                 ORDER BY 1, 2, 3) PARCIAL
						  GROUP BY PARCIAL.CDFILIAL, PARCIAL.NMFILIAL, PARCIAL.IDORIGEMVENDA, PARCIAL.DTENTRVENDA, PARCIAL.HORAVEND, PARCIAL.NRORG
						  ORDER BY 1, 2, 3) FINAL
				  GROUP BY CDFILIAL, NMFILIAL, IDORIGEMVENDA, DTENTRVENDA, HORAVEND, NRORG
				  ORDER BY CDFILIAL, DTENTRVENDA
				) LOOP
				V_CONTADOR := V_CONTADOR + 1;
				/* Aplica um valor X a mais no valor vendido */
				V_VNDREALIZADAS := C_VENDA.TOTALVEND + ((V_PERCACRES/100)*C_VENDA.TOTALVEND);

				V_HORAS(C_VENDA.HORAVEND+1) := V_HORAS(C_VENDA.HORAVEND+1) + V_VNDREALIZADAS;

				V_TICKETMEDIO := V_TICKETMEDIO + (C_VENDA.TICKETMEDIO + ((V_PERCACRES/100)*C_VENDA.TICKETMEDIO)) ;

				IF C_VENDA.IDORIGEMVENDA = 'CMD' THEN
					V_EST_CMD  := V_EST_CMD + V_VNDREALIZADAS;
				ELSIF C_VENDA.IDORIGEMVENDA = 'TAA' THEN
					V_EST_TAA  := V_EST_TAA + V_VNDREALIZADAS;
				ELSIF C_VENDA.IDORIGEMVENDA = 'DLV' THEN
					V_EST_DLV  := V_EST_DLV + V_VNDREALIZADAS;
				ELSIF C_VENDA.IDORIGEMVENDA = 'BAL' THEN
					V_EST_BAL  := V_EST_BAL + V_VNDREALIZADAS;
				ELSIF C_VENDA.IDORIGEMVENDA = 'MES' THEN
					V_EST_MES  := V_EST_MES + V_VNDREALIZADAS;
				ELSE
					V_EST_OUT  := V_EST_OUT + V_VNDREALIZADAS;
				END IF;

			/* END FOR */
			END LOOP;

			IF V_CONTADOR > 0 THEN
				SELECT COUNT(*)
					INTO V_DIASDASEMANAANT
				FROM DATA
				WHERE TO_CHAR(DTDATA, 'D') = V_NRDIA
					AND (TO_CHAR(DTDATA, 'MM') = V_CDMES OR V_PERIODO = 'S')
					AND (TO_CHAR(DTDATA, 'YYYY') = V_CDANO-1 OR V_PERIODO = 'S')
					AND (DTDATA BETWEEN TO_DATE(V_DTINI, 'DD/MM/YYYY') AND TO_DATE(V_DTFIN, 'DD/MM/YYYY') OR V_PERIODO = 'N');

				/* Realiza a meta das vendas somadas de um determinado dia. */
				V_VNDREALIZADAS := (V_EST_CMD + V_EST_TAA + V_EST_DLV + V_EST_BAL + V_EST_MES + V_EST_OUT)/ V_DIASDASEMANAANT;

				SELECT COUNT(*)
					INTO V_DIASDASEMANA
				FROM DATA
				WHERE TO_CHAR(DTDATA, 'D') = V_NRDIA
					AND TO_CHAR(DTDATA, 'MM') = V_CDMES
					AND TO_CHAR(DTDATA, 'YYYY') = V_CDANO;
				/* Nesse momento, a variavel V_VNDREALIZADAS estAom uma mAa de venda por dia da semana. */
				IF(V_VNDREALIZADAS > 0) THEN
					IF V_PERIODO = 'N' THEN
						V_TICKETMEDIO := V_TICKETMEDIO/V_DIASDASEMANA;

						V_EST_CMD  := ((V_EST_CMD/V_DIASDASEMANA) * 100) / V_VNDREALIZADAS;
						V_EST_TAA  := ((V_EST_TAA/V_DIASDASEMANA) * 100) / V_VNDREALIZADAS;
						V_EST_DLV  := ((V_EST_DLV/V_DIASDASEMANA) * 100) / V_VNDREALIZADAS;
						V_EST_BAL  := ((V_EST_BAL/V_DIASDASEMANA) * 100) / V_VNDREALIZADAS;
						V_EST_MES  := ((V_EST_MES/V_DIASDASEMANA) * 100) / V_VNDREALIZADAS;
						V_EST_OUT  := ((V_EST_OUT/V_DIASDASEMANA) * 100) / V_VNDREALIZADAS;
					ELSE
						V_TICKETMEDIO := V_TICKETMEDIO/V_DIASDASEMANAANT;

						V_EST_CMD  := ((V_EST_CMD/V_DIASDASEMANAANT) * 100) / V_VNDREALIZADAS;
						V_EST_TAA  := ((V_EST_TAA/V_DIASDASEMANAANT) * 100) / V_VNDREALIZADAS;
						V_EST_DLV  := ((V_EST_DLV/V_DIASDASEMANAANT) * 100) / V_VNDREALIZADAS;
						V_EST_BAL  := ((V_EST_BAL/V_DIASDASEMANAANT) * 100) / V_VNDREALIZADAS;
						V_EST_MES  := ((V_EST_MES/V_DIASDASEMANAANT) * 100) / V_VNDREALIZADAS;
						V_EST_OUT  := ((V_EST_OUT/V_DIASDASEMANAANT) * 100) / V_VNDREALIZADAS;
					END IF;
				ELSE
					V_EST_CMD  := 0;
					V_EST_TAA  := 0;
					V_EST_DLV  := 0;
					V_EST_BAL  := 0;
					V_EST_MES  := 0;
					V_EST_OUT  := 0;
				END IF;
			END IF;

			/* Atribuo ao array de dias da semana o valor que devo vender em um determinado dia da semana */
			V_VALORES(V_NRDIA) := V_VNDREALIZADAS;

			V_VENDASEMANA := V_VENDASEMANA + V_VNDREALIZADAS;
			V_TOTVENDAMES := V_TOTVENDAMES + (V_VNDREALIZADAS * V_DIASDASEMANA);

			V_CONTADOR := 0;

			/* Confere se existe algum registro na METADIA e METAHORA. Se nAhouver, insere.
			   Se nAhouver nenhum registro em METADIA Antendido que em METAHORA tambAnAexiste. */
			BEGIN
				SELECT COUNT(CDFILIAL) INTO V_CONTADOR FROM METADIA WHERE NRDIA = V_NRDIA AND CDMES = V_CDMES AND CDANO = V_CDANO AND CDFILIAL = V_CDFILIAL AND NRORG = V_NRORG;
			EXCEPTION
			WHEN NO_DATA_FOUND THEN
				V_CONTADOR := 0;
			END;

			IF V_CONTADOR = 0 THEN

				INSERT INTO METADIA (CDFILIAL, NRDIA, CDMES, CDANO, VRPERCDIA, VRTICKETDIA, NRORG)
				VALUES (V_CDFILIAL, V_NRDIA, V_CDMES, V_CDANO, TRUNC(100/7,2), 0, V_NRORG);

				V_CONTHORA := 0;
				WHILE V_CONTHORA <= 23 LOOP

					INSERT INTO METAHORA (CDFILIAL, CDHORA, NRDIA, CDMES, CDANO, VRPERCHORA, NRORG)
					VALUES (V_CDFILIAL, V_CONTHORA, V_NRDIA, V_CDMES, V_CDANO, 0, V_NRORG);

					V_CONTHORA := V_CONTHORA + 1;
				END LOOP;
			END IF;

			V_CONTADOR := 0;

			/* Confere se existe algum registro na METAMODALIDADE. Se nAhouver, insere. */
			BEGIN
				SELECT COUNT(CDFILIAL) INTO V_CONTADOR FROM METAMODALIDADEDIA WHERE NRDIA = V_NRDIA AND CDMES = V_CDMES AND CDANO = V_CDANO AND CDFILIAL = V_CDFILIAL AND NRORG = V_NRORG;
			EXCEPTION
			WHEN NO_DATA_FOUND THEN
				V_CONTADOR := 0;
			END;

			IF V_CONTADOR = 0 THEN

				INSERT INTO METAMODALIDADEDIA (CDFILIAL, IDMODALIDADE, NRDIA, CDMES, CDANO, VRPERCMODALIDADE, NRORG)
				VALUES (V_CDFILIAL, 'CMD', V_NRDIA, V_CDMES, V_CDANO, 0, V_NRORG);

				INSERT INTO METAMODALIDADEDIA (CDFILIAL, IDMODALIDADE, NRDIA, CDMES, CDANO, VRPERCMODALIDADE, NRORG)
				VALUES (V_CDFILIAL, 'TAA', V_NRDIA, V_CDMES, V_CDANO, 0, V_NRORG);

				INSERT INTO METAMODALIDADEDIA (CDFILIAL, IDMODALIDADE, NRDIA, CDMES, CDANO, VRPERCMODALIDADE, NRORG)
				VALUES (V_CDFILIAL, 'DLV', V_NRDIA, V_CDMES, V_CDANO, 0, V_NRORG);

				INSERT INTO METAMODALIDADEDIA (CDFILIAL, IDMODALIDADE, NRDIA, CDMES, CDANO, VRPERCMODALIDADE, NRORG)
				VALUES (V_CDFILIAL, 'BAL', V_NRDIA, V_CDMES, V_CDANO, 0, V_NRORG);

				INSERT INTO METAMODALIDADEDIA (CDFILIAL, IDMODALIDADE, NRDIA, CDMES, CDANO, VRPERCMODALIDADE, NRORG)
				VALUES (V_CDFILIAL, 'MES', V_NRDIA, V_CDMES, V_CDANO, 0, V_NRORG);

				INSERT INTO METAMODALIDADEDIA (CDFILIAL, IDMODALIDADE, NRDIA, CDMES, CDANO, VRPERCMODALIDADE, NRORG)
				VALUES (V_CDFILIAL, 'OUT', V_NRDIA, V_CDMES, V_CDANO, 0, V_NRORG);

			END IF;

			/* Atualiza a estimativa da modalidade CMD */
			UPDATE METAMODALIDADEDIA SET VRPERCMODALIDADE = V_EST_CMD
			WHERE CDFILIAL = V_CDFILIAL AND NRDIA = V_NRDIA AND CDMES = V_CDMES AND CDANO = V_CDANO AND IDMODALIDADE = 'CMD' AND NRORG = V_NRORG;

			/* Atualiza a estimativa da modalidade TAA */
			UPDATE METAMODALIDADEDIA SET VRPERCMODALIDADE = V_EST_TAA
			WHERE CDFILIAL = V_CDFILIAL AND NRDIA = V_NRDIA AND CDMES = V_CDMES AND CDANO = V_CDANO AND IDMODALIDADE = 'TAA' AND NRORG = V_NRORG;

			/* Atualiza a estimativa da modalidade DLV */
			UPDATE METAMODALIDADEDIA SET VRPERCMODALIDADE = V_EST_DLV
			WHERE CDFILIAL = V_CDFILIAL AND NRDIA = V_NRDIA AND CDMES = V_CDMES AND CDANO = V_CDANO AND IDMODALIDADE = 'DLV' AND NRORG = V_NRORG;

			/* Atualiza a estimativa da modalidade BAL */
			UPDATE METAMODALIDADEDIA SET VRPERCMODALIDADE = V_EST_BAL
			WHERE CDFILIAL = V_CDFILIAL AND NRDIA = V_NRDIA AND CDMES = V_CDMES AND CDANO = V_CDANO AND IDMODALIDADE = 'BAL' AND NRORG = V_NRORG;

			/* Atualiza a estimativa da modalidade MES */
			UPDATE METAMODALIDADEDIA SET VRPERCMODALIDADE = V_EST_MES
			WHERE CDFILIAL = V_CDFILIAL AND NRDIA = V_NRDIA AND CDMES = V_CDMES AND CDANO = V_CDANO AND IDMODALIDADE = 'MES' AND NRORG = V_NRORG;

			/* Atualiza a estimativa da modalidade OUT */
			UPDATE METAMODALIDADEDIA SET VRPERCMODALIDADE = V_EST_OUT
			WHERE CDFILIAL = V_CDFILIAL AND NRDIA = V_NRDIA AND CDMES = V_CDMES AND CDANO = V_CDANO AND IDMODALIDADE = 'OUT' AND NRORG = V_NRORG;

			FOR h IN 1..24 LOOP
				IF (V_VNDREALIZADAS > 0) THEN
					IF V_PERIODO = 'N' THEN
						V_HORAS(h) := (V_HORAS(h)/ V_DIASDASEMANA)*100/V_VNDREALIZADAS;
					ELSE
						V_HORAS(h) := (V_HORAS(h)/ V_DIASDASEMANAANT)*100/V_VNDREALIZADAS;
					END IF;
				ELSE
					V_HORAS(h) := 0;
				END IF;
				V_VND_PROV2 := V_VND_PROV2 + TRUNC(V_HORAS(h), 2);
			END LOOP;

			IF (V_VND_PROV2 < 100) THEN
				V_HORAS(24) := V_HORAS(24) + (100-V_VND_PROV2);
			ELSIF (V_VND_PROV2 > 100) THEN

				V_VND_PROV2 := V_VND_PROV2 - 100;

				FOR h IN 1..24 LOOP
					IF (V_HORAS(h) > V_VND_PROV2) THEN
						V_HORAS(h) := V_HORAS(h) - V_VND_PROV2;
						EXIT;
					END IF;
				END LOOP;
			END IF;

			V_CONTHORA := 0;

			WHILE V_CONTHORA <= 23 LOOP

				UPDATE METAHORA SET VRPERCHORA = TRUNC(V_HORAS(V_CONTHORA+1),2)
				WHERE CDFILIAL = V_CDFILIAL AND CDHORA = V_CONTHORA AND NRDIA = V_NRDIA AND CDMES = V_CDMES AND CDANO = V_CDANO AND NRORG = V_NRORG;

				V_CONTHORA := V_CONTHORA + 1;
			END LOOP;

		/* END LOOP DE DIAS DA SEMANA */
		END LOOP;

		IF(V_VENDASEMANA > 0) THEN
			FOR i IN 1..7 LOOP
					V_VND_PROV := (V_VALORES(i)*100)/V_VENDASEMANA;
					UPDATE METADIA SET VRPERCDIA = TRUNC(V_VND_PROV,2), VRTICKETDIA = V_TICKETMEDIO
					WHERE CDFILIAL = V_CDFILIAL AND NRDIA = i AND CDMES = V_CDMES AND CDANO = V_CDANO AND NRORG = V_NRORG;
			END LOOP;
		END IF;

		UPDATE METAMES SET VRMES = TRUNC(V_TOTVENDAMES,2), VRSEM = TRUNC(V_VENDASEMANA,2)
		WHERE CDFILIAL = V_CDFILIAL AND CDMES = V_CDMES AND CDANO = V_CDANO AND NRORG = V_NRORG;

	/* END LOOP MES */
	END LOOP;
	COMMIT;
	CALCULA_METAS_RM(V_CDFILIAL, V_NRORG, V_CDANO);
END;