DROP FUNCTION CALCULO_EQUIP
/

DROP TYPE CALCULO_EQUIP_TABLE 
/ 

DROP TYPE CALCULO_EQUIP_TYPE
/

CREATE TYPE CALCULO_EQUIP_TYPE AS OBJECT 
(
CDPRATO VARCHAR2(10), 
CDFILAUXPRAT VARCHAR2(04), 
NREQUIPAMENTO NUMBER, 
DESCRICAO VARCHAR2(50), 
QTDISPTOTAL NUMBER, 
PESO FLOAT(126), 
QTEQUIP NUMBER, 
QTPRODUTO FLOAT, 
TEMPOPREP FLOAT(126), 
HORAINI FLOAT, 
HORAFIN FLOAT,
TEMPTOTALEQUIP FLOAT,
AGRUPAMENTO NUMBER
)
/
CREATE TYPE CALCULO_EQUIP_TABLE AS TABLE OF CALCULO_EQUIP_TYPE
/

create or replace FUNCTION CALCULO_EQUIP
  (
   P_CDFILIAL IN EQUIPAMCOZ.CDCENTRAL%TYPE,
   P_CDPRATO IN PRATO.CDPRATO%TYPE,
   P_CDFILAUXPRAT IN PRATO.CDFILAUXPRAT%TYPE,
   P_QTDPROD IN NUMBER,
   P_HORA IN VARCHAR2,
   P_TIPOHORA IN VARCHAR2 default ('INI'), --Hora final ou inicial ('INI', 'FIN')
   P_NRORG VARCHAR2 DEFAULT 1
   )
   RETURN CALCULO_EQUIP_TABLE PIPELINED IS

   OUT_RECORD CALCULO_EQUIP_TYPE := CALCULO_EQUIP_TYPE
   (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);

V_QTAGRUP NUMBER;
V_MAXQTD NUMBER;
V_QTDTOTALPROD FLOAT;
V_QTDAPRODUZIR FLOAT;
V_QTEQUIP NUMBER;
V_HRINIPRODANT FLOAT;
V_HRINIPROD FLOAT;
V_HRFINPROD FLOAT;

