NYBU#25763: Reserveringen: tarief-uitbreidingen tbv NYBU

svn path=/Database/trunk/; revision=17669
This commit is contained in:
Marcel Bourseau
2013-04-18 07:59:52 +00:00
parent 1ace6a410b
commit 6870cc42e1

View File

@@ -977,18 +977,33 @@ AS
price_morning res_ruimte.res_ruimte_prijs_ochtend%TYPE;
price_afternoon res_ruimte.res_ruimte_prijs_middag%TYPE;
price_evening res_ruimte.res_ruimte_prijs_avond%TYPE;
price_allday res_ruimte.res_ruimte_prijs_dag%TYPE;
room_price_total res_rsv_ruimte.res_rsv_ruimte_prijs%TYPE;
prs_kostenplaats_extern prs_kostenplaats.prs_kostenplaats_extern%TYPE;
res_ruimte_korting res_rsv_ruimte.res_rsv_ruimte_korting%TYPE;
res_ruimte_length NUMBER;
res_ruimte_begin NUMBER;
res_ruimte_end NUMBER;
res_length_morning NUMBER;
res_length_afternoon NUMBER;
res_length_evening NUMBER;
lres_t_middag NUMBER;
lres_t_avond NUMBER;
res_1e_dagblok NUMBER;
res_2e_dagblok NUMBER;
cost_morning NUMBER;
cost_afternoon NUMBER;
cost_evening NUMBER;
verwijderdatum res_rsv_ruimte.res_rsv_ruimte_verwijder%TYPE;
statusfokey res_rsv_ruimte.res_status_fo_key%TYPE;
doorbelasting res_disc_params.res_disc_params_kosten%TYPE;
res_roompricingmethod NUMBER;
thisroomprice NUMBER;
BEGIN
-- Is de reservering verwijderd
SELECT rrr.res_rsv_ruimte_verwijder,
@@ -1039,59 +1054,79 @@ AS
THEN
NULL;
END;
lres_t_middag := fac.safe_to_number (fac.getsetting ('res_t_middag'));
lres_t_avond := fac.safe_to_number (fac.getsetting ('res_t_avond'));
BEGIN
SELECT COALESCE (ru.res_ruimte_prijs, 0),
ru.res_ruimte_prijs_vast,
COALESCE (ru.res_ruimte_prijs_ochtend, 0),
COALESCE (ru.res_ruimte_prijs_middag, 0),
ru.res_ruimte_prijs_avond,
fac.safe_to_number (TO_CHAR (rr.res_rsv_ruimte_tot - rr.res_rsv_ruimte_van)) * 24,
fac.safe_to_number (TO_CHAR (rr.res_rsv_ruimte_van, 'HH24'))
+ fac.safe_to_number (TO_CHAR (rr.res_rsv_ruimte_van, 'MI')) / 60,
fac.safe_to_number (TO_CHAR (rr.res_rsv_ruimte_tot, 'HH24'))
+ fac.safe_to_number (TO_CHAR (rr.res_rsv_ruimte_tot, 'MI')) / 60
INTO room_price,
room_price_fixed,
price_morning,
price_afternoon,
price_evening,
res_ruimte_length,
res_ruimte_begin,
res_ruimte_end
FROM res_rsv_ruimte rr, res_ruimte_opstelling ro, res_ruimte ru
WHERE rr.res_ruimte_opstel_key = ro.res_ruimte_opstel_key
AND ro.res_ruimte_key = ru.res_ruimte_key
AND rr.res_rsv_ruimte_key = pres_rsv_ruimte_key;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
-- Geen R-reservering maar een CV-reservering, dan kost de ruimte niks
RETURN 0;
END;
-- Nu zijn er verschillende berekeningsmethoden om de prijs van een gereserveerde ruimte
-- te bepalen. Welke methode gehanteerd wordt is bepaald door setting 'res_roompricingmethod'
res_roompricingmethod := fac.safe_to_number (fac.getsetting ('res_roompricingmethod'));
lres_t_middag := fac.safe_to_number (fac.getsetting ('res_t_middag'));
lres_t_avond := fac.safe_to_number (fac.getsetting ('res_t_avond'));
-- Wat basisgegevens
BEGIN
SELECT COALESCE (ru.res_ruimte_prijs, 0),
ru.res_ruimte_prijs_vast,
COALESCE (ru.res_ruimte_prijs_ochtend, 0),
COALESCE (ru.res_ruimte_prijs_middag, 0),
COALESCE (ru.res_ruimte_prijs_avond, 0),
COALESCE (ru.res_ruimte_prijs_dag, 0),
fac.safe_to_number (TO_CHAR (rr.res_rsv_ruimte_tot - rr.res_rsv_ruimte_van)) * 24,
fac.safe_to_number (TO_CHAR (rr.res_rsv_ruimte_van, 'HH24'))
+ fac.safe_to_number (TO_CHAR (rr.res_rsv_ruimte_van, 'MI')) / 60,
fac.safe_to_number (TO_CHAR (rr.res_rsv_ruimte_tot, 'HH24'))
+ fac.safe_to_number (TO_CHAR (rr.res_rsv_ruimte_tot, 'MI')) / 60,
COALESCE (kp.prs_kostenplaats_extern, 0),
COALESCE (rr.res_rsv_ruimte_korting, 0)
INTO room_price,
room_price_fixed,
price_morning,
price_afternoon,
price_evening,
price_allday,
res_ruimte_length,
res_ruimte_begin,
res_ruimte_end,
prs_kostenplaats_extern,
res_ruimte_korting
FROM res_rsv_ruimte rr, res_ruimte_opstelling ro, res_ruimte ru, prs_kostenplaats kp
WHERE rr.res_ruimte_opstel_key = ro.res_ruimte_opstel_key
AND rr.prs_kostenplaats_key = kp.prs_kostenplaats_key (+) -- of isdie verplicht?
AND ro.res_ruimte_key = ru.res_ruimte_key
AND rr.res_rsv_ruimte_key = pres_rsv_ruimte_key;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
-- Geen R-reservering maar een CV-reservering, dan kost de ruimte niks. Klaar.
RETURN 0;
END;
-- Uren dagdeel ochtend: [0 - lres_t_middag]
res_length_morning := LEAST (res_ruimte_end, lres_t_middag) - res_ruimte_begin;
IF res_length_morning < 0
THEN
res_length_morning := 0;
END IF;
-- Uren dagdeel middag: [lres_t_middag - lres_t_avond]
res_length_afternoon := LEAST (res_ruimte_end, lres_t_avond) - GREATEST (res_ruimte_begin, lres_t_middag);
IF res_length_afternoon < 0
THEN
res_length_afternoon := 0;
END IF;
-- Uren dagdeel avond: [lres_t_avond - 24]
res_length_evening := res_ruimte_end - GREATEST (res_ruimte_begin, lres_t_avond);
IF res_length_evening < 0
THEN
res_length_evening := 0;
END IF;
IF res_roompricingmethod = 1
THEN
-- Zoals we het altijd deden
IF (lres_t_middag > 0 AND lres_t_middag < 24 AND lres_t_avond > 0 AND lres_t_avond < 24)
THEN -- Prijsbepaling per dagdeel?
-- Uren dagdeel ochtend: [0 - lres_t_middag]
res_length_morning := LEAST (res_ruimte_end, lres_t_middag) - res_ruimte_begin;
IF res_length_morning < 0
THEN
res_length_morning := 0;
END IF;
-- Uren dagdeel middag: [lres_t_middag - lres_t_avond]
res_length_afternoon := LEAST (res_ruimte_end, lres_t_avond) - GREATEST (res_ruimte_begin, lres_t_middag);
IF res_length_afternoon < 0
THEN
res_length_afternoon := 0;
END IF;
-- Uren dagdeel avond: [lres_t_avond - 24]
res_length_evening := res_ruimte_end - GREATEST (res_ruimte_begin, lres_t_avond);
IF res_length_evening < 0
THEN
res_length_evening := 0;
END IF;
THEN -- Prijsbepaling per dagdeel
IF room_price_fixed = 1
THEN
-- Een prijs per blok (kennelijk). Tellen hoeveel blokken dan
IF res_length_morning > 0
THEN
res_length_morning := 1;
@@ -1105,7 +1140,7 @@ AS
res_length_evening := 1;
END IF;
END IF;
room_price_total :=
thisroomprice :=
price_morning * res_length_morning
+ price_afternoon * res_length_afternoon
+ price_evening * res_length_evening;
@@ -1114,10 +1149,193 @@ AS
THEN
res_ruimte_length := 1;
END IF;
room_price_total := room_price * res_ruimte_length;
thisroomprice := room_price * res_ruimte_length;
END IF;
RETURN room_price_total * doorbelasting / 100;
ELSIF res_roompricingmethod = 2
THEN
-- Lever voor de duur van de reservering de laagste prijs op: zie NYBU#25763
-- Dagprijs -> Uren uitgesplitst per dagdeel (uur van dat dagdeel x prijs) en vergelijken met dagdeelprijs, en daarvan het goedkoopste.
-- Voor alle 3 dagdelen verkijgen we dan een goedkoopste gedrag (D1 + D2 +D3), die optellen en vergelijken met dagprijs, en daarvan de goedkoopste.
-- room_price_fixed = 1 werkt alleen op dagdeelprijs, en NIET op uurtarief (eigenlijk zouden we 2 vinkjes moeten hebben, voor ieder 1 afzonderlijk).
-- En tenslotte nog vergelijken met dagprijs, neem de goedkoopste.
cost_morning := 0;
cost_afternoon := 0;
cost_evening := 0;
-- Hieronder de uren uitsplitsen naar dagdelen en vergelijken met dagdeelprijzen, daarvan de goedkoopste.
-- Net als bij res_roompricingmethod = 1, ook kijken of de middag en avond tijden zijn ingesteld, anders doen die niet mee.
IF (lres_t_middag > 0 AND lres_t_middag < 24 AND lres_t_avond > 0 AND lres_t_avond < 24)
THEN
-- Een prijs per blok (kennelijk). Tellen hoeveel blokken dan
IF res_length_morning > 0
THEN
IF room_price_fixed = 1
THEN
cost_morning := price_morning;
ELSE
cost_morning := price_morning * res_length_morning;
END IF;
IF (res_length_morning * room_price) < cost_morning
THEN
cost_morning := res_length_morning * room_price;
END IF;
END IF;
IF res_length_afternoon > 0
THEN
IF room_price_fixed = 1
THEN
cost_afternoon := price_afternoon;
ELSE
cost_afternoon := price_afternoon * res_length_afternoon;
END IF;
IF (res_length_afternoon * room_price) < cost_afternoon
THEN
cost_afternoon := res_length_afternoon * room_price;
END IF;
END IF;
IF res_length_evening > 0
THEN
IF room_price_fixed = 1
THEN
cost_evening := price_evening;
ELSE
cost_evening := price_evening * res_length_evening;
END IF;
IF (res_length_evening * room_price) < cost_evening
THEN
cost_evening := res_length_evening * room_price;
END IF;
END IF;
thisroomprice := cost_morning + cost_afternoon + cost_evening;
-- Als dagprijs = 0 (d.i. price_allday is NULL cq. is niet gevuld), dan telt die niet mee, en moet de nieuwe prijsberekening gelden.
-- Of als dagprijs lager is lager is dan de nieuwe prijsberekening, dan ook.
IF (price_allday <> 0) AND price_allday < thisroomprice
THEN
thisroomprice := price_allday;
END IF;
ELSE
thisroomprice := price_allday;
END IF;
ELSIF res_roompricingmethod = 3
THEN
-- Methode 3: STAFFELS van b.v. 4 en 8: zie WIBC#26163
-- uurprijs, dagdeelprijs en dagprijs volgens onderstaande methodiek (x = vergaderduur):
-- x < 4 uur: duur x uurprijs
-- 4 <= x < 8 uur: dagdeelprijs (ochtend) + (duur - 4) x uurprijs
-- x >= 8 uur: dagprijs, (of indien dagprijs niet is ingesteld, dan dagdeelprijs (middag) + (duur - 8) x uurprijs
-- Bij methode 3 wordt lres_t_middag niet als tijdsgrens tussen morgen en middag ingesteld, maar als een 'blok' van een aantal uren.
-- En idem voor avond, die is het 2e blok (groter aantal) uren dan het 1e blok.
--
res_1e_dagblok := lres_t_middag;
res_2e_dagblok := lres_t_avond;
--- MB: Overlegd met DEVELOP (PF): geconstateerd dat res_ruimte_res bij een reservering van 10:00-14:00 niet exact 4 is, maar 4.000000en-een-beetje.
--- Tot dusver ook geen probleem met voorgaande price-methodes, maar nu gaan we (exact) vergelijken met een staffel, en dan kan die net de verkeerde kant (if-then-else) opvallen!
-- Vandaar deze foef om af te ronden, alleen op deze plaats.
res_ruimte_length := ROUND(res_ruimte_length, 2);
IF (res_1e_dagblok > 0 AND res_1e_dagblok < 24)
THEN
-- Er is een 1e block gedefinieerd
IF res_ruimte_length < res_1e_dagblok
THEN
-- Reserv. duur is kleiner dan 1e blok uren, gewoon uur x prijs.
-- Ook hier doet setting room_price_fixed ook gewoon mee.
IF room_price_fixed = 1
THEN
res_ruimte_length := 1;
END IF;
thisroomprice := room_price * res_ruimte_length;
ELSE
-- Reserv. duur is groter dan 1e blok uren, is er een 2e blok gedefinieerd?
-- Als 2e blok er is, en aantal uren is ook nog meer dan 2e blok, dan de dagprijs.
-- Ook hier doet setting room_price_fixed ook gewoon mee.
IF (res_2e_dagblok > 0 AND res_2e_dagblok < 24)
THEN
-- Er is een 2e block gedefinieerd
IF res_ruimte_length >= res_2e_dagblok
THEN
-- Reserv. duur is GROTER dan 2e blok uren, dan geldt de dagprijs indien deze is ingesteld.
-- Als de dagprijs NIET is ingesteld, dan dagdeelprijs (middag) + (duur - 8) x uurprijs
IF price_allday > 0
THEN
-- Er is een dagprijs voor de ruimte ingesteld, die telt dan.
thisroomprice := price_allday;
ELSE
-- Er is geen dagprijs ingesteld, neem dan dagdeelprijs (middag) + (duur - 8) x uurprijs
IF room_price_fixed = 1 AND res_ruimte_length > res_2e_dagblok
THEN
-- Niet 1 (zoals overal anders, maar 1 optellen bij het 2e dagblok (voor hieronder om weer 1 over te houden)!!
-- En alleen indien res_ruimte_length groter is dan 2e dagblok (anders geen 1 bij optellen, dan geldt alleen dagdeelprijs)
res_ruimte_length := res_2e_dagblok + 1;
END IF;
thisroomprice := price_afternoon + (room_price * (res_ruimte_length - res_2e_dagblok));
END IF;
ELSE
-- Reserv. duur is ligt tussen 1e en 2e blok uren in,
-- dan geldt dagdeelprijs (ochtend) + (duur - 4) x uurprijs
IF room_price_fixed = 1 AND res_ruimte_length > res_1e_dagblok
THEN
-- Niet 1 (zoals overal anders, maar 1 optellen bij het 1e dagblok (voor hieronder om weer 1 over te houden)!!
-- En alleen indien res_ruimte_length groter is dan 1e dagblok (anders geen 1 bij optellen, dan geldt alleen dagdeelprijs)
res_ruimte_length := res_1e_dagblok + 1;
END IF;
thisroomprice := price_morning + (room_price * (res_ruimte_length - res_1e_dagblok));
END IF;
ELSE
-- Er is geen 2e blok uren gedefinieerd, alleen een 1e urenblok.
-- Dan gewoon dagdeelprijs (ochtend) + (duur - 4) x uurprijs
IF room_price_fixed = 1 AND res_ruimte_length > res_1e_dagblok
THEN
-- Niet 1 (zoals overal anders, maar 1 optellen bij het 1e dagblok (voor hieronder om weer 1 over te houden)!!
-- En alleen indien res_ruimte_length groter is dan 1e dagblok (anders geen 1 bij optellen, dan geldt alleen dagdeelprijs)
res_ruimte_length := res_1e_dagblok + 1;
END IF;
thisroomprice := price_morning + (room_price * (res_ruimte_length - res_1e_dagblok));
END IF;
END IF;
ELSE
-- Er is geen 1e blok gedefinieerd.
-- Dan maar gewoon uur x prijs.
-- Ook hier doet setting room_price_fixed ook gewoon mee.
IF room_price_fixed = 1
THEN
res_ruimte_length := 1;
END IF;
thisroomprice := room_price * res_ruimte_length;
END IF;
ELSIF res_roompricingmethod = 9
THEN
-- Kost nooit wat.
thisroomprice := 0;
END IF;
-- Hier rekening houden met intern/extern tarief
IF prs_kostenplaats_extern = 0
THEN
thisroomprice := thisroomprice * fac.safe_to_number (fac.getsetting ('res_ruimte_prijsfactor_intern'));
END IF;
-- Hier wordt een eventuele korting (door FO ingevoerd) nog verrekend: zie NYBU#25763
thisroomprice := thisroomprice - res_ruimte_korting;
-- Doorbelastingspercentage (bij annuleren) op het laatste moment nog.
thisroomprice := thisroomprice * doorbelasting / 100;
RETURN thisroomprice;
END;
FUNCTION getdeelprijs (pres_rsv_deel_key IN NUMBER)
RETURN NUMBER IS
deel_price res_deel.res_deel_prijs%TYPE;