451 lines
17 KiB
Plaintext
451 lines
17 KiB
Plaintext
#ifdef FIN
|
|
/* FIN_PAC.SRC
|
|
* $Revision: 5 $
|
|
* $Modtime: 6-09-10 15:33 $
|
|
*/
|
|
|
|
/* Formatted on 16-7-2010 17:57:48 (QP5 v5.136.908.31019) */
|
|
CREATE OR REPLACE PACKAGE fin
|
|
AS
|
|
PROCEDURE setfactuurstatus (pfactuurkey IN NUMBER, pstatus IN NUMBER, puserkey IN NUMBER);
|
|
|
|
FUNCTION matchfactuur (pfactuur_key IN NUMBER)
|
|
RETURN NUMBER;
|
|
|
|
PROCEDURE matchandsetfactuur (pfactuur_key IN NUMBER, prejecttoo IN BOOLEAN);
|
|
|
|
PROCEDURE autoapprovefactuur (pfactuur_key IN NUMBER);
|
|
END fin;
|
|
/
|
|
|
|
/* Formatted on 16-7-2010 18:17:24 (QP5 v5.136.908.31019) */
|
|
CREATE OR REPLACE PACKAGE BODY fin
|
|
AS
|
|
-- Geef meldingkey, gewenste status en userkey, en de status wortdt
|
|
-- gezet, waarbij zonodig (indien verandering) een trackrecord wordt gemaakt
|
|
-- Als de status niet wijzigt, wordt ook geen trackrecord gemaakt
|
|
-- ZIE schema StateDiagramOpdrachten.vsd
|
|
PROCEDURE setfactuurstatus (pfactuurkey IN NUMBER, pstatus IN NUMBER, puserkey IN NUMBER)
|
|
AS
|
|
currentstatus fin_factuur.fin_factuur_statuses_key%TYPE;
|
|
newstatus fin_factuur.fin_factuur_statuses_key%TYPE;
|
|
eventcode fac_srtnotificatie.fac_srtnotificatie_code%TYPE;
|
|
BEGIN
|
|
SELECT fin_factuur_statuses_key
|
|
INTO currentstatus
|
|
FROM fin_factuur
|
|
WHERE fin_factuur_key = pfactuurkey;
|
|
|
|
CASE pstatus
|
|
WHEN 1 -- Afgewezen
|
|
THEN
|
|
IF currentstatus IS NULL OR currentstatus = 2
|
|
THEN
|
|
newstatus := pstatus;
|
|
eventcode := 'FINFNO';
|
|
END IF;
|
|
WHEN 2 -- Ingevoerd
|
|
THEN
|
|
IF currentstatus IS NULL
|
|
THEN
|
|
newstatus := pstatus;
|
|
eventcode := 'FINNEW';
|
|
ELSIF currentstatus = 1 OR currentstatus = 6
|
|
THEN
|
|
newstatus := pstatus;
|
|
eventcode := 'FINFUN';
|
|
END IF;
|
|
WHEN 6 -- Verwerkt
|
|
THEN
|
|
IF currentstatus = 2
|
|
THEN
|
|
newstatus := pstatus;
|
|
eventcode := 'FINFOK';
|
|
END IF;
|
|
WHEN 7 -- Uitgegeven
|
|
THEN
|
|
IF currentstatus = 6
|
|
THEN
|
|
newstatus := pstatus;
|
|
eventcode := 'FINVER';
|
|
END IF;
|
|
ELSE
|
|
-- Invalid statuschange or no change
|
|
newstatus := NULL;
|
|
END CASE;
|
|
|
|
IF newstatus IS NOT NULL
|
|
THEN
|
|
-- vooralsnog lopen de notificaties 1-op-1 met de tracking
|
|
-- noticode := eventcode;
|
|
|
|
UPDATE fin_factuur
|
|
SET fin_factuur_statuses_key = newstatus
|
|
WHERE fin_factuur_key = pfactuurkey;
|
|
|
|
-- We know that trackaction doesnt do tracking if eventcode is null
|
|
fac.trackaction (eventcode, pfactuurkey, puserkey, NULL, NULL);
|
|
END IF;
|
|
END;
|
|
|
|
-- Gegeven de 2 referentiekeys, lever het type 'B', 'O' of 'C' op
|
|
-- Interne functie in de package vooralsnog
|
|
FUNCTION getreferentietype (po_key IN NUMBER, pc_key IN NUMBER, pb_key IN NUMBER)
|
|
RETURN VARCHAR2
|
|
IS
|
|
rtype VARCHAR2 (1) := '?';
|
|
BEGIN
|
|
IF po_key IS NOT NULL
|
|
THEN
|
|
rtype := 'O';
|
|
DBMS_OUTPUT.put_line ('opdrachtkey: ' || po_key);
|
|
ELSIF pc_key IS NOT NULL
|
|
THEN
|
|
rtype := 'C';
|
|
DBMS_OUTPUT.put_line ('contractkey: ' || pc_key);
|
|
ELSIF pb_key IS NOT NULL
|
|
THEN
|
|
rtype := 'B';
|
|
DBMS_OUTPUT.put_line ('besteloprachtkey: ' || pb_key);
|
|
END IF;
|
|
|
|
RETURN rtype;
|
|
END;
|
|
|
|
FUNCTION matchfactuur (pfactuur_key IN NUMBER)
|
|
RETURN NUMBER
|
|
IS
|
|
-- controleert deze nieuwe factuur, en levert een oordeel op:
|
|
-- -1 factuur niet (automatisch) goed
|
|
-- 0 niks van te zeggen of reeds goed-/afgekeurd/verwerkt
|
|
-- 1 factuur okay
|
|
|
|
ftype VARCHAR2 (1);
|
|
c_key fin_factuur.cnt_contract_key%TYPE;
|
|
b_key fin_factuur.bes_bestelopdr_key%TYPE;
|
|
o_key fin_factuur.mld_opdr_key%TYPE;
|
|
factuurstatus fin_factuur.fin_factuur_statuses_key%TYPE;
|
|
factuurdatum fin_factuur.fin_factuur_datum%TYPE;
|
|
discipline ins_tab_discipline.ins_discipline_key%TYPE;
|
|
korting bes_bestelopdr.bes_bestelopdr_korting%TYPE;
|
|
levkosten bes_bestelopdr.bes_bestelopdr_levkosten%TYPE;
|
|
contracttermijnkosten cnt_contract.cnt_contract_termijnkosten%TYPE;
|
|
contractkosten cnt_contract.cnt_contract_kosten%TYPE;
|
|
opdrachtkosten mld_opdr.mld_opdr_kosten%TYPE;
|
|
matchtype mld_typeopdr.mld_typeopdr_matchtype%TYPE;
|
|
factuurbedrag NUMBER (12, 2);
|
|
bestelbedrag NUMBER (12, 2); -- van de opdracht waar deze factuur over gaat
|
|
totaalgefactureerd NUMBER (12, 2); -- met deze factuur erbij eerder gefactureerd van dezelfde B(R)OC
|
|
retval NUMBER := 0;
|
|
|
|
-- Bepaal te tolerantie van de vakgroep
|
|
-- waarschijnlijk in procenten of zo?
|
|
-- of geven we de factuurwaarde mee en leveren we true/false op?
|
|
FUNCTION tolerantiematch (pdisckey IN NUMBER, pftype IN VARCHAR2, pfactbedrag IN NUMBER, pbestelbedrag IN NUMBER)
|
|
RETURN BOOLEAN
|
|
IS
|
|
discpct NUMBER;
|
|
discmarge NUMBER;
|
|
upperlimit NUMBER;
|
|
BEGIN
|
|
CASE
|
|
WHEN pftype = 'B'
|
|
THEN
|
|
SELECT p.bes_disc_params_factuurpct, p.bes_disc_params_factuurmarge
|
|
INTO discpct, discmarge
|
|
FROM bes_disc_params p
|
|
WHERE p.bes_ins_discipline_key = pdisckey;
|
|
WHEN pftype = 'C'
|
|
THEN
|
|
SELECT p.cnt_disc_params_factuurpct, p.cnt_disc_params_factuurmarge
|
|
INTO discpct, discmarge
|
|
FROM cnt_disc_params p
|
|
WHERE p.cnt_ins_discipline_key = pdisckey;
|
|
WHEN pftype = 'O'
|
|
THEN
|
|
SELECT p.mld_disc_params_factuurpct, p.mld_disc_params_factuurmarge
|
|
INTO discpct, discmarge
|
|
FROM mld_disc_params p
|
|
WHERE p.mld_ins_discipline_key = pdisckey;
|
|
ELSE
|
|
discpct := 0;
|
|
discmarge := 0;
|
|
END CASE;
|
|
|
|
IF discpct IS NULL AND discmarge IS NULL
|
|
THEN
|
|
upperlimit := pbestelbedrag;
|
|
ELSIF discpct IS NULL
|
|
THEN
|
|
upperlimit := pbestelbedrag + discmarge;
|
|
ELSE
|
|
upperlimit := pbestelbedrag * (100 + discpct) / 100;
|
|
END IF;
|
|
|
|
DBMS_OUTPUT.put_line ('discipline: ' || pdisckey);
|
|
DBMS_OUTPUT.put_line ('tolerantie%: ' || discpct);
|
|
DBMS_OUTPUT.put_line ('tolerantie-abs: ' || discmarge);
|
|
DBMS_OUTPUT.put_line ('bestel/opdracht/contactbedrag: ' || pbestelbedrag);
|
|
DBMS_OUTPUT.put_line ('bovengrens ' || upperlimit);
|
|
DBMS_OUTPUT.put_line ('factuurbedrag: ' || pfactbedrag);
|
|
RETURN pfactbedrag <= upperlimit;
|
|
END;
|
|
BEGIN
|
|
--------------------------------------------
|
|
------------ START MAIN ROUTINE ------------
|
|
--------------------------------------------
|
|
---
|
|
--- Over wat voor soort factuur hebben we het?
|
|
---
|
|
IF pfactuur_key IS NULL
|
|
THEN
|
|
DBMS_OUTPUT.put_line ('STOP, factuurkey: NULL');
|
|
RETURN 0;
|
|
END IF;
|
|
|
|
DBMS_OUTPUT.put_line ('\nfactuurkey: ' || pfactuur_key);
|
|
|
|
SELECT mld_opdr_key,
|
|
cnt_contract_key,
|
|
bes_bestelopdr_key,
|
|
fin_factuur_totaal,
|
|
fin_factuur_statuses_key,
|
|
fin_factuur_datum
|
|
INTO o_key,
|
|
c_key,
|
|
b_key,
|
|
factuurbedrag,
|
|
factuurstatus,
|
|
factuurdatum
|
|
FROM fin_factuur
|
|
WHERE fin_factuur_key = pfactuur_key;
|
|
|
|
IF factuurstatus <> 2 -- is al verwerkt, matching zinloos
|
|
THEN
|
|
DBMS_OUTPUT.put_line ('STOP, factuurstatus: ' || factuurstatus);
|
|
RETURN 0;
|
|
END IF;
|
|
|
|
ftype := fin.getreferentietype (o_key, c_key, b_key);
|
|
|
|
DBMS_OUTPUT.put_line ('>opdrachttype: ' || ftype);
|
|
|
|
--
|
|
-- Ga maar eens matchen
|
|
--
|
|
CASE
|
|
--
|
|
-- BESTELLING
|
|
--
|
|
WHEN ftype = 'B'
|
|
THEN
|
|
-- Factuur ok als binnen de toleranties van de bestelcatalogus
|
|
-- en het totaal met de eerder bestellingfacturen ook
|
|
SELECT SUM (boi.bes_bestelopdr_item_aantal * boi.bes_bestelopdr_item_prijs),
|
|
MAX (isg.ins_discipline_key),
|
|
MAX (COALESCE (bo.bes_bestelopdr_korting, 0)),
|
|
MAX (COALESCE (bo.bes_bestelopdr_levkosten, 0))
|
|
INTO bestelbedrag, discipline, korting, levkosten
|
|
FROM bes_bestelopdr_item boi,
|
|
bes_bestelling_item bbi,
|
|
ins_srtdeel isd,
|
|
ins_srtgroep isg,
|
|
bes_bestelopdr bo
|
|
WHERE boi.bes_bestelopdr_item_key = bbi.bes_bestelopdr_item_key
|
|
AND bo.bes_bestelopdr_key = boi.bes_bestelopdr_key
|
|
AND bbi.ins_srtdeel_key = isd.ins_srtdeel_key
|
|
AND isd.ins_srtgroep_key = isg.ins_srtgroep_key
|
|
AND boi.bes_bestelopdr_key = b_key;
|
|
|
|
bestelbedrag := bestelbedrag - korting + levkosten;
|
|
|
|
SELECT SUM (fin_factuur_totaal) -- is excl BTW
|
|
INTO totaalgefactureerd
|
|
FROM fin_factuur
|
|
WHERE bes_bestelopdr_key = b_key AND fin_factuur_statuses_key <> 1 AND fin_factuur_datum <= factuurdatum;
|
|
|
|
IF tolerantiematch (discipline, ftype, totaalgefactureerd, bestelbedrag)
|
|
THEN
|
|
retval := 1;
|
|
ELSE
|
|
retval := -1;
|
|
END IF;
|
|
--
|
|
-- CONTRACT
|
|
--
|
|
WHEN ftype = 'C'
|
|
THEN
|
|
-- controle op termijn bedrag en totaal (later ook factuurschema)
|
|
SELECT c.cnt_contract_termijnkosten, c.cnt_contract_kosten, c.ins_discipline_key
|
|
INTO contracttermijnkosten, contractkosten, discipline
|
|
FROM cnt_contract c
|
|
WHERE cnt_contract_key = c_key;
|
|
|
|
IF contracttermijnkosten IS NULL OR contractkosten IS NULL
|
|
THEN
|
|
retval := 0;
|
|
END IF;
|
|
|
|
SELECT SUM (fin_factuur_totaal)
|
|
INTO totaalgefactureerd
|
|
FROM fin_factuur
|
|
WHERE cnt_contract_key = c_key AND fin_factuur_statuses_key <> 1 AND fin_factuur_datum <= factuurdatum;
|
|
|
|
IF tolerantiematch (discipline, ftype, totaalgefactureerd, contractkosten)
|
|
AND tolerantiematch (discipline, ftype, factuurbedrag, contracttermijnkosten)
|
|
THEN
|
|
retval := 1;
|
|
ELSE
|
|
retval := -1;
|
|
END IF;
|
|
--
|
|
-- OPDRACHT
|
|
--
|
|
WHEN ftype = 'O'
|
|
THEN
|
|
-- controleer op basis van typeopdr.matchtype
|
|
SELECT o.mld_opdr_kosten, m.mld_ins_discipline_key, top.mld_typeopdr_matchtype
|
|
INTO opdrachtkosten, discipline, matchtype
|
|
FROM mld_opdr o, mld_melding m, mld_typeopdr top
|
|
WHERE o.mld_melding_key = m.mld_melding_key
|
|
AND o.mld_typeopdr_key = top.mld_typeopdr_key
|
|
AND mld_opdr_key = o_key;
|
|
|
|
DBMS_OUTPUT.put_line ('opdrachtkosten: ' || opdrachtkosten);
|
|
DBMS_OUTPUT.put_line ('matchtype: ' || matchtype);
|
|
|
|
IF opdrachtkosten IS NULL -- niks van te zeggen
|
|
THEN
|
|
RETURN 0;
|
|
END IF;
|
|
|
|
IF matchtype = 0 -- altijd goed
|
|
THEN
|
|
retval := 1;
|
|
ELSIF matchtype = 1 -- 1 factuur moet matchen met opdracht
|
|
THEN
|
|
IF tolerantiematch (discipline, ftype, factuurbedrag, opdrachtkosten)
|
|
THEN
|
|
retval := 1;
|
|
ELSE
|
|
retval := -1;
|
|
END IF;
|
|
ELSIF matchtype = 2 -- 2 termijnfactuur
|
|
THEN
|
|
SELECT SUM (fin_factuur_totaal)
|
|
INTO totaalgefactureerd
|
|
FROM fin_factuur
|
|
WHERE mld_opdr_key = o_key AND fin_factuur_statuses_key <> 1 AND fin_factuur_datum <= factuurdatum;
|
|
|
|
IF tolerantiematch (discipline, ftype, totaalgefactureerd, opdrachtkosten)
|
|
THEN
|
|
retval := 1;
|
|
ELSE
|
|
retval := -1;
|
|
END IF;
|
|
ELSE --IF matchtype = 3 THEN
|
|
DBMS_OUTPUT.put_line ('matchtype unsupported yet!');
|
|
RETURN 0;
|
|
END IF;
|
|
|
|
SELECT SUM (fin_factuur_totaal)
|
|
INTO totaalgefactureerd
|
|
FROM fin_factuur
|
|
WHERE mld_opdr_key = o_key AND fin_factuur_statuses_key <> 1 AND fin_factuur_datum <= factuurdatum;
|
|
|
|
IF tolerantiematch (discipline, ftype, totaalgefactureerd, opdrachtkosten)
|
|
THEN
|
|
retval := 1;
|
|
ELSE
|
|
retval := -1;
|
|
END IF;
|
|
ELSE
|
|
retval := 0;
|
|
END CASE;
|
|
|
|
RETURN retval;
|
|
END;
|
|
|
|
-- Keurt een ingevoerde factuur (onvoorwaardelijk) goed of (als rejecttoo) af op basis van de matchingscriteria
|
|
PROCEDURE matchandsetfactuur (pfactuur_key IN NUMBER, prejecttoo IN BOOLEAN)
|
|
IS
|
|
BEGIN
|
|
CASE fin.matchfactuur (pfactuur_key)
|
|
WHEN 1
|
|
THEN
|
|
fin.setfactuurstatus (pfactuur_key, 6, NULL);
|
|
WHEN -1
|
|
THEN
|
|
IF prejecttoo
|
|
THEN
|
|
fin.setfactuurstatus (pfactuur_key, 1, NULL);
|
|
END IF;
|
|
ELSE NULL;
|
|
END CASE;
|
|
END;
|
|
|
|
-- Behandelt een ingevoerde factuur conform settings en matchingscriteria
|
|
PROCEDURE autoapprovefactuur (pfactuur_key IN NUMBER)
|
|
IS
|
|
ftype VARCHAR2 (1);
|
|
c_key fin_factuur.cnt_contract_key%TYPE;
|
|
b_key fin_factuur.bes_bestelopdr_key%TYPE;
|
|
o_key fin_factuur.mld_opdr_key%TYPE;
|
|
factuurappr bes_disc_params.bes_disc_params_factuurappr%TYPE;
|
|
BEGIN
|
|
SELECT mld_opdr_key, cnt_contract_key, bes_bestelopdr_key
|
|
INTO o_key, c_key, b_key
|
|
FROM fin_factuur
|
|
WHERE fin_factuur_key = pfactuur_key;
|
|
|
|
ftype := fin.getreferentietype (o_key, c_key, b_key);
|
|
|
|
-- Jammer dat ik ook hier nog eens de discipline moet bepalen
|
|
CASE
|
|
WHEN ftype = 'B'
|
|
THEN
|
|
SELECT p.bes_disc_params_factuurappr
|
|
INTO factuurappr
|
|
FROM bes_disc_params p
|
|
WHERE p.bes_ins_discipline_key =
|
|
(SELECT MAX (isg.ins_discipline_key)
|
|
FROM bes_bestelopdr_item boi, bes_bestelling_item bbi, ins_srtdeel isd, ins_srtgroep isg
|
|
WHERE boi.bes_bestelopdr_item_key = bbi.bes_bestelopdr_item_key
|
|
AND bbi.ins_srtdeel_key = isd.ins_srtdeel_key
|
|
AND isd.ins_srtgroep_key = isg.ins_srtgroep_key
|
|
AND boi.bes_bestelopdr_key = b_key);
|
|
WHEN ftype = 'C'
|
|
THEN
|
|
SELECT p.cnt_disc_params_factuurappr
|
|
INTO factuurappr
|
|
FROM cnt_disc_params p
|
|
WHERE p.cnt_ins_discipline_key = (SELECT c.ins_discipline_key
|
|
FROM cnt_contract c
|
|
WHERE cnt_contract_key = c_key);
|
|
WHEN ftype = 'O'
|
|
THEN
|
|
SELECT p.mld_disc_params_factuurappr
|
|
INTO factuurappr
|
|
FROM mld_disc_params p
|
|
WHERE p.mld_ins_discipline_key =
|
|
(SELECT m.mld_ins_discipline_key
|
|
FROM mld_opdr o, mld_melding m, mld_typeopdr top
|
|
WHERE o.mld_melding_key = m.mld_melding_key
|
|
AND o.mld_typeopdr_key = top.mld_typeopdr_key
|
|
AND mld_opdr_key = o_key);
|
|
ELSE
|
|
factuurappr := 0;
|
|
END CASE;
|
|
|
|
IF factuurappr = 1
|
|
THEN
|
|
matchandsetfactuur (pfactuur_key, FALSE);
|
|
END IF;
|
|
END;
|
|
END fin;
|
|
/
|
|
|
|
REGISTERRUN('$Workfile: fin_pac.src $','$Revision: 5 $')
|
|
|
|
#endif // FIN
|