/* Sistemas Integrados TEKNISA
   Compras e Suprimentos

Nome: 8220_SUPTRGO.sql

Descrição:
Calcula o preço econômico para um determinado produto da coleta,
verificando se determinados campos foram alterados antes de efetivar a
alteração do regitro.

Criação:
25/08/1999 Yoris L. de Souza
*/

CREATE OR REPLACE TRIGGER CALC_PRECO_ECON
BEFORE INSERT OR UPDATE OF VRPRECUNIITM, VRPERDESITM, IDTPFOPGTCOL,
                           CDFORMPGTO, NRDIAPGFXCOL, IDUTDIAPGCOL, NRPARCPGTCOL
ON ITEMCOLE FOR EACH ROW
DECLARE
   V_DTCOLEPREC    COLETAPR.DTCOLEPREC%TYPE;
   V_DTPARCELA    DATE;
   V_NRDIAS       NUMBER;
   V_NRFATOR      NUMBER;
   V_VRINDICE     NUMBER;
   V_DTULDIAMES   DATE;
   V_DTULTAUX     DATE;
   V_FATORPARC    NUMBER;
   V_VRPRECECO    NUMBER;
   V_VRPZOPGT     NUMBER;
   V_CONTA        NUMBER;
   V_DTPRIPARC    DATE;
   V_TOTREST      NUMBER;

   V_VRPERDESITM  ITEMCOLE.VRPERDESITM%TYPE;
   V_VRIMPITM     IMPCOLET.VRADIMPCOL%TYPE;
   V_AUXVRIMPITM  IMPCOLET.VRADIMPCOL%TYPE;
   V_VRRENDATUMAR MARCPROD.VRRENDATUMAR%TYPE;
   V_CDEMPRESA    PARCMPSUP.CDEMPRESA%TYPE;
   V_INSCESTA     FILIAL.CDINSCESTA%TYPE;
   V_IDUTDESCBON  PARASUPRI.IDUTDESCBON%TYPE;
   V_IDTPDESCFORN FORNECEDOR.IDTPDESCFORN%TYPE;
   V_VRPEDESCFORN FORNECEDOR.VRPEDESCFORN%TYPE;

   V_TESTENR      NUMBER;
   V_VRPERPIFORN  NUMBER;
   V_VRPRECECOPI  NUMBER;

   V_TIPOOPER     VARCHAR2(02);

   V_IDDTREPRECON PARASUPRI.IDDTREPRECON%TYPE;

-- Cursor com as datas e percentuais de pagamento para forma de pgto variavel
 CURSOR C_PARCELAS IS
  SELECT
   V_DTPRIPARC +
   PZOPGTITMCOL.NRDIASPGTCOL AS DTPARCELA,
   PZOPGTITMCOL.VRPERCPGTCOL AS VRPZOPGT
  FROM
   PZOPGTITMCOL
  WHERE
   PZOPGTITMCOL.CDFILIAL    = :NEW.CDFILIAL AND
   PZOPGTITMCOL.NRCOLEPRECO = :NEW.NRCOLEPRECO AND
   PZOPGTITMCOL.CDFORNECED  = :NEW.CDFORNECED AND
   PZOPGTITMCOL.CDREGIAO    = :NEW.CDREGIAO AND
   PZOPGTITMCOL.CDPRODUTO   = :NEW.CDPRODUTO AND
   PZOPGTITMCOL.CDMARCA     = :NEW.CDMARCA;
BEGIN

  SELECT
     NVL(MAX(PARCMPSUP.CDTIPOOPER), '01') INTO V_TIPOOPER
  FROM
     PARCMPSUP,
     FILIAL
  WHERE
     (FILIAL.CDFILIAL    = :NEW.CDFILIAL) AND
     (PARCMPSUP.CDFILIAL = NVL(FILIAL.CDFILCENTCMP, FILIAL.CDFILIAL));

  SELECT
    NVL(IDDTREPRECON, '1') INTO V_IDDTREPRECON
  FROM
    PARASUPRI
  WHERE
    CDFILIAL = :NEW.CDFILIAL;

  IF V_IDDTREPRECON = '1' THEN
    SELECT MAX(DTCOLEPREC) INTO V_DTCOLEPREC -- Busca a data da Coleta
    FROM COLETAPR
    WHERE
      CDFILIAL    =  :NEW.CDFILIAL   AND
      NRCOLEPRECO =  :NEW.NRCOLEPRECO;
  ELSE
    V_DTCOLEPREC := :NEW.DTINIVALITM;
  END IF;

