#ifdef BGT
/*
 * $Revision$
 * $Id$
 */
CREATE OR REPLACE PACKAGE bgt
AS
   FUNCTION getMutatieOpBudget( p_budget_key IN NUMBER
                              , p_mutatie_key IN NUMBER
                              , p_btw IN NUMBER
                              ) RETURN NUMBER;
   FUNCTION getBudgetMutaties ( p_budget_key IN NUMBER
                              , p_btw IN NUMBER
                              , p_datum_van DATE DEFAULT NULL
                              , p_datum_tot DATE DEFAULT NULL
                              ) RETURN NUMBER;
   FUNCTION getBudgetOpDatum ( p_budget_key IN NUMBER
                             , p_btw IN NUMBER
                             , p_datum DATE DEFAULT NULL
                             ) RETURN NUMBER;
   FUNCTION getBudgetSoortMutatie  ( p_kostenrubriek_key IN NUMBER
                                   , p_kostensoortgrp_key IN NUMBER
                                   , p_kostensoort_key IN NUMBER
                                   , p_btw IN NUMBER
                                   , p_soortmutatie IN VARCHAR2
                                   , p_datum IN DATE DEFAULT NULL
                                   ) RETURN NUMBER;
   FUNCTION getSoortMutatie ( p_mutatie_key IN NUMBER
                            ) RETURN VARCHAR2;
   FUNCTION getContractwaarde( p_srtkey IN VARCHAR2
                             , p_key IN NUMBER
                             , p_btw IN NUMBER
                             , p_status NUMBER DEFAULT 3
                             , p_datum_van DATE DEFAULT NULL
                             , p_datum_tot DATE DEFAULT NULL
                             ) RETURN NUMBER;
   FUNCTION getRaming ( p_mld_opdr_key IN NUMBER
                      , p_btw IN NUMBER
                      , p_datum_van DATE DEFAULT NULL
                      , p_datum_tot DATE DEFAULT NULL
                      ) RETURN NUMBER;
   FUNCTION getGecontracteerd ( p_mld_opdr_key IN NUMBER
                              , p_btw IN NUMBER
                              , p_datum_van DATE DEFAULT NULL
                              , p_datum_tot DATE DEFAULT NULL
                              ) RETURN NUMBER;
   FUNCTION getGefactureerdSoort( p_kostensoort_key IN NUMBER
                                , p_btw IN NUMBER
                                ) RETURN NUMBER;
   FUNCTION getGefactureerd ( p_mld_opdr_key IN NUMBER
                            , p_btw IN NUMBER
                            , p_datum_van DATE DEFAULT NULL
                            , p_datum_tot DATE DEFAULT NULL
                            ) RETURN NUMBER;
   FUNCTION getTefactureren ( p_mld_opdr_key IN NUMBER
                            , p_btw IN NUMBER
                            , p_datum_van DATE DEFAULT NULL
                            , p_datum_tot DATE DEFAULT NULL
                            ) RETURN NUMBER;
END bgt;
/

CREATE OR REPLACE PACKAGE BODY bgt
AS
   FUNCTION getMutatieOpBudget( p_budget_key IN NUMBER
                              , p_mutatie_key IN NUMBER
                              , p_btw IN NUMBER
                              ) RETURN NUMBER
   IS
      v_bedrag_mut  NUMBER;
   BEGIN
      -- p_btw: 0=excl.btw, 1=btw, 2=incl.btw.
      BEGIN
         SELECT SUM(bedrag_mutatie)
           INTO v_bedrag_mut
           FROM (SELECT bgt_budgetmutatie_key
                      , bgt_budget_key_van     budget_key
                      , CASE WHEN p_btw=0 THEN COALESCE(bgt_budget_bedrag_van, 0)
                             WHEN p_btw=1 THEN COALESCE(bgt_budget_btwbedrag_van, 0)
                             WHEN p_btw=2 THEN COALESCE(bgt_budget_bedrag_van, 0) + COALESCE(bgt_budget_btwbedrag_van, 0)
                        END  bedrag_mutatie
                   FROM bgt_budgetmutatie
                  UNION
                 SELECT bgt_budgetmutatie_key
                      , bgt_budget_key_naar     budget_key
                      , CASE WHEN p_btw=0 THEN COALESCE(bgt_budget_bedrag_naar, 0)
                             WHEN p_btw=1 THEN COALESCE(bgt_budget_btwbedrag_naar, 0)
                             WHEN p_btw=2 THEN COALESCE(bgt_budget_bedrag_naar, 0) + COALESCE(bgt_budget_btwbedrag_naar, 0)
                        END  bedrag_mutatie
                   FROM bgt_budgetmutatie
                ) mut
          WHERE mut.budget_key = p_budget_key
            AND mut.bgt_budgetmutatie_key = DECODE(p_mutatie_key , NULL, mut.bgt_budgetmutatie_key, p_mutatie_key);
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            v_bedrag_mut := NULL;
      END;
      RETURN v_bedrag_mut;
   END getMutatieOpBudget;

   FUNCTION getBudgetMutaties ( p_budget_key IN NUMBER
                              , p_btw IN NUMBER
                              , p_datum_van DATE DEFAULT NULL
                              , p_datum_tot DATE DEFAULT NULL  -- eigenlijk: tot-en-met
                              ) RETURN NUMBER
   IS
      v_bedrag_mut  NUMBER;
   BEGIN
      -- p_btw: 0=excl.btw, 1=btw, 2=incl.btw.
      -- NB: dit zijn zowel onderlinge mutaties als van-naar reserve mutaties!!
      BEGIN
         SELECT COALESCE(SUM(mut.bedrag_mutaties), 0)
           INTO v_bedrag_mut
           FROM (SELECT CASE WHEN p_btw=0 THEN SUM(bgt_budget_bedrag_van)
                             WHEN p_btw=1 THEN SUM(bgt_budget_btwbedrag_van)
                             WHEN p_btw=2 THEN SUM(bgt_budget_bedrag_van) + SUM(bgt_budget_btwbedrag_van)
                        END bedrag_mutaties
                   FROM bgt_budgetmutatie
                  WHERE bgt_budget_key_van = p_budget_key
                    AND ((p_datum_van IS NOT NULL AND bgt_budgetmutatie_datum >= p_datum_van) OR p_datum_van IS NULL)
                    AND ((p_datum_tot IS NOT NULL AND bgt_budgetmutatie_datum <= p_datum_tot) OR p_datum_tot IS NULL)
                 UNION
                 SELECT CASE WHEN p_btw=0 THEN SUM(bgt_budget_bedrag_naar)
                             WHEN p_btw=1 THEN SUM(bgt_budget_btwbedrag_naar)
                             WHEN p_btw=2 THEN SUM(bgt_budget_bedrag_naar) + SUM(bgt_budget_btwbedrag_naar)
                        END bedrag_mutaties
                   FROM bgt_budgetmutatie
                  WHERE bgt_budget_key_naar = p_budget_key
                    AND ((p_datum_van IS NOT NULL AND bgt_budgetmutatie_datum >= p_datum_van) OR p_datum_van IS NULL)
                    AND ((p_datum_tot IS NOT NULL AND bgt_budgetmutatie_datum <= p_datum_tot) OR p_datum_tot IS NULL)
                ) mut;
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            v_bedrag_mut := NULL;
      END;
      RETURN v_bedrag_mut;
   END getBudgetMutaties;

   FUNCTION getBudgetOpDatum ( p_budget_key IN NUMBER
                             , p_btw IN NUMBER
                             , p_datum DATE DEFAULT NULL
                             ) RETURN NUMBER
   IS
      v_huidig_budget  NUMBER;
      v_mutatie        NUMBER;
      v_datum_budget   NUMBER;
   BEGIN
      -- p_btw: 0=excl.btw, 1=btw, 2=incl.btw.
      BEGIN
         SELECT CASE WHEN p_btw=0 THEN COALESCE(bgt_budget_bedrag, 0)
                     WHEN p_btw=1 THEN COALESCE(bgt_budget_btwbedrag, 0)
                     WHEN p_btw=2 THEN COALESCE(bgt_budget_bedrag, 0) + COALESCE(bgt_budget_btwbedrag, 0)
                END huidig_budget
              , CASE WHEN p_btw=0 THEN BGT.getBudgetMutaties(bgt_budget_key, 0, p_datum, NULL)
                     WHEN p_btw=1 THEN BGT.getBudgetMutaties(bgt_budget_key, 1, p_datum, NULL)
                     WHEN p_btw=2 THEN BGT.getBudgetMutaties(bgt_budget_key, 0, p_datum, NULL) + BGT.getBudgetMutaties(bgt_budget_key, 1, p_datum, NULL)
                END mutaties
           INTO v_huidig_budget
              , v_mutatie
           FROM bgt_budget
          WHERE bgt_budget_key = p_budget_key;
         --
         v_datum_budget := v_huidig_budget - v_mutatie;
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            v_datum_budget := NULL;
      END;
      RETURN v_datum_budget;
   END getBudgetOpDatum;

   FUNCTION getBudgetSoortMutatie  ( p_kostenrubriek_key IN NUMBER
                                   , p_kostensoortgrp_key IN NUMBER
                                   , p_kostensoort_key IN NUMBER
                                   , p_btw IN NUMBER
                                   , p_soortmutatie IN VARCHAR2
                                   , p_datum IN DATE DEFAULT NULL
                                   ) RETURN NUMBER
   IS
      v_bedrag  NUMBER;
   BEGIN
      -- p_btw: 0=excl.btw, 1=btw, 2=incl.btw.
      BEGIN
         SELECT SUM(bgt_mutatie_bedrag) bgt_mutatie_bedrag
           INTO v_bedrag
           FROM ( SELECT b.bgt_kostenrubriek_key
                       , b.prs_kostensoortgrp_key
                       , b.prs_kostensoort_key
                       , b.bgt_budget_isreserve
                       , TRUNC(m.bgt_budgetmutatie_datum)  bgt_budgetmutatie_datum
                       , CASE WHEN p_btw=0 THEN COALESCE(m.bgt_budget_bedrag_van, 0)
                              WHEN p_btw=1 THEN COALESCE(m.bgt_budget_btwbedrag_van, 0)
                              WHEN p_btw=2 THEN COALESCE(m.bgt_budget_bedrag_van, 0) + COALESCE(m.bgt_budget_btwbedrag_van, 0)
                         END bgt_mutatie_bedrag
                       , BGT.getSoortMutatie (m.bgt_budgetmutatie_key) bgt_mutatie_soort
                    FROM bgt_budget b
                       , bgt_budgetmutatie m
                   WHERE b.bgt_budget_key = m.bgt_budget_key_van
                  UNION ALL
                  SELECT b.bgt_kostenrubriek_key
                       , b.prs_kostensoortgrp_key
                       , b.prs_kostensoort_key
                       , b.bgt_budget_isreserve
                       , TRUNC(m.bgt_budgetmutatie_datum)  bgt_budgetmutatie_datum
                       , CASE WHEN p_btw=0 THEN COALESCE(m.bgt_budget_bedrag_naar, 0)
                              WHEN p_btw=1 THEN COALESCE(m.bgt_budget_btwbedrag_naar, 0)
                              WHEN p_btw=2 THEN COALESCE(m.bgt_budget_bedrag_naar, 0) + COALESCE(m.bgt_budget_btwbedrag_naar, 0)
                         END bgt_mutatie_bedrag
                       , BGT.getSoortMutatie (m.bgt_budgetmutatie_key) bgt_mutatie_soort
                    FROM bgt_budget b
                       , bgt_budgetmutatie m
                   WHERE b.bgt_budget_key = m.bgt_budget_key_naar
                ) single_mutatie
         WHERE INSTR(p_soortmutatie, bgt_mutatie_soort) > 0
           AND (  (p_kostenrubriek_key IS NOT NULL AND p_kostensoortgrp_key = -1        AND p_kostensoort_key = -1        AND bgt_kostenrubriek_key = p_kostenrubriek_key)
               OR (p_kostenrubriek_key IS NOT NULL AND p_kostensoortgrp_key IS NULL     AND p_kostensoort_key IS NULL     AND bgt_kostenrubriek_key = p_kostenrubriek_key AND prs_kostensoortgrp_key IS NULL AND prs_kostensoort_key IS NULL)
               OR (p_kostenrubriek_key IS NOT NULL AND p_kostensoortgrp_key IS NOT NULL AND p_kostensoort_key IS NOT NULL AND prs_kostensoort_key = p_kostensoort_key)
               OR (p_kostenrubriek_key IS NULL     AND p_kostensoortgrp_key IS NOT NULL AND p_kostensoort_key = -1        AND prs_kostensoortgrp_key = p_kostensoortgrp_key)
               OR (p_kostenrubriek_key IS NULL     AND p_kostensoortgrp_key IS NOT NULL AND p_kostensoort_key IS NULL     AND prs_kostensoortgrp_key = p_kostensoortgrp_key AND prs_kostensoort_key IS NULL)
               OR (p_kostenrubriek_key IS NULL     AND p_kostensoortgrp_key IS NULL     AND p_kostensoort_key IS NOT NULL AND prs_kostensoort_key = p_kostensoort_key)
               )
           AND (bgt_budgetmutatie_datum < p_datum OR p_datum IS NULL);
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            v_bedrag := NULL;
      END;
      RETURN v_bedrag;
   END getBudgetSoortMutatie;

   FUNCTION getSoortMutatie( p_mutatie_key IN NUMBER
                           ) RETURN VARCHAR2
   IS
      v_budget_van            bgt_budgetmutatie.bgt_budget_key_van%TYPE;
      v_budget_naar           bgt_budgetmutatie.bgt_budget_key_naar%TYPE;
      v_mutatie_omschrijving  bgt_budgetmutatie.bgt_budgetmutatie_omschrijving%TYPE;
      v_mutatie_reserve       bgt_budgetmutatie.bgt_budgetmutatie_reserve%TYPE;
      v_mutatie_level_van     VARCHAR2(1);
      v_mutatie_level_naar    VARCHAR2(1);
      v_soort_mutatie         VARCHAR2(1);
      v_budget_isreserve      bgt_budget.bgt_budget_isreserve%TYPE;
   BEGIN
      BEGIN
         SELECT m.bgt_budget_key_van
              , m.bgt_budget_key_naar
              , m.bgt_budgetmutatie_omschrijving
              , m.bgt_budgetmutatie_reserve
              , CASE WHEN bv.prs_kostensoort_key IS NOT NULL
                     THEN 'S'
                     ELSE CASE WHEN bv.prs_kostensoortgrp_key IS NOT NULL
                               THEN 'G'
                               ELSE CASE WHEN bv.bgt_kostenrubriek_key IS NOT NULL
                                         THEN 'R'
                                         ELSE 'P'
                                         END
                               END
                     END mutatie_level_van
              , CASE WHEN bn.prs_kostensoort_key IS NOT NULL
                     THEN 'S'
                     ELSE CASE WHEN bn.prs_kostensoortgrp_key IS NOT NULL
                               THEN 'G'
                               ELSE CASE WHEN bn.bgt_kostenrubriek_key IS NOT NULL
                                         THEN 'R'
                                         ELSE 'P'
                                         END
                               END
                     END mutatie_level_naar
              , bv.bgt_budget_isreserve
           INTO v_budget_van
              , v_budget_naar
              , v_mutatie_omschrijving
              , v_mutatie_reserve
              , v_mutatie_level_van
              , v_mutatie_level_naar
              , v_budget_isreserve
           FROM bgt_budget bv
              , bgt_budget bn
              , bgt_budgetmutatie m
          WHERE m.bgt_budget_key_van  = bv.bgt_budget_key(+)
            AND m.bgt_budget_key_naar = bn.bgt_budget_key(+)
            AND m.bgt_budgetmutatie_key = p_mutatie_key;
         --
         -- Mutatie van-naar reserve (tussen algemeenreserve en kostensoort of kostenrubriek en kostensoort)
         -- (Is dus allebei tussen kostenrubriek en kostensoort).
         -- Maak nog onderscheid tussen automatische overboeking A (correctie van budget tgv meer gecontracteerd dan budget)
         -- en een gewone mutatie van/naar reserve.
         IF (  (v_mutatie_level_van  = 'R')
            OR (v_mutatie_level_naar = 'R')
            ) THEN
            IF (v_mutatie_reserve = 1) THEN  -- 'AO Automatische overboeking'
                v_soort_mutatie := 'A';
            ELSE
                v_soort_mutatie := 'R';
            END IF;
         END IF;
         --
         -- Mutatie extra budget (er wordt geld aan algemeenreserve, kostenrubriek of kostensoort toegevoegd OF onttrokken.
         IF ((v_budget_van = v_budget_naar) OR (v_budget_van IS NULL) OR (v_budget_naar IS NULL) ) THEN
            v_soort_mutatie := 'E';
         END IF;
         --
         -- Onderlinge mutatie (mutaties tussen kostensoorten)
         IF (   (v_budget_van <> v_budget_naar)
            AND (v_mutatie_level_van = 'S')
            AND (v_mutatie_level_naar = 'S')
            ) THEN
            v_soort_mutatie := 'M';
         END IF;
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            v_soort_mutatie := NULL;
      END;
      --
      RETURN v_soort_mutatie;
   END getSoortMutatie;

   FUNCTION getContractwaarde( p_srtkey IN VARCHAR2
                             , p_key IN NUMBER
                             , p_btw IN NUMBER
                             , p_status NUMBER DEFAULT 3
                             , p_datum_van DATE DEFAULT NULL
                             , p_datum_tot DATE DEFAULT NULL  -- eigenlijk: tot-en-met
                             ) RETURN NUMBER
   IS
      v_bedrag  NUMBER;
   BEGIN
      -- p_srtkey: SRT=prs_kostensoort_key, OPDR=mld_opdr_key.
      -- p_btw: 0=excl.btw, 1=btw, 2=incl.btw.
      -- p_status: 1=raming, 2=gecontracteerd, 3=alles.
      BEGIN
         SELECT CASE WHEN p_btw=0 THEN SUM(COALESCE(mld_opdr_kosten,     0))
                     WHEN p_btw=1 THEN SUM(COALESCE(mld_opdr_kosten_btw, 0))
                     WHEN p_btw=2 THEN SUM(COALESCE(mld_opdr_kosten,     0)) + SUM(COALESCE(mld_opdr_kosten_btw, 0))
                END contracten
           INTO v_bedrag
           FROM mld_opdr
          WHERE p_key = DECODE(p_srtkey, 'SRT', prs_kostensoort_key, 'OPDR', mld_opdr_key)
            AND (  (p_status = 1 AND mld_statusopdr_key = 10)
                OR (p_status = 2 AND mld_statusopdr_key <> 10)
                OR (p_status = 3 AND mld_statusopdr_key = mld_statusopdr_key)
                )
            AND ((p_datum_van IS NOT NULL AND mld_opdr_datumbegin >= p_datum_van) OR p_datum_van IS NULL)
            AND ((p_datum_tot IS NOT NULL AND mld_opdr_datumbegin <= p_datum_tot) OR p_datum_tot IS NULL);
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            v_bedrag := NULL;
      END;
      RETURN v_bedrag;
   END getContractwaarde;

   FUNCTION getRaming( p_mld_opdr_key IN NUMBER
                     , p_btw IN NUMBER
                     , p_datum_van DATE DEFAULT NULL
                     , p_datum_tot DATE DEFAULT NULL
                     ) RETURN NUMBER
   IS
      v_bedrag  NUMBER;
   BEGIN
      v_bedrag := BGT.getContractwaarde('OPDR', p_mld_opdr_key, p_btw, 1, p_datum_van, p_datum_tot);
      RETURN v_bedrag;
   END getRaming;

   FUNCTION getGecontracteerd( p_mld_opdr_key IN NUMBER
                             , p_btw IN NUMBER
                             , p_datum_van DATE DEFAULT NULL
                             , p_datum_tot DATE DEFAULT NULL
                             ) RETURN NUMBER
   IS
      v_bedrag  NUMBER;
   BEGIN
      v_bedrag := BGT.getContractwaarde('OPDR', p_mld_opdr_key, p_btw, 2, p_datum_van, p_datum_tot);
      RETURN v_bedrag;
   END getGecontracteerd;

   FUNCTION getGefactureerdSoort( p_kostensoort_key IN NUMBER
                                , p_btw IN NUMBER
                                ) RETURN NUMBER
   IS
      v_bedrag  NUMBER;
   BEGIN
      BEGIN
         SELECT SUM(BGT.getGefactureerd(mld_opdr_key, p_btw, NULL, NULL))
           INTO v_bedrag
           FROM mld_opdr
          WHERE prs_kostensoort_key = p_kostensoort_key;
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            v_bedrag := NULL;
      END;
      RETURN v_bedrag;
   END getGefactureerdSoort;

   FUNCTION getGefactureerd ( p_mld_opdr_key IN NUMBER
                            , p_btw IN NUMBER
                            , p_datum_van DATE DEFAULT NULL
                            , p_datum_tot DATE DEFAULT NULL  -- eigenlijk: tot-en-met
                            ) RETURN NUMBER
   IS
      v_bedrag  NUMBER;
   BEGIN
      -- p_btw: 0=excl.btw, 1=btw, 2=incl.btw.
      v_bedrag := 0;
      BEGIN
         SELECT CASE WHEN p_btw=0 THEN SUM(COALESCE(fin_factuur_totaal,     0))
                     WHEN p_btw=1 THEN SUM(COALESCE(fin_factuur_totaal_btw, 0))
                     WHEN p_btw=2 THEN SUM(COALESCE(fin_factuur_totaal,     0)) + SUM(COALESCE(fin_factuur_totaal_btw, 0))
                END facturen
           INTO v_bedrag
           FROM fin_factuur
          WHERE ((p_datum_van IS NOT NULL AND fin_factuur_advies >= p_datum_van) OR p_datum_van IS NULL)
            AND ((p_datum_tot IS NOT NULL AND fin_factuur_advies <= p_datum_tot) OR p_datum_tot IS NULL)
            AND mld_opdr_key = p_mld_opdr_key;
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            v_bedrag := 0;
      END;
      RETURN v_bedrag;
   END getGefactureerd;

   FUNCTION getTefactureren ( p_mld_opdr_key IN NUMBER
                            , p_btw IN NUMBER
                            , p_datum_van DATE DEFAULT NULL
                            , p_datum_tot DATE DEFAULT NULL
                            ) RETURN NUMBER
   IS
      v_statusopdr  NUMBER;
      v_cont        NUMBER;
      v_fact        NUMBER;
      v_bedrag      NUMBER;
   BEGIN
      -- p_btw: 0=excl.btw, 1=btw, 2=incl.btw.
      v_bedrag := 0;
      BEGIN
         SELECT NVL(mld_statusopdr_key, 0)
           INTO v_statusopdr
           FROM mld_opdr
          WHERE mld_opdr_key = p_mld_opdr_key;
         --
         IF (v_statusopdr <> 10) THEN
            v_cont := getGecontracteerd(p_mld_opdr_key, p_btw, p_datum_van, p_datum_tot);
            v_fact := getGefactureerd(p_mld_opdr_key, p_btw, p_datum_van, p_datum_tot);
            v_bedrag := COALESCE(v_cont, 0) - COALESCE(v_fact, 0);
         END IF;
      END;
      RETURN v_bedrag;
   END getTefactureren;


END bgt;
/

REGISTERRUN('$Id$')

#endif // BGT