BEGIN
    FOR C_DADOS IN (
        SELECT EQPRAT.CDPRATO, EQPRAT.CDFILAUXPRAT, 
                EQUIP.NREQUIPAMCOZ AS NREQUIPAMENTO, EQUIP.DSEQUIPAMCOZ AS DESCRICAO, 
                EQUIP.QTDISPTOTAL, EQUIP.PESO, EQUIP.SGUNIDADE,
                TEMP.TEMPTOTALEQUIP, EQPRAT.TEMPOPREP
            FROM EQUIPAMCOZ EQUIP
            INNER JOIN EQUIPRATOCOZ EQPRAT ON EQPRAT.NREQUIPAMENTO = EQUIP.NREQUIPAMCOZ
                                            AND EQPRAT.CDPRATO = P_CDPRATO
                                            AND EQPRAT.CDFILAUXPRAT = P_CDFILAUXPRAT
            LEFT JOIN (
                SELECT CDPRATO, CDFILAUXPRAT, SUM(TEMPOPREP) TEMPTOTALEQUIP
                FROM EQUIPRATOCOZ
                WHERE CDPRATO = P_CDPRATO
                      AND CDFILAUXPRAT = P_CDFILAUXPRAT
                GROUP BY CDPRATO, CDFILAUXPRAT
            ) TEMP ON TEMP.CDPRATO = EQPRAT.CDPRATO AND TEMP.CDFILAUXPRAT = EQPRAT.CDFILAUXPRAT
            WHERE EQUIP.CDCENTRAL = P_CDFILIAL
                AND EQUIP.NRORG = P_NRORG
        ORDER BY (PESO * QTDISPTOTAL)
    )LOOP

        V_QTDTOTALPROD := P_QTDPROD;

        IF(V_MAXQTD IS NULL) THEN 
            V_MAXQTD := C_DADOS.PESO * C_DADOS.QTDISPTOTAL;
        END IF;

        V_QTAGRUP := CEIL(P_QTDPROD/V_MAXQTD);

        IF(V_HRINIPRODANT IS NULL) THEN
            IF P_TIPOHORA = 'FIN' THEN V_HRINIPROD := P_HORA - C_DADOS.TEMPOPREP;
            ELSE V_HRINIPROD := P_HORA;
            END IF;
        ELSE
            IF P_TIPOHORA = 'FIN' THEN V_HRINIPROD := V_HRINIPRODANT - C_DADOS.TEMPOPREP;
            ELSE V_HRINIPROD := V_HRINIPRODANT --+ C_DADOS.TEMPOPREP
            ;
            END IF;
        END IF;

        FOR AGRUP IN 1..V_QTAGRUP LOOP

            IF(V_QTDTOTALPROD > V_MAXQTD) THEN
                V_QTDAPRODUZIR := V_MAXQTD;
            ELSE 
                V_QTDAPRODUZIR := V_QTDTOTALPROD;
            END IF;

            V_QTEQUIP := CEIL(V_QTDAPRODUZIR / C_DADOS.PESO);

            --Valida horas anteriores ou superiores a meia noite 
            IF(V_HRINIPROD <= 0) THEN
                V_HRINIPROD := MOD(24 + V_HRINIPROD, 24);
            END IF;

            V_HRFINPROD := V_HRINIPROD + C_DADOS.TEMPOPREP;

            IF(V_HRFINPROD >= 24) THEN
                V_HRFINPROD := MOD(V_HRFINPROD, 24);
            END IF; 

            OUT_RECORD.CDPRATO := C_DADOS.CDPRATO;
            OUT_RECORD.CDFILAUXPRAT := C_DADOS.CDFILAUXPRAT;
            OUT_RECORD.NREQUIPAMENTO := C_DADOS.NREQUIPAMENTO;
            OUT_RECORD.DESCRICAO := C_DADOS.DESCRICAO;
            OUT_RECORD.QTDISPTOTAL := C_DADOS.QTDISPTOTAL;
            OUT_RECORD.PESO := C_DADOS.PESO;

            OUT_RECORD.QTEQUIP := V_QTEQUIP;
            OUT_RECORD.QTPRODUTO := V_QTDAPRODUZIR;
            OUT_RECORD.TEMPOPREP := C_DADOS.TEMPOPREP;
            OUT_RECORD.HORAINI := V_HRINIPROD;
            OUT_RECORD.HORAFIN := V_HRFINPROD;
            OUT_RECORD.TEMPTOTALEQUIP := C_DADOS.TEMPTOTALEQUIP;

            OUT_RECORD.AGRUPAMENTO := AGRUP;
            PIPE ROW (OUT_RECORD);

            V_QTDTOTALPROD := V_QTDTOTALPROD - V_MAXQTD;
            IF P_TIPOHORA = 'FIN' THEN V_HRINIPROD := V_HRINIPROD - C_DADOS.TEMPTOTALEQUIP;
            ELSE V_HRINIPROD := V_HRINIPROD + C_DADOS.TEMPTOTALEQUIP;
            END IF;
        END LOOP;

        IF(V_HRINIPRODANT IS NULL) THEN
            IF P_TIPOHORA = 'FIN' THEN V_HRINIPRODANT := P_HORA - C_DADOS.TEMPOPREP;
            ELSE V_HRINIPRODANT := P_HORA + C_DADOS.TEMPOPREP;
            END IF;
        ELSE 
            IF P_TIPOHORA = 'FIN' THEN V_HRINIPRODANT := V_HRINIPRODANT - C_DADOS.TEMPOPREP;
            ELSE V_HRINIPRODANT := V_HRINIPRODANT + C_DADOS.TEMPOPREP;
            END IF;
        END IF;


    END LOOP;

   RETURN;
END;
/