-- Busca o valor de redimento para o produto e marca da coleta
   SELECT
     MAX(QFOMARPROD.VRRENDATU) INTO V_VRRENDATUMAR
   FROM QFOMARPROD
   WHERE
     QFOMARPROD.CDPRODUTO     = :NEW.CDPRODUTO  AND
     QFOMARPROD.CDMARCA    = :NEW.CDMARCA;
-- Busca o total do imposto calculado para o item da coleta
   SELECT
     SUM(VRADIMPCOL) INTO V_VRIMPITM
   FROM
     IMPCOLET
   WHERE
     CDFILIAL    = :NEW.CDFILIAL    AND
     NRCOLEPRECO = :NEW.NRCOLEPRECO AND
     CDFORNECED  = :NEW.CDFORNECED  AND
     CDREGIAO    = :NEW.CDREGIAO    AND
     CDPRODUTO   = :NEW.CDPRODUTO   AND
     CDMARCA     = :NEW.CDMARCA;
  IF V_VRIMPITM IS NULL THEN
     V_VRIMPITM := 0;
  END IF;

  /* Cálculo para os impostos com as seguintes condições(ICMS por exemplo):
     Destacar Valor, Imposto Recuperável e com Crédito de Imposto */
  /* INICIO */
  V_CDEMPRESA := NULL;

  SELECT
     SUBSTR(EMITENTE(:NEW.CDFILIAL, :NEW.CDPRODUTO, :NEW.CDFORNECED), 3, 2) AS CDEMPRESA
  INTO
     V_CDEMPRESA
  FROM
     PARAMGERAL;

  SELECT
    MAX(FILIAL.CDINSCESTA) INTO V_INSCESTA
  FROM
    FILIAL
  WHERE
    FILIAL.CDFILIAL  = :NEW.CDFILIAL AND
    FILIAL.CDEMPRESA = V_CDEMPRESA;

  SELECT SUM(VRIMPCOLETA) INTO V_AUXVRIMPITM
    FROM IMPCOLET, IMPOSTO
   WHERE IMPCOLET.CDFILIAL    = :NEW.CDFILIAL           AND
         IMPCOLET.NRCOLEPRECO = :NEW.NRCOLEPRECO        AND
         IMPCOLET.CDFORNECED  = :NEW.CDFORNECED         AND
         IMPCOLET.CDREGIAO    = :NEW.CDREGIAO           AND
         IMPCOLET.CDPRODUTO   = :NEW.CDPRODUTO          AND
         IMPCOLET.CDMARCA     = :NEW.CDMARCA            AND
         IMPCOLET.CDIMPOSTO   = IMPOSTO.CDIMPOSTO       AND
         IMPOSTO.IDTRATIMPO   = 'V'                     AND
         IMPOSTO.IDIMPORECUP  = 'S'                     AND
         IMPCOLET.CDFISCITMCOL = '1';

  IF V_AUXVRIMPITM IS NULL THEN
     V_AUXVRIMPITM := 0;
  END IF;

  V_VRIMPITM := V_VRIMPITM - V_AUXVRIMPITM;
  /* FIM */

  IF (:NEW.VRPERDESITM IS NULL ) THEN
     V_VRPERDESITM := 0;
  ELSE
     V_VRPERDESITM := :NEW.VRPERDESITM;
  END IF;


  SELECT
     NVL(MAX(IDUTDESCBON), 'N') INTO V_IDUTDESCBON
  FROM
     PARASUPRI
  WHERE
     CDFILIAL = :NEW.CDFILIAL;

  IF V_IDUTDESCBON = 'S' THEN
     SELECT
        NVL(MAX(IDTPDESCFORN), 'C'),
        MAX(VRPEDESCFORN)
     INTO
        V_IDTPDESCFORN,
        V_VRPEDESCFORN
     FROM
        FORNECEDOR
     WHERE
        CDFORNECED = :NEW.CDFORNECED;
     IF V_IDTPDESCFORN = 'B' THEN
        IF (V_VRPEDESCFORN IS NOT NULL) AND (V_VRPEDESCFORN <> 0) THEN
           V_VRPERDESITM := V_VRPEDESCFORN;
        END IF;
     END IF;
  END IF;

  IF (V_VRRENDATUMAR IS NULL) OR (V_VRRENDATUMAR = 0) THEN
     V_VRRENDATUMAR := 1;
  END IF;
  V_VRPRECECO := 0;
  V_VRPRECECOPI := 0;

--*** Se forma de pagamento for Variavel
  IF :NEW.IDTPFOPGTCOL = 'V' THEN
    -- Busca a data da primeira parcela se basendo na media de dias entre uma
    -- parcela e outra.
    SELECT
     MIN(ROUND((TO_NUMBER(NVL(DIAPGTO.NRDIAFINPGTO,1)) - 1)/2) +
     V_DTCOLEPREC) INTO V_DTPRIPARC
    FROM
     DIAPGTO
    WHERE
     DIAPGTO.CDFORMPGTO               = :NEW.CDFORMPGTO AND
     TO_NUMBER(DIAPGTO.NRDIAINIPGTO ) = 1;

    IF V_DTPRIPARC IS NULL THEN
       V_DTPRIPARC := V_DTCOLEPREC;
    END IF;

    V_TOTREST := 0;

    OPEN C_PARCELAS;
    LOOP
       FETCH C_PARCELAS INTO V_DTPARCELA, V_VRPZOPGT;
       EXIT WHEN C_PARCELAS%NOTFOUND;

       V_NRFATOR := 1;
       V_DTULDIAMES := LAST_DAY(V_DTCOLEPREC);
       V_NRDIAS := LAST_DAY(V_DTCOLEPREC)-V_DTCOLEPREC;
       V_DTULTAUX := V_DTCOLEPREC;

       IF V_DTULDIAMES = V_DTCOLEPREC THEN
          WHILE V_DTPARCELA > V_DTULDIAMES LOOP
            -- Busca o indice a ser aplicado para correcao
             SELECT MAX(MOVINDICE.VRINDICE) INTO V_VRINDICE
             FROM
              PARASUPRI, MOVINDICE
             WHERE
              PARASUPRI.CDFILIAL   = :NEW.CDFILIAL         AND
              TO_CHAR(MOVINDICE.DTREFIND,'MMYYYY') =
              TO_CHAR(V_DTULDIAMES,'MMYYYY')               AND
              PARASUPRI.CDTPINDICE = MOVINDICE.CDTPINDICE AND
              PARASUPRI.IDPERVALOR = MOVINDICE.IDPERVALOR AND
              PARASUPRI.CDINDICE   = MOVINDICE.CDINDICE;
             IF V_VRINDICE IS NULL THEN
                V_VRINDICE := 0;
             END IF;
             V_NRFATOR := V_NRFATOR * (1 + (V_VRINDICE/100))**(V_NRDIAS/30);
             V_DTULTAUX := V_DTULDIAMES;
             V_DTULDIAMES := LAST_DAY(V_DTULDIAMES+1);
             V_NRDIAS   := V_DTULDIAMES - V_DTULTAUX;
          END LOOP;
       ELSE
          WHILE V_DTPARCELA > V_DTULDIAMES LOOP
           -- Busca o indice a ser aplicado para correcao
            SELECT MAX(MOVINDICE.VRINDICE) INTO V_VRINDICE
            FROM
             PARASUPRI, MOVINDICE
            WHERE
             PARASUPRI.CDFILIAL   = :NEW.CDFILIAL         AND
             TO_CHAR(MOVINDICE.DTREFIND,'MMYYYY') =
             TO_CHAR(V_DTULDIAMES,'MMYYYY')               AND
             PARASUPRI.CDTPINDICE = MOVINDICE.CDTPINDICE AND
             PARASUPRI.IDPERVALOR = MOVINDICE.IDPERVALOR AND
             PARASUPRI.CDINDICE   = MOVINDICE.CDINDICE;
            IF V_VRINDICE IS NULL THEN
               V_VRINDICE := 0;
            END IF;
            V_NRFATOR := V_NRFATOR * (1 + (V_VRINDICE/100))**(V_NRDIAS/30);
            V_DTULTAUX := V_DTULDIAMES;
            V_DTULDIAMES := LAST_DAY(V_DTULDIAMES+1);
            V_NRDIAS := V_DTULDIAMES - V_DTULTAUX;
          END LOOP;
       END IF;

       V_NRDIAS := V_DTPARCELA - V_DTULTAUX;
    -- Busca o indice a ser aplicado para correcao
       SELECT MAX(MOVINDICE.VRINDICE) INTO V_VRINDICE
       FROM
        PARASUPRI, MOVINDICE
       WHERE
        PARASUPRI.CDFILIAL   = :NEW.CDFILIAL         AND
        TO_CHAR(MOVINDICE.DTREFIND,'MMYYYY') =
        TO_CHAR(V_DTPARCELA,'MMYYYY')               AND
        PARASUPRI.CDTPINDICE = MOVINDICE.CDTPINDICE AND
        PARASUPRI.IDPERVALOR = MOVINDICE.IDPERVALOR AND
        PARASUPRI.CDINDICE   = MOVINDICE.CDINDICE;
       IF V_VRINDICE IS NULL THEN
          V_VRINDICE := 0;
       END IF;
       V_NRFATOR := V_NRFATOR * (1 + (V_VRINDICE/100))**(V_NRDIAS/30);
       V_TOTREST := V_TOTREST + ((1 / V_NRFATOR) * (V_VRPZOPGT/100));
    END LOOP;
    CLOSE C_PARCELAS;
    IF V_TOTREST = 0 THEN
       V_TOTREST := 1;
    END IF;
    V_VRPRECECO := ROUND((:NEW.VRPRECUNIITM - (:NEW.VRPRECUNIITM * (V_VRPERDESITM /100)) + V_VRIMPITM) *
                   (1/V_VRRENDATUMAR) * V_TOTREST,5);          

    V_VRPRECECOPI := ROUND((:NEW.VRPRECUNIITM - (:NEW.VRPRECUNIITM * (V_VRPERDESITM /100)) + V_VRIMPITM) * V_TOTREST,5);

--*** Se forma de pagamento for Fixa
  ELSIF :NEW.IDTPFOPGTCOL = 'F' THEN

    V_TESTENR := :NEW.NRDIAPGFXCOL;
    IF :NEW.NRDIAPGFXCOL > TO_NUMBER(TO_CHAR(LAST_DAY(V_DTCOLEPREC), 'DD')) THEN
      V_TESTENR := TO_NUMBER(TO_CHAR(LAST_DAY(V_DTCOLEPREC), 'DD'));
    END IF;

 -- Apura a data inicial de pagamento baseado na condicao informada
      IF TO_DATE(LPAD(TO_CHAR(V_TESTENR),2,'0') ||
         TO_CHAR(V_DTCOLEPREC,'MMYYYY'),'DDMMYYYY') >
         V_DTCOLEPREC AND :NEW.IDUTDIAPGCOL = 'I' THEN

         V_DTPARCELA := TO_DATE(LPAD(TO_CHAR(V_TESTENR),2,'0') ||
                        TO_CHAR(V_DTCOLEPREC,'MMYYYY'),'DDMMYYYY');
      END IF;
      IF (TO_DATE(LPAD(TO_CHAR(V_TESTENR),2,'0') ||
          TO_CHAR(V_DTCOLEPREC,'MMYYYY'),'DDMMYYYY') <=
          V_DTCOLEPREC AND :NEW.IDUTDIAPGCOL = 'I') OR
         (:NEW.IDUTDIAPGCOL = 'E') THEN

         V_DTPARCELA := :NEW.NRDIAPGFXCOL + LAST_DAY(V_DTCOLEPREC);

      END IF;

      V_FATORPARC := 0;
      V_CONTA := 1;
      V_NRFATOR := 1;
      V_DTULTAUX := V_DTCOLEPREC;

 -- Calcula fator de correcao de acordo com o numero de parcelas informadas.
      FOR V_CONTA IN 1..:NEW.NRPARCPGTCOL LOOP
         V_DTULDIAMES := LAST_DAY(V_DTCOLEPREC);
         V_NRDIAS := LAST_DAY(V_DTCOLEPREC)-V_DTCOLEPREC;
         V_DTULTAUX := V_DTCOLEPREC;

         IF V_DTCOLEPREC = V_DTULDIAMES THEN
            WHILE V_DTPARCELA > V_DTULDIAMES LOOP
           -- Busca o indice a ser aplicado para correcao
              SELECT MAX(MOVINDICE.VRINDICE) INTO V_VRINDICE
              FROM
               PARASUPRI, MOVINDICE
              WHERE
               PARASUPRI.CDFILIAL   = :NEW.CDFILIAL         AND
               TO_CHAR(MOVINDICE.DTREFIND,'MMYYYY') =
               TO_CHAR(V_DTULDIAMES,'MMYYYY')               AND
               PARASUPRI.CDTPINDICE = MOVINDICE.CDTPINDICE AND
               PARASUPRI.IDPERVALOR = MOVINDICE.IDPERVALOR AND
               PARASUPRI.CDINDICE   = MOVINDICE.CDINDICE;

              IF V_VRINDICE IS NULL THEN
                 V_VRINDICE := 0;
              END IF;
              V_NRFATOR := V_NRFATOR * (1 + (V_VRINDICE/100))**(V_NRDIAS/30);
              V_DTULTAUX := V_DTULDIAMES;
              V_DTULDIAMES := LAST_DAY(V_DTULDIAMES+1);
              V_NRDIAS := V_DTULDIAMES - V_DTULTAUX;
            END LOOP;
         ELSE
            WHILE V_DTPARCELA > V_DTULDIAMES LOOP
           -- Busca o indice a ser aplicado para correcao
              SELECT MAX(MOVINDICE.VRINDICE) INTO V_VRINDICE
              FROM
               PARASUPRI, MOVINDICE
              WHERE
               PARASUPRI.CDFILIAL   = :NEW.CDFILIAL         AND
               TO_CHAR(MOVINDICE.DTREFIND,'MMYYYY') =
               TO_CHAR(V_DTULDIAMES,'MMYYYY')               AND
               PARASUPRI.CDTPINDICE = MOVINDICE.CDTPINDICE AND
               PARASUPRI.IDPERVALOR = MOVINDICE.IDPERVALOR AND
               PARASUPRI.CDINDICE   = MOVINDICE.CDINDICE;

              IF V_VRINDICE IS NULL THEN
                 V_VRINDICE := 0;
              END IF;
              V_NRFATOR := V_NRFATOR * (1 + (V_VRINDICE/100))**(V_NRDIAS/30);
              V_DTULTAUX := V_DTULDIAMES;
              V_DTULDIAMES := LAST_DAY(V_DTULDIAMES+1);
              V_NRDIAS   := V_DTULDIAMES - V_DTULTAUX;
             END LOOP;
         END IF;
         V_NRDIAS := V_DTPARCELA - V_DTULTAUX;
     -- Busca o indice a ser aplicado para correcao
         SELECT MAX(MOVINDICE.VRINDICE) INTO V_VRINDICE
         FROM
          PARASUPRI, MOVINDICE
         WHERE
          PARASUPRI.CDFILIAL   = :NEW.CDFILIAL        AND
          TO_CHAR(MOVINDICE.DTREFIND,'MMYYYY') =
          TO_CHAR(V_DTPARCELA,'MMYYYY')               AND
          PARASUPRI.CDTPINDICE = MOVINDICE.CDTPINDICE AND
          PARASUPRI.IDPERVALOR = MOVINDICE.IDPERVALOR AND
          PARASUPRI.CDINDICE   = MOVINDICE.CDINDICE;
         IF V_VRINDICE IS NULL THEN
            V_VRINDICE := 0;
         END IF;
         V_NRFATOR := V_NRFATOR * (1 + (V_VRINDICE/100))**(V_NRDIAS/30);
         V_FATORPARC := V_FATORPARC + (1/V_NRFATOR);
         V_DTPARCELA := ADD_MONTHS(V_DTPARCELA,1);
      END LOOP;
      V_VRPRECECO := ROUND(((:NEW.VRPRECUNIITM -
                     (:NEW.VRPRECUNIITM * (V_VRPERDESITM /100)) +
                      V_VRIMPITM) / :NEW.NRPARCPGTCOL) *
                      (1/V_VRRENDATUMAR) *
                      V_FATORPARC,5);

      V_VRPRECECOPI := ROUND(((:NEW.VRPRECUNIITM -
                       (:NEW.VRPRECUNIITM * (V_VRPERDESITM /100)) +
                        V_VRIMPITM) / :NEW.NRPARCPGTCOL) *
                        V_FATORPARC,5);

  ELSIF :NEW.IDTPFOPGTCOL IS NULL THEN
 -- Se nao foi informado forma de pagamento
      V_VRPRECECO := ROUND((:NEW.VRPRECUNIITM -
                     (:NEW.VRPRECUNIITM * (V_VRPERDESITM /100)) +
                      V_VRIMPITM) *
                      (1/V_VRRENDATUMAR),5);

      V_VRPRECECOPI := ROUND((:NEW.VRPRECUNIITM -
                       (:NEW.VRPRECUNIITM * (V_VRPERDESITM /100)) +
                        V_VRIMPITM), 5);
  END IF;
  :NEW.VRPRECECOITM := V_VRPRECECO;
  SELECT NVL(MAX(VRPERPIPRFO), 0) INTO V_VRPERPIFORN /* PROCURA O PI NA PRODFORNCOMP*/
  FROM PRODFORNCOMP
  WHERE CDFORNECED = :NEW.CDFORNECED AND
        CDPRODCOMPL = :NEW.CDPRODUTO;
  IF V_VRPERPIFORN = 0 THEN
     SELECT NVL(MAX(VRPERPIFORN), 0) INTO V_VRPERPIFORN /* SE NAO ACHAR NA PRODFORNCOMP ENTAO*/
     FROM FORNECEDOR                                    /*PROCURA NO FORNECEDOR*/
     WHERE CDFORNECED = :NEW.CDFORNECED;
  END IF;
  V_VRPRECECOPI := (V_VRPRECECOPI - (:NEW.VRPRECUNIITM*V_VRPERPIFORN)/100) * (1/V_VRRENDATUMAR); /*CALCULO DO PI(PURCHASE INCOME)*/

  :NEW.VRPRECOITMPI := V_VRPRECECOPI;
  IF UPDATING THEN
     UPDATE PREVLISTA
      SET IDATUCUSLIST = 'S'
      WHERE
          CDFILIAL = :NEW.CDFILIAL AND
          NRSEQPRELIST = :NEW.NRSEQPRELIST;
  END IF;
  IF NVL(:NEW.VRPRECOITMPI, 0) = 0 THEN
     :NEW.VRPRECOITMPI := :NEW.VRPRECUNIITM;
  END IF;
  IF NVL(:NEW.VRPRECECOITM, 0) = 0 THEN
     :NEW.VRPRECECOITM := :NEW.VRPRECUNIITM;
  END IF;
END;
/

-- VERSAO --
BEGIN ATUVEROBJ('CALC_PRECO_ECON','5.80.XXX'); END;
/