#ifdef CNT /* * $Revision$ * $Id$ */ CREATE OR REPLACE PACKAGE cnt AS PROCEDURE setcontractstatus (pcontractkey IN NUMBER, pstatus IN NUMBER, puserkey IN NUMBER); FUNCTION getVerlengschemaEinddatum(startdatum IN DATE, cnt_key IN NUMBER, volgnr IN NUMBER) RETURN DATE; FUNCTION cnt_getTermijndatum (pdate IN DATE, ptermijn_key IN NUMBER, prichting IN NUMBER) RETURN DATE; FUNCTION termijnjaarfactor (ptermijn_key IN NUMBER) RETURN NUMBER; FUNCTION cnt_getOpzegdatum (pcnt_contract_key IN NUMBER) RETURN DATE; FUNCTION cnt_getRappeldatum (pcnt_contract_key IN NUMBER) RETURN DATE; FUNCTION cnt_contract_status (van IN DATE, rappel IN DATE, opzeg IN DATE, tot IN DATE) RETURN NUMBER; PROCEDURE autoverleng_contract; PROCEDURE autoinactiveer_contract; PROCEDURE splitscontract (p_key IN NUMBER, p_datum IN DATE, p_user IN NUMBER, p_amount NUMBER); PROCEDURE generatefactuurschema (pcontractkey IN NUMBER,ptermijnbedrag IN NUMBER DEFAULT NULL); FUNCTION getnieuwsteversiekey(p_key IN NUMBER) RETURN NUMBER; FUNCTION sprintf (ps IN VARCHAR2 , p_contract_key IN NUMBER) RETURN VARCHAR2; PROCEDURE remove(p_contract_key IN NUMBER); PROCEDURE notifycontractbedrijven (pcntkey NUMBER, ptrackingkey NUMBER, pnotidelay NUMBER DEFAULT NULL); PRAGMA RESTRICT_REFERENCES (cnt_contract_status, WNDS, WNPS); END cnt; / CREATE OR REPLACE PACKAGE BODY cnt AS -- Geef contractkey, 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 StateDiagramContracten.vsd PROCEDURE setcontractstatus (pcontractkey IN NUMBER, pstatus IN NUMBER, puserkey IN NUMBER) AS currentstatus cnt_contract.cnt_contract_status%TYPE; newstatus cnt_contract.cnt_contract_status%TYPE; eventcode VARCHAR(7); -- fac_srtnotificatie.fac_srtnotificatie_code%TYPE is te klein voor '@CNTNEW' BEGIN SELECT cnt_contract_status INTO currentstatus FROM cnt_contract WHERE cnt_contract_key = pcontractkey; CASE pstatus WHEN 0 -- Actief THEN IF currentstatus IS NULL THEN newstatus := pstatus; eventcode := 'CNTNEW'; -- direct ook notificeren ELSIF currentstatus = 2 OR currentstatus = 3 -- Het kan ook zijn dat er geen fiattering nodig is. THEN newstatus := pstatus; eventcode := 'CNTFIT'; fac.notifytrackingbedrijven('CNTNEW', pcontractkey); -- Nu alsnog notificeren, we zijn helemaal klaar met fiatteren END IF; WHEN 1 -- Gesloten THEN IF currentstatus = 0 THEN newstatus := pstatus; eventcode := 'CNTCLO'; END IF; WHEN 2 -- Nieuw THEN IF currentstatus IS NULL THEN newstatus := pstatus; eventcode := '@CNTNEW'; -- nog niet notificeren ELSIF currentstatus = 3 THEN newstatus := pstatus; eventcode := 'CNTREJ'; END IF; WHEN 3 -- Ter goedkeuring THEN IF currentstatus = 2 OR currentstatus IS NULL THEN newstatus := pstatus; eventcode := 'CNTCPT'; 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 cnt_contract SET cnt_contract_status = newstatus WHERE cnt_contract_key = pcontractkey; -- We know that trackaction doesnt do tracking if eventcode is null fac.trackaction (eventcode, pcontractkey, puserkey, NULL, NULL); END IF; END; -- Bepaal de einddatum na x iteraties van het verlengschema vanaf een startdatum. FUNCTION getVerlengschemaEinddatum(startdatum IN DATE, cnt_key IN NUMBER, volgnr IN NUMBER) RETURN DATE IS CURSOR c_verleng IS SELECT cnt_verlengschema_volgnr , cnt_verlengschema_verlengtermijn FROM cnt_verlengschema WHERE cnt_verlengschema_volgnr <= volgnr AND cnt_contract_key = cnt_key; einddatum DATE := startdatum; BEGIN FOR c IN c_verleng LOOP einddatum := cnt.cnt_getTermijndatum(einddatum, c.cnt_verlengschema_verlengtermijn, 1); END LOOP; RETURN einddatum; END; -- Deze functie bepaalt de datum door het termijn (ptermijn_key) van de datum (pdate) in mindering te brengen. -- Indien de 29, 30 of 31 datum niet in de betreffende maand voorkomt wordt de eerste van de volgende maand genomen. -- prichting geeft aan of ten opzichte van pdate achteruit (-1) of vooruit (1, of anders) moet worden gerekend. FUNCTION cnt_getTermijndatum (pdate IN DATE, ptermijn_key IN NUMBER, prichting IN NUMBER) RETURN DATE IS ptermijn_type VARCHAR2(1); ptermijn_aantal NUMBER; lrichting NUMBER; BEGIN IF prichting = -1 THEN lrichting := -1; ELSE lrichting := 1; END IF; -- Bepaal type en aantal periodes IF ptermijn_key IS NOT NULL THEN SELECT cnt_termijn_type, cnt_termijn_aantal INTO ptermijn_type, ptermijn_aantal FROM cnt_termijn WHERE cnt_termijn_key = ptermijn_key; ELSE -- Als ptermijn_key leeg/ongedefinieerd, return pdate (ofwel termijn dan impliciet 0 dagen)! RETURN pdate; END IF; IF ptermijn_type = 'D' THEN RETURN pdate + (lrichting * ptermijn_aantal); ELSIF ptermijn_type = 'W' THEN RETURN pdate + (lrichting * ptermijn_aantal * 7); ELSIF ptermijn_type = 'M' THEN RETURN fac.addMonths(pdate, lrichting * ptermijn_aantal); ELSE -- ptermijn_type = 'Y' RETURN fac.addMonths(pdate, lrichting * ptermijn_aantal * 12); END IF; END; -- Deze functie benadert de factor om een contracttermijn te normaliseren tot een (1) jaar. -- Als dat niet kan (ongeldige termijn) wordt nu -1 opgeleverd -- Vb: 4W -> 13, 2M ->6, 2J-> 0,5 -- Kan geen rekening houden met schrikkeljaren en 53 weken en zo FUNCTION termijnjaarfactor (ptermijn_key IN NUMBER) RETURN NUMBER IS ptermijn_type VARCHAR2 (1); ptermijn_aantal NUMBER; BEGIN IF ptermijn_key IS NOT NULL THEN SELECT cnt_termijn_type, cnt_termijn_aantal INTO ptermijn_type, ptermijn_aantal FROM cnt_termijn WHERE cnt_termijn_key = ptermijn_key; ELSE -- Als ptermijn_key leeg/ongedefinieerd, return dan maar 1 RETURN -1; END IF; IF ptermijn_aantal = 0 THEN RETURN -1; -- delen door null mag niet he END IF; IF ptermijn_type = 'D' THEN RETURN 365 / ptermijn_aantal; -- soms 366 ELSIF ptermijn_type = 'W' THEN RETURN 52 / ptermijn_aantal; -- soms 53 ELSIF ptermijn_type = 'M' THEN RETURN 12 / ptermijn_aantal; ELSE -- ptermijn_type = 'Y' RETURN 1 / ptermijn_aantal; END IF; END; FUNCTION cnt_getOpzegdatum (pcnt_contract_key IN NUMBER) RETURN DATE IS plooptijd_tot DATE; popzegtermijn NUMBER; BEGIN SELECT cnt_contract_looptijd_tot, cnt_contract_opzegtermijn INTO plooptijd_tot, popzegtermijn FROM cnt_contract WHERE cnt_contract_key = pcnt_contract_key; RETURN cnt_getTermijndatum (plooptijd_tot, popzegtermijn, -1); END; FUNCTION cnt_getRappeldatum (pcnt_contract_key IN NUMBER) RETURN DATE IS plooptijd_tot DATE; prappeltermijn NUMBER; popzegtermijn NUMBER; BEGIN SELECT cnt_contract_looptijd_tot, cnt_contract_rappeltermijn, cnt_contract_opzegtermijn INTO plooptijd_tot, prappeltermijn, popzegtermijn FROM cnt_contract WHERE cnt_contract_key = pcnt_contract_key; RETURN cnt_getTermijndatum (cnt_getTermijndatum (plooptijd_tot, popzegtermijn, -1), prappeltermijn, -1); END; FUNCTION cnt_contract_status (van IN DATE, rappel IN DATE, opzeg IN DATE, tot IN DATE) RETURN NUMBER AS varSysdate DATE; BEGIN varSysdate:=SYSDATE; IF varSysdate < van THEN RETURN 0; ELSIF varSysdate <= rappel THEN RETURN 1; ELSIF varSysdate <= opzeg THEN RETURN 2; ELSIF varSysdate <= tot THEN RETURN 3; END IF; RETURN 4; END; PROCEDURE autoverleng_contract IS CURSOR c_verleng IS SELECT c.cnt_contract_key , c.ins_discipline_key , c.cnt_contract_nummer_intern , c.cnt_contract_omschrijving , c.cnt_contract_looptijd_tot , c.cnt_contract_verleng_termijn , o.cnt_termijn_omschrijving opzegtermijn , cnt.cnt_getTermijndatum (c.cnt_contract_looptijd_tot, c.cnt_contract_opzegtermijn, -1) dtopzeggen , v.cnt_termijn_omschrijving verlengtermijn , cnt.cnt_getTermijndatum (c.cnt_contract_looptijd_tot, c.cnt_contract_verleng_termijn, 1) dtnieuw FROM cnt_contract c , cnt_disc_params p , cnt_termijn o , cnt_termijn v WHERE c.ins_discipline_key = p.cnt_ins_discipline_key AND c.cnt_contract_opzegtermijn = o.cnt_termijn_key AND c.cnt_contract_verleng_termijn = v.cnt_termijn_key AND c.cnt_contract_verwijder IS NULL AND BITAND(p.cnt_disc_params_opties,1) = 1 -- Dit contracttype mag automatisch verlengd worden AND BITAND(c.cnt_contract_verlenging,4) = 4 -- Dit contract mag automatisch verlengd worden AND TRUNC(SYSDATE) > cnt.cnt_getTermijndatum (c.cnt_contract_looptijd_tot, c.cnt_contract_opzegtermijn, -1) AND NOT EXISTS ( SELECT 1 FROM cnt_contract cn WHERE cn.cnt_contract_nummer_intern = c.cnt_contract_nummer_intern AND cn.cnt_contract_versie > c.cnt_contract_versie AND cn.cnt_contract_looptijd_van = (c.cnt_contract_looptijd_tot + 1) AND cn.cnt_contract_verwijder IS NULL ); tracking VARCHAR2(4000); this_verlengschema_key cnt_verlengschema.cnt_verlengschema_key%TYPE; next_verlengschema_key cnt_verlengschema.cnt_verlengschema_key%TYPE; next_termijn cnt_termijn.cnt_termijn_key%TYPE; infinite_prolongate NUMBER(1) := 0; BEGIN FOR cnt_verloopt IN c_verleng LOOP UPDATE cnt_contract SET cnt_contract_looptijd_tot = cnt_verloopt.dtnieuw WHERE cnt_contract_key = cnt_verloopt.cnt_contract_key; tracking := REPLACE(REPLACE(lcl.l('lcl_cnt_prolongation_tracking') , '{0}', cnt_verloopt.verlengtermijn ) , '{1}', TO_CHAR(cnt_verloopt.dtnieuw,'dd-mm-yyyy') ); fac.trackaction ('CNTUPD', cnt_verloopt.cnt_contract_key, NULL, NULL, tracking); -- Heeft dit automatisch verlengbaar contract een verlengschema? BEGIN SELECT this_schema_key , next_schema_key INTO this_verlengschema_key , next_verlengschema_key FROM ( SELECT cnt_verlengschema_key AS this_schema_key , LEAD(cnt_verlengschema_key) OVER(ORDER BY cnt_verlengschema_volgnr) AS next_schema_key FROM cnt_verlengschema WHERE cnt_contract_key = cnt_verloopt.cnt_contract_key ) WHERE rownum = 1; -- Dan eerstvolgende verlengtermijn uit verlengschema naar het veld verlengtermijn in contract kopieren... IF next_verlengschema_key IS NOT NULL THEN SELECT cnt_verlengschema_verlengtermijn INTO next_termijn FROM cnt_verlengschema WHERE cnt_verlengschema_key = next_verlengschema_key; ELSE IF infinite_prolongate = 1 THEN next_termijn := cnt_verloopt.cnt_contract_verleng_termijn; ELSE next_termijn := NULL; END IF; END IF; UPDATE cnt_contract SET cnt_contract_verleng_termijn = next_termijn WHERE cnt_contract_key = cnt_verloopt.cnt_contract_key; -- ...en deze verlengtermijn uit het verlengschema verwijderen. DELETE FROM cnt_verlengschema WHERE cnt_verlengschema_key = this_verlengschema_key; EXCEPTION WHEN NO_DATA_FOUND THEN NULL; -- Laat laatste verlengtermijn staan als er geen volgende in het schema gevonden kan worden. END; END LOOP; END; PROCEDURE autoinactiveer_contract IS l_prs_perslid_key prs_perslid.prs_perslid_key%TYPE; tracking VARCHAR2(4000); CURSOR c_inactiveer IS SELECT c.cnt_contract_key FROM cnt_contract c WHERE c.cnt_contract_inactiveren = 1 AND TRUNC(c.cnt_contract_looptijd_tot) < TRUNC(SYSDATE) AND NOT EXISTS (SELECT f.fin_factuur_key -- Contract mag geen openstaande facturen hebben. FROM fin_factuur f WHERE f.cnt_contract_key = c.cnt_contract_key AND f.fin_factuur_statuses_key NOT IN (1,7) AND f.fin_factuur_verwijder IS NULL); BEGIN BEGIN SELECT prs_perslid_key INTO l_prs_perslid_key FROM prs_perslid WHERE prs_perslid_oslogin = '_SYSTEEM' AND prs_perslid_verwijder IS NULL; EXCEPTION WHEN NO_DATA_FOUND THEN fac.putsystemnotification ('Invalid configuration: missing _SYSTEEM user', 1); END; FOR cnt_inactiveer IN c_inactiveer LOOP cnt.setcontractstatus(cnt_inactiveer.cnt_contract_key, 1, l_prs_perslid_key); -- Zorgt ook voor tracking en daarmee notificatie. UPDATE cnt_contract SET cnt_contract_inactiveren = 0 WHERE cnt_contract_key = cnt_inactiveer.cnt_contract_key; tracking := lcl.l('lcl_cnt_is_cntupd') || CHR(10) || lcl.l('lcl_cnt_auto_close') || ': ' || lcl.l('lcl_Yes') || lcl.l('lcl_trackto') || lcl.l('lcl_No'); fac.trackaction('CNTUPD', cnt_inactiveer.cnt_contract_key, NULL, NULL, tracking); END LOOP; END; PROCEDURE splitscontract (p_key IN NUMBER, p_datum IN DATE, p_user IN NUMBER, p_amount NUMBER) IS begin1 DATE; eind1 DATE; versie1 cnt_contract.cnt_contract_versie%TYPE; newkey NUMBER; nummer1 cnt_contract.cnt_contract_nummer_intern%TYPE; amount1 cnt_contract.cnt_contract_kosten%TYPE; approve_new cnt_disc_params.cnt_disc_params_approve_new%TYPE; srtcontract_type cnt_disc_params.cnt_srtcontract_type%TYPE; new_status cnt_contract.cnt_contract_status%TYPE; tracking VARCHAR2 (4000); splitsen BOOLEAN := TRUE; BEGIN -- Splits het contract met p_key in twee delen: het oude dat eindigt op p_datum - 1, -- en een nieuwe kopie die begint op die p_datum -- p_amount is -optioneel- het bedrag dat bij het oude contract moeten blijven -- de rest komt bij de nieuwe. Als p_amount NULL is, eindigen beide contracten -- met het originele bedrag. IF p_key IS NULL THEN RETURN; END IF; BEGIN SELECT c.cnt_contract_looptijd_van, c.cnt_contract_looptijd_tot, COALESCE (c.cnt_contract_versie, '0'), cnt_contract_nummer_intern, cnt_contract_kosten, cdp.cnt_srtcontract_type, cdp.cnt_disc_params_approve_new, c.cnt_contract_status INTO begin1, eind1, versie1, nummer1, amount1, srtcontract_type, approve_new, new_status FROM cnt_contract c, cnt_disc_params cdp WHERE c.ins_discipline_key = cdp.cnt_ins_discipline_key AND c.cnt_contract_key = p_key; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN; END; IF (begin1 < p_datum AND eind1 > p_datum) THEN -- Splitsen van contract. begin1 := p_datum; IF (fac.getsetting('cnt_contract_approval') = 1 AND srtcontract_type != 6) -- niet voor mantelcontracten THEN new_status := 2; -- altijd op nieuw(=concept) ELSE new_status := 0; -- direct actief END IF; ELSIF (eind1 < p_datum) THEN -- Verlengen van contract begin1 := eind1 + 1; eind1 := p_datum; splitsen := FALSE; ELSE RETURN; END IF; -- de datum is een zinvolle splitsdatum, alles in orde INSERT INTO cnt_contract (cnt_contract_nummer, cnt_contract_omschrijving, cnt_contract_looptijd_tot, cnt_contract_kosten, cnt_contract_uurloon, cnt_prs_bedrijf_key, cnt_prs_afdeling_key, cnt_prs_perslid_key, cnt_contract_verwijder, cnt_contract_nummer_intern, cnt_contract_korting, prs_contactpersoon_key, cnt_contract_contact_persoon, ins_discipline_key, cnt_contract_document, prs_perslid_key_eig, prs_perslid_key_beh, prs_afdeling_key_eig, cnt_contract_status, cnt_contract_looptijd_van, prs_kostenplaats_key, cnt_contract_termijnkosten, prs_kostensoort_key, cnt_contract_opmerking, cnt_contract_mantel_key, cnt_contract_opzegtermijn, cnt_contract_rappeltermijn, cnt_contract_versie, prs_dienst_key, cnt_contract_termijntermijn ) SELECT cnt_contract_nummer, cnt_contract_omschrijving, eind1, amount1 - COALESCE(p_amount, 0), cnt_contract_uurloon, cnt_prs_bedrijf_key, cnt_prs_afdeling_key, cnt_prs_perslid_key, NULL, cnt_contract_nummer_intern, cnt_contract_korting, prs_contactpersoon_key, cnt_contract_contact_persoon, ins_discipline_key, cnt_contract_document, prs_perslid_key_eig, prs_perslid_key_beh, prs_afdeling_key_eig, new_status, begin1, prs_kostenplaats_key, cnt_contract_termijnkosten, prs_kostensoort_key, cnt_contract_opmerking, cnt_contract_mantel_key, cnt_contract_opzegtermijn, cnt_contract_rappeltermijn, TO_CHAR (versie1 + 1), prs_dienst_key, cnt_contract_termijntermijn FROM cnt_contract WHERE cnt_contract_key = p_key; --- ik wil de nieuwe key weten SELECT cnt_contract_key INTO newkey FROM cnt_contract WHERE cnt_contract_nummer_intern = nummer1 AND cnt_contract_versie = TO_CHAR (versie1 + 1) AND cnt_contract_verwijder IS NULL; --- Een versieloos oud contract krijgt expliciet versie 0 --- Looptijd_tot en kosten moteen alleen bij splitsen worden aangepast. IF splitsen THEN UPDATE cnt_contract SET cnt_contract_looptijd_tot = p_datum - 1, cnt_contract_versie = versie1, cnt_contract_kosten = COALESCE(p_amount, cnt_contract_kosten) WHERE cnt_contract_key = p_key; ELSE UPDATE cnt_contract SET cnt_contract_versie = versie1 WHERE cnt_contract_key = p_key; END IF; tracking := lcl.l('lcl_cnt_is_cntupd') || CHR(10) || lcl.l('lcl_cnt_enddate') || ': ' || TO_CHAR(eind1, 'dd-mm-yyyy') || lcl.l('lcl_trackto') || TO_CHAR((p_datum - 1), 'dd-mm-yyyy'); IF (p_amount IS NOT NULL AND p_amount <> amount1) THEN tracking := tracking || CHR(10) || lcl.l('lcl_cnt_contract_sum') || ': ' || amount1 || lcl.l('lcl_trackto') || p_amount; END IF; fac.trackaction ('CNTUPD', p_key, p_user, NULL, tracking); -- de basis is gelegd, nu de aanhang meekopieren -- flexkenmerken INSERT INTO cnt_kenmerkcontract (cnt_contract_key, cnt_kenmerk_key, cnt_kenmerkcontract_waarde ) SELECT newkey, k.cnt_kenmerk_key, k.cnt_kenmerkcontract_waarde FROM cnt_kenmerkcontract k WHERE k.cnt_contract_key = p_key AND k.cnt_kenmerkcontract_verwijder IS NULL; -- cnt_contract_dienst (blind kopieren) INSERT INTO cnt_contract_dienst (cnt_contract_key, cnt_contract_dienst_contactext, cnt_contract_dienst_contactint, cnt_contract_dienst_materiaal, cnt_contract_dienst_uitvoertd, cnt_contract_dienst_uren, cnt_contract_dienst_uurloon, mld_stdmelding_key, prs_bedrijf_key ) SELECT newkey, cd.cnt_contract_dienst_contactext, cd.cnt_contract_dienst_contactint, cd.cnt_contract_dienst_materiaal, cd.cnt_contract_dienst_uitvoertd, cd.cnt_contract_dienst_uren, cd.cnt_contract_dienst_uurloon, cd.mld_stdmelding_key, cd.prs_bedrijf_key FROM cnt_contract_dienst cd WHERE cd.cnt_contract_key = p_key; -- scope en zo -- cnt_contract_object INSERT INTO cnt_contract_object (cnt_contract_key, cnt_ins_srtdeel_key, cnt_ins_deel_key ) SELECT newkey, cob.cnt_ins_srtdeel_key, cob.cnt_ins_deel_key FROM cnt_contract_object cob WHERE cob.cnt_contract_key = p_key AND cob.cnt_contract_object_verwijder IS NULL; --cnt_contract_plaats INSERT INTO cnt_contract_plaats (cnt_contract_key, cnt_alg_plaats_code, cnt_alg_plaats_key, cnt_contract_plaats_gewicht ) SELECT newkey, cop.cnt_alg_plaats_code, cop.cnt_alg_plaats_key, cop.cnt_contract_plaats_gewicht FROM cnt_contract_plaats cop WHERE cop.cnt_contract_key = p_key AND cop.cnt_contract_plaats_verwijder IS NULL; IF p_amount IS NOT NULL AND amount1 <> 0 AND fac.getsetting('cnt_scopeverdeling') = 1 THEN -- gewicht is dan telkens een bedrag en cnt_contract_kosten is het totaal daarvan UPDATE cnt_contract_plaats SET cnt_contract_plaats_gewicht = cnt_contract_plaats_gewicht / amount1 * p_amount WHERE cnt_contract_key = p_key; UPDATE cnt_contract_plaats SET cnt_contract_plaats_gewicht = cnt_contract_plaats_gewicht / amount1 * (amount1 - p_amount) WHERE cnt_contract_key = newkey; END IF; --cnt_factuurschema: splitst op dezelfde grensdatum UPDATE cnt_factuurschema SET cnt_contract_key = newkey WHERE cnt_contract_key = p_key AND cnt_factuurschema_boekmaand >= TO_CHAR(p_datum, 'YYYY-MM'); fac.trackaction ('CNTNEW', newkey, p_user, NULL, NULL); END splitscontract; -- Genereer een factuurschema met een gelijk bedrag per maand gedurende -- de looptijd van het contract -- Verondersteld dat er nog geen schema was. PROCEDURE generatefactuurschema ( pcontractkey IN NUMBER, ptermijnbedrag IN NUMBER DEFAULT NULL) AS maanden NUMBER (10); maand NUMBER (10); ltermijnbedrag cnt_factuurschema.cnt_factuurschema_bedrag%TYPE; BEGIN FOR cnt_rec IN (SELECT cnt_contract_kosten, cnt_contract_looptijd_tot, cnt_contract_looptijd_van FROM cnt_contract WHERE cnt_contract_key = pcontractkey) LOOP maanden := 1 + TRUNC(MONTHS_BETWEEN (cnt_rec.cnt_contract_looptijd_tot, cnt_rec.cnt_contract_looptijd_van)); ltermijnbedrag := COALESCE (ptermijnbedrag, cnt_rec.cnt_contract_kosten / maanden); FOR maand IN 0 .. maanden - 1 LOOP INSERT INTO cnt_factuurschema (cnt_contract_key, cnt_factuurschema_boekmaand, cnt_factuurschema_bedrag) VALUES (pcontractkey, TO_CHAR ( ADD_MONTHS (cnt_rec.cnt_contract_looptijd_van, maand), 'YYYY-MM'), ltermijnbedrag); END LOOP; END LOOP; END; -- Zoek de key van de hoogste revisie van het meegegeven contract -- Beseffende dat _versie een oplopende reeks is en hopende dat -- nummer_intern hetzelfde blijft over versies en vrij uniek is -- Voor wat extra zekerheid wordt bedrijf betrokken FUNCTION getnieuwsteversiekey (p_key IN NUMBER) RETURN NUMBER IS nummer1 cnt_contract.cnt_contract_nummer_intern%TYPE; versie1 cnt_contract.cnt_contract_versie%TYPE; bedrijf1 cnt_contract.cnt_prs_bedrijf_key%TYPE; maxversie NUMBER; resultkey NUMBER; BEGIN resultkey := p_key; -- mocht ik niks vinden, dan is dit em SELECT cnt_contract_nummer_intern, cnt_contract_versie, cnt_prs_bedrijf_key INTO nummer1, versie1, bedrijf1 FROM cnt_contract WHERE cnt_contract_verwijder IS NULL AND cnt_contract_key = p_key; SELECT MAX (fac.safe_to_number (cnt_contract_versie)) INTO maxversie FROM cnt_contract WHERE cnt_contract_nummer_intern = nummer1 AND cnt_prs_bedrijf_key = bedrijf1 AND cnt_contract_verwijder IS NULL; IF maxversie IS NOT NULL THEN SELECT cnt_contract_key INTO resultkey FROM cnt_contract WHERE cnt_contract_nummer_intern = nummer1 AND cnt_prs_bedrijf_key = bedrijf1 AND fac.safe_to_number (cnt_contract_versie) = maxversie AND cnt_contract_verwijder IS NULL; END IF; RETURN resultkey; END; FUNCTION sprintf (ps IN VARCHAR2 , p_contract_key IN NUMBER ) RETURN VARCHAR2 IS s VARCHAR2 (2048 CHAR); varlev VARCHAR2 (255 CHAR); -- Kan nu ook een samenstelling zijn van prs_perslid gegevens. varomsch cnt_contract.cnt_contract_omschrijving%TYPE; varnummer cnt_contract.cnt_contract_nummer_intern%TYPE; BEGIN s := ps; -- We do support substitution of placeholders in the messages -- ##LEV## = prs_bedrijf_naam -- ##OMSCH## = cnt_contract_omschrijving -- ##KEY## = cnt_contract_nummer_intern IF INSTR (s, '#') > 0 THEN SELECT COALESCE(b.prs_bedrijf_naam, p.prs_perslid_naam_full, a.prs_afdeling_omschrijving), c.cnt_contract_omschrijving, c.cnt_contract_nummer_intern INTO varlev, varomsch, varnummer FROM cnt_contract c, prs_bedrijf b, prs_v_perslid_fullnames_all p, prs_afdeling a WHERE c.cnt_prs_bedrijf_key = b.prs_bedrijf_key(+) AND c.cnt_prs_perslid_key = p.prs_perslid_key(+) AND c.cnt_prs_afdeling_key = a.prs_afdeling_key(+) AND c.cnt_contract_key = p_contract_key; s := REPLACE (REPLACE (REPLACE (s, '##LEV##', varlev), '##OMSCH##', varomsch), '##KEY##', varnummer ); END IF; RETURN s; END; PROCEDURE remove(p_contract_key IN NUMBER) IS CURSOR c_contract IS SELECT cnt_contract_key FROM cnt_contract WHERE cnt_contract_mantel_key = p_contract_key; CURSOR c_factuur IS SELECT fin_factuur_key FROM fin_factuur WHERE cnt_contract_key = p_contract_key; CURSOR c_bijlagen(p_refkey IN NUMBER) IS SELECT fac_bijlagen_key FROM fac_bijlagen b , cnt_contract r WHERE b.fac_bijlagen_refkey = r.cnt_contract_key AND b.fac_bijlagen_module = 'CNT' AND b.fac_bijlagen_refkey = p_refkey; BEGIN -- Verwijder alle subcontracten van dit contract. FOR ref_contract IN c_contract LOOP cnt.remove(ref_contract.cnt_contract_key); END LOOP; FOR ref_factuur IN c_factuur LOOP fin.remove(ref_factuur.fin_factuur_key); END LOOP; FOR ref_bijlagen IN c_bijlagen(p_contract_key) LOOP flx.deleteflexbijlage (ref_bijlagen.fac_bijlagen_key); END LOOP; FOR ref_mldopdr IN (SELECT mld_opdr_key FROM mld_opdr WHERE cnt_contract_key = p_contract_key ) LOOP -- Verwijder melding-opdrachten die aan dit contract zitten. mld.remove_opdr(ref_mldopdr.mld_opdr_key); END LOOP; DELETE FROM cnt_contract WHERE cnt_contract_key = p_contract_key; -- Van de volgende tabellen worden de records die naar deze p_contact_key -- verwijzen met ON DELETE CASCADE ook verwijderd: -- cnt_contract_note -- cnt_contract_object -- cnt_contract_plaats -- cnt_contract_dienst -- cnt_factuurschema -- cnt_kenmerkcontract -- In de volgende tabel wordt cnt_contract_key leeg gemaakt bij het verwijderen van p_contract_key: -- mld_opdr fac.remove_tracking('contract', p_contract_key); -- NB: -- Tabel bes_bestelopdr heeft ook een cnt_contract key, maar deze heeft geen referential integrity constraint. -- In geen enkele omgeving is cnt_contract_key in deze tabel ingevuld. END; PROCEDURE notifycontractbedrijven (pcntkey NUMBER, ptrackingkey NUMBER, pnotidelay NUMBER DEFAULT NULL) AS BEGIN FOR bedrijfrec IN (SELECT b.prs_bedrijf_key, l.alg_locatie_key, CASE WHEN b.prs_bedrijf_key = c.cnt_prs_bedrijf_key THEN 'C' ELSE 'G' END bedrijfadres_type, cnt_contract_nummer_intern, c.ins_discipline_key, COALESCE (l.alg_locatie_email, ins_discipline_email), d.prs_bedrijf_key persoon_bedrijf_key -- van de melder, niet de uitvoerende FROM prs_bedrijf b, cnt_contract c, ins_tab_discipline d, alg_locatie l, prs_perslid p, prs_v_afdeling d, ( SELECT cnt_contract_key, DECODE (MIN (cp1.cnt_alg_plaats_code), 'L', MIN (cp1.cnt_alg_plaats_key), MIN (alg_boom.alg_locatie_key)) cnt_locatie_key FROM cnt_contract_plaats cp1, (SELECT alg_r.alg_ruimte_key, alg_r.alg_verdieping_key, alg_v.alg_gebouw_key, alg_g.alg_locatie_key, 'R' alg_type FROM alg_ruimte alg_r, alg_verdieping alg_v, alg_gebouw alg_g WHERE alg_r.alg_verdieping_key = alg_v.alg_verdieping_key AND alg_v.alg_gebouw_key = alg_g.alg_gebouw_key UNION SELECT TO_NUMBER (NULL), alg_v.alg_verdieping_key, alg_v.alg_gebouw_key, alg_g.alg_locatie_key, 'V' alg_type FROM alg_verdieping alg_v, alg_gebouw alg_g WHERE alg_v.alg_gebouw_key = alg_g.alg_gebouw_key UNION SELECT TO_NUMBER (NULL), TO_NUMBER (NULL), alg_g.alg_gebouw_key, alg_g.alg_locatie_key, 'G' alg_type FROM alg_gebouw alg_g) alg_boom WHERE cp1.cnt_alg_plaats_key = CASE cp1.cnt_alg_plaats_code WHEN 'G' THEN alg_boom.alg_gebouw_key(+) WHEN 'V' THEN alg_boom.alg_verdieping_key(+) WHEN 'R' THEN alg_boom.alg_ruimte_key(+) END AND cp1.cnt_alg_plaats_code = alg_boom.alg_type(+) AND cp1.cnt_contract_plaats_verwijder IS NULL GROUP BY cnt_contract_key HAVING COUNT (1) = 1) cp WHERE c.cnt_contract_key = pcntkey AND d.ins_discipline_key = c.ins_discipline_key AND c.cnt_contract_key = cp.cnt_contract_key(+) AND cp.cnt_locatie_key = l.alg_locatie_key(+) AND d.prs_afdeling_key = p.prs_afdeling_key AND p.prs_perslid_key = c.prs_perslid_key_beh AND ( b.prs_bedrijf_key = c.cnt_prs_bedrijf_key -- type 'C' OR EXISTS (SELECT 1 FROM prs_bedrijfadres ba WHERE ba.prs_bedrijf_key = b.prs_bedrijf_key AND ba.prs_bedrijfadres_startdatum <= SYSDATE AND ba.prs_bedrijfadres_type = 'G'))) LOOP fac.notifybedrijf (pbedrijf_key => bedrijfrec.prs_bedrijf_key, pbedrijfadres_type => bedrijfrec.bedrijfadres_type, prefkey => pcntkey, ptrackingkey => ptrackingkey, preference => bedrijfrec.cnt_contract_nummer_intern, pdiscipline_key => bedrijfrec.ins_discipline_key, plocatie_key => bedrijfrec.alg_locatie_key, pbedrijf_key2 => bedrijfrec.persoon_bedrijf_key, pnotidelay => pnotidelay); END LOOP; END; END cnt; / REGISTERRUN('$Id$') #endif // CNT