diff --git a/CAD/CAD_VIE.SRC b/CAD/CAD_VIE.SRC
index ceac4e33..4930b5d0 100644
--- a/CAD/CAD_VIE.SRC
+++ b/CAD/CAD_VIE.SRC
@@ -132,8 +132,8 @@ AS
COUNT (ra.prs_afdeling_key) aantal
FROM prs_v_aanwezigruimteafdeling ra, prs_v_aanwezigafdeling d
WHERE ra.prs_afdeling_key = d.prs_afdeling_key
- AND SYSDATE BETWEEN ra.prs_ruimteafdeling_ingangsdatum
- AND COALESCE (ra.prs_ruimteafdeling_einddatum, TRUNC (SYSDATE) + 1)
+ AND SYSDATE BETWEEN ra.prs_ruimteafdeling_ingangsdatum
+ AND COALESCE (ra.prs_ruimteafdeling_einddatum, TRUNC (SYSDATE) + 1)
GROUP BY ra.alg_ruimte_key) x;
// De afdelingsbezetting maar dan gebaseerd op de afdelingen
@@ -579,6 +579,7 @@ AS
-- waarde_html: van Naam [default]
-- waarde_html2: Naam
+-- Let op: er ook een cad_v_label_deel_res_datum_TZ met timezone ondersteuning. Die wordt met 2026.1 de standaard.
CREATE_VIEW(cad_v_label_deel_res_datum, 0)
(
fclt_f_datum,
@@ -673,6 +674,110 @@ AS
WHERE isd.res_ins_deel_key = res.res_ins_deel_key(+) AND datums.datum = res.datum(+)
GROUP BY datums.datum, isd.res_ins_deel_key, res_deel_omschrijving;
+-- Variant van cad_v_label_deel_res_datum met Timezone ondersteuning. Moet met 2026.1 de standaard worden
+CREATE_VIEW(cad_v_label_deel_res_datum_TZ, 0)
+(
+ fclt_f_datum,
+ ins_deel_key,
+ res_deel_omschrijving,
+ waarde1,
+ waarde,
+ waarde3,
+ waarde_html,
+ waarde_html2
+)
+AS
+ WITH
+ datums
+ AS
+ ( SELECT TRUNC (SYSDATE) + LEVEL - 1 datum
+ FROM DUAL
+ CONNECT BY LEVEL <= 42)
+ SELECT datums.datum
+ fclt_f_datum,
+ isd.res_ins_deel_key
+ ins_deel_key,
+ res_deel_omschrijving,
+ CHR (10)
+ || LISTAGG (
+ DECODE (
+ naam,
+ NULL, '',
+ '[s40]'
+ || naam
+ || ' ('
+ || TO_CHAR (localized_van, 'HH24:MI')
+ || '-'
+ || DECODE (TRUNC (localized_tot),
+ TRUNC (localized_van), TO_CHAR (localized_tot, 'HH24:MI'),
+ TO_CHAR (localized_tot, 'DD-MM-YYYY HH24:MI'))
+ || ')'),
+ CHR (10))
+ WITHIN GROUP (ORDER BY localized_van)
+ waarde1,
+ CHR (10)
+ || LISTAGG (
+ DECODE (naam,
+ NULL, '',
+ '[s40]' || TO_CHAR (localized_van, 'HH24:MI') || ' ' || naam),
+ CHR (10))
+ WITHIN GROUP (ORDER BY localized_van)
+ waarde2,
+ CHR (10)
+ || LISTAGG (DECODE (naam, NULL, '', '[s40]' || naam), CHR (10))
+ WITHIN GROUP (ORDER BY localized_van)
+ waarde3,
+ LISTAGG (
+ DECODE (
+ naam,
+ NULL, '',
+ ''
+ || TO_CHAR (localized_van, 'HH24:MI')
+ || ' '
+ || naam
+ || ''),
+ '
')
+ WITHIN GROUP (ORDER BY localized_van)
+ waarde_html,
+ LISTAGG (DECODE (naam, NULL, '', '' || naam || ''), '
')
+ WITHIN GROUP (ORDER BY localized_van)
+ waarde_html2
+ FROM res_v_aanwezigdeel isd,
+ datums,
+ (SELECT datum,
+ res_ins_deel_key,
+ DECODE (p.prs_perslid_visibility,
+ 1, pf.prs_perslid_naam_friendly,
+ a.prs_afdeling_omschrijving)
+ naam,
+ res_rsv_deel_van,
+ res_rsv_deel_tot,
+ CAST (
+ FROM_TZ (CAST (rrr.res_rsv_ruimte_van AS TIMESTAMP), fac.getsetting ('fac_server_timezone'))
+ AT TIME ZONE COALESCE (l.alg_locatie_timezone, fac.getsetting ('fac_server_timezone')) AS DATE) localized_van,
+ CAST (
+ FROM_TZ (CAST (rrr.res_rsv_ruimte_tot AS TIMESTAMP), fac.getsetting ('fac_server_timezone'))
+ AT TIME ZONE COALESCE (l.alg_locatie_timezone, fac.getsetting ('fac_server_timezone')) AS DATE) localized_tot
+ FROM res_v_aanwezigdeel r,
+ res_v_aanwezigrsv_deel rrd,
+ res_rsv_ruimte rrr,
+ alg_v_ruimte_gegevens r,
+ alg_locatie l,
+ prs_v_perslid_fullnames pf,
+ prs_perslid p,
+ prs_afdeling a,
+ datums
+ WHERE r.res_deel_key = rrd.res_deel_key
+ AND rrd.res_rsv_ruimte_key = rrr.res_rsv_ruimte_key
+ AND rrr.res_rsv_ruimte_host_key = pf.prs_perslid_key
+ AND rrr.alg_ruimte_key = r.alg_ruimte_key
+ AND r.alg_locatie_key = l.alg_locatie_key
+ AND pf.prs_perslid_key = p.prs_perslid_key
+ AND p.prs_afdeling_key = a.prs_afdeling_key
+ AND datum + 1 >= res_rsv_deel_van
+ AND datum < res_rsv_deel_tot ) res -- Bezet
+ WHERE isd.res_ins_deel_key = res.res_ins_deel_key(+) AND datums.datum = res.datum(+)
+ GROUP BY datums.datum, isd.res_ins_deel_key, res_deel_omschrijving;
--
-- Thema's gebaseerd op objectstatus van objecten binnen ruimte/werkplek (typisch sensoren)
@@ -790,6 +895,7 @@ AS
-- waarde: Voor halve dagen: Vrij(0), Ochtendbezet(1), MiddagBezet(2), Helemaalbezet(3)
-- waarde3: Voor tellen: Het aantal reservering op de dag, met 0 is dus Vrij
+-- Let op: er ook een cad_v_thema_deel_res_datum_TZ met timezone ondersteuning. Die wordt met 2026.1 de standaard.
CREATE_VIEW(cad_v_thema_deel_res_datum,0)
(
fclt_f_datum,
@@ -848,6 +954,81 @@ AS
GROUP BY datum, ins_deel_key
ORDER BY datum, ins_deel_key;
+-- Variant van cad_v_thema_deel_res_datum met Timezone ondersteuning. Moet met 2026.1 de standaard worden
+CREATE_VIEW(cad_v_thema_deel_res_datum_TZ,0)
+(
+ fclt_f_datum,
+ ins_deel_key,
+ min_van,
+ max_tot,
+ waarde1,
+ waarde,
+ waarde3
+)
+AS
+ WITH
+ datums
+ AS
+ ( SELECT TRUNC (SYSDATE) + LEVEL - 1 datum
+ FROM DUAL
+ CONNECT BY LEVEL <= 42)
+ SELECT datum -- serverdatum!
+ fclt_f_datum,
+ ins_deel_key,
+ MIN (localized_van)
+ min_van,
+ MAX (localized_tot)
+ max_tot,
+ CASE WHEN MAX (localized_tot) IS NULL THEN 0 ELSE 3 -- hele dag
+ END
+ waarde1,
+ CASE
+ WHEN MAX (localized_tot) IS NULL THEN 0
+ WHEN TO_CHAR (MAX (localized_tot), 'HH24') <= 13 THEN 1 -- ochtend
+ WHEN TO_CHAR (MIN (localized_van), 'HH24') >= 12 THEN 2 -- middag
+ ELSE 3 -- hele dag
+ END
+ waarde,
+ COUNT (localized_tot) -- aantal reservering deze dag
+ waarde3
+ FROM (SELECT datums.datum,
+ res_ins_deel_key ins_deel_key,
+ localized_van,
+ localized_tot
+ FROM res_v_aanwezigdeel r,
+ ins_deel d,
+ datums,
+ (SELECT datum,
+ res_deel_key,
+ localized_van,
+ localized_tot
+ FROM datums,
+ res_v_aanwezigrsv_deel rrd,
+ (SELECT CAST (
+ FROM_TZ (CAST (res_rsv_ruimte_van AS TIMESTAMP), fac.getsetting ('fac_server_timezone'))
+ AT TIME ZONE COALESCE(l.alg_locatie_timezone, fac.getsetting ('fac_server_timezone')) AS DATE)
+ localized_van,
+ CAST (
+ FROM_TZ (CAST (res_rsv_ruimte_tot AS TIMESTAMP), fac.getsetting ('fac_server_timezone'))
+ AT TIME ZONE COALESCE(l.alg_locatie_timezone, fac.getsetting ('fac_server_timezone')) AS DATE)
+ localized_tot,
+ res_rsv_ruimte_key
+ FROM res_rsv_ruimte rrr,
+ alg_v_ruimte_gegevens r,
+ alg_locatie l
+ WHERE rrr.alg_ruimte_key = r.alg_ruimte_key
+ AND r.alg_locatie_key = l.alg_locatie_key) rrr
+ WHERE rrd.res_rsv_ruimte_key = rrr.res_rsv_ruimte_key
+ AND res_rsv_deel_van > TRUNC (SYSDATE) - 1 -- negeer alle irrelevante historie sowieso
+ AND datum + 1 >= localized_van
+ AND datum < localized_tot) blokkerend -- vandaag en nog niet afgelopen
+ WHERE r.res_deel_key = blokkerend.res_deel_key(+)
+ AND datums.datum = blokkerend.datum(+)
+ AND (r.res_deel_vervaldatum IS NULL or r.res_deel_vervaldatum > datums.datum)
+ AND d.ins_deel_key = r.res_ins_deel_key)
+ GROUP BY datum, ins_deel_key
+ ORDER BY datum, ins_deel_key;
+
-- Paar views om de populariteit van reserveerbare objecten te kunnen illustreren
-- Basisview, met aantal per datum
@@ -860,7 +1041,7 @@ AS
FROM res_rsv_deel rrd, res_deel rd
WHERE rrd.res_deel_key = rd.res_deel_key
GROUP BY TRUNC (rrd.res_rsv_deel_van), rd.res_ins_deel_key, rd.res_deel_omschrijving;
-
+
-- Totaal gereserveerde dagen of delen daarvan in de afgelopen 1, 4 resp 8 wkn
CREATE_VIEW(cad_v_thema_deel_populair_1wkn,0)
AS
@@ -893,7 +1074,7 @@ AS
// Een basisview om sensorgemiddelde per ruimte per dag te berekenen
-// AI-generated, nog niet nageteld, maar who cares.
+// AI-generated, nog niet nageteld, maar who cares.
// Bevat alleen sensoren met niet-discrete numerieke waarden zoals temperatuur, niet bezetting
// Bevat het ruimtegemiddelde van alle sensoren van hetzelfde srtdeel gedurende de kantoortijden
CREATE_VIEW(ins_v_sensorgemiddele_per_ruimte_per_dag, 0)
diff --git a/FAC/FAC_LCL.SRC b/FAC/FAC_LCL.SRC
index be2d8dd4..50425b70 100644
--- a/FAC/FAC_LCL.SRC
+++ b/FAC/FAC_LCL.SRC
@@ -5199,6 +5199,8 @@ FAC_LCL('lcl_bes_opdracht_item', 'Bestelopdracht item', 'Purchaseorder item')
FAC_LCL('lcl_bes_opdr_kenmerk_visible', 'Ook bij de bestelopdracht tonen', 'Also visible at the purchaseorder')
FAC_LCL('lcl_bes_bestelling_item', 'Bestelitem', 'Orderitem')
FAC_LCL('lcl_bes_bestelling_items', 'Bestellijst', 'Orderlist')
+FAC_LCL('lcl_bes_fromcatalog', 'Uit catalogus', 'From catalog')
+FAC_LCL('lcl_bes_createfreely', 'Vrij aanmaken', 'Create freely')
FAC_LCL('lcl_bes_orderlist', 'Bestellijst', 'Orderlist')
FAC_LCL('lcl_bes_currentlist', 'Actuele voorraad', 'Current stock')
FAC_LCL('lcl_cad_doorvoeren', 'Doorvoeren', 'Process')
diff --git a/FAC/FAC_PAC.SRC b/FAC/FAC_PAC.SRC
index 0952867c..07efbd53 100644
--- a/FAC/FAC_PAC.SRC
+++ b/FAC/FAC_PAC.SRC
@@ -6506,7 +6506,10 @@ CREATE OR REPLACE PACKAGE BODY fac AS
AND fac_gui_counter_group <> 'audit' -- die mag je echt niet zo snel opruimen
AND prs_perslid_key IS NOT NULL;
DELETE fac_import WHERE fac_import_datum_gelezen < SYSDATE - 90;
- DELETE imp_log WHERE fac_import_key IS NULL AND imp_log_datum < SYSDATE - 90;
+ DELETE imp_log
+ WHERE fac_import_key IS NULL
+ AND imp_log_datum < SYSDATE - 90
+ AND imp_log_applicatie <> '$PURGE$'; --$PURGE$ wil je echt wel langer bewaren
DELETE fac_kenmwaarden WHERE fac_kenmwaarden_aanmaak < SYSDATE - 7;
DELETE fac_gebruikersgroep WHERE fac_gebruikersgroep_vervaldatum < TRUNC(SYSDATE);
diff --git a/FAC/FAC_PACANO.SRC b/FAC/FAC_PACANO.SRC
index c133414d..93af081a 100644
--- a/FAC/FAC_PACANO.SRC
+++ b/FAC/FAC_PACANO.SRC
@@ -1261,7 +1261,7 @@ CREATE OR REPLACE PACKAGE BODY ano AS
(SELECT prs_perslid_apikey
FROM prs_perslid
WHERE prs_perslid_oslogin = '_PUTORDERS')
- WHERE fac_setting_pvalue IS NULL
+ WHERE fac_setting_pvalue IS NOT NULL
AND fac_setting_name = 'puo_fclt_web_apikey';
DELETE FROM fac_imp_perslid;
diff --git a/FAC/FAC_PACF.SRC b/FAC/FAC_PACF.SRC
index 98eaf141..d7eebaee 100644
--- a/FAC/FAC_PACF.SRC
+++ b/FAC/FAC_PACF.SRC
@@ -15976,10 +15976,11 @@ AS
-- - An optional prefix of up to 3 letters,
-- - Followed by 1 to 10 digits,
-- - Optionally followed by a slash and a sequence number (e.g., ST0123456/2).
+ -- Note: NOT used for contract id's. They are freeform.
-- Examples:
- -- 'C12345 Somecomments' -> 'C12345'
- -- 'Sometext C12345' -> 'C12345'
- -- 'SometextC12345' -> 'xtC12345' (!)
+ -- 'M12345 Somecomments' -> 'M12345'
+ -- 'Sometext M12345' -> 'M12345'
+ -- 'SometextM12345' -> 'xtM12345' (!)
-- 'ST0123456/2 extra' -> 'ST0123456/2'
FUNCTION sanitizereferentiestring (p_broc_nr IN VARCHAR2)
RETURN VARCHAR2
@@ -15987,7 +15988,7 @@ AS
cleaner_broc_nr fac_imp_factuur.ordernr%TYPE;
BEGIN
-- Extract pattern: up to 3 letters, 1-10 digits, optional /digits
- cleaner_broc_nr := REGEXP_SUBSTR (p_broc_nr, '([A-Za-z]{0,3}\d{1,10}(\/\d+)?)', 1);
+ cleaner_broc_nr := REGEXP_SUBSTR (p_broc_nr, fac.getsetting('fin_factuur_import_sanitize_id'), 1); -- default'([A-Za-z]{0,3}\d{1,10}(\/\d+)?)'
IF cleaner_broc_nr IS NULL
THEN
cleaner_broc_nr := p_broc_nr;
@@ -16031,19 +16032,22 @@ AS
p_ckey:=NULL;
p_okey:=NULL;
p_bkey:=NULL;
- sanitized_broc_nr := sanitizereferentiestring (p_broc_nr);
- IF LENGTH (sanitized_broc_nr) > 0
+ IF LENGTH (p_broc_nr) > 0
THEN
- p_ckey := try_getcontract_id (sanitized_broc_nr, p_leverancier_nr, p_factuur_datum);
+ p_ckey := try_getcontract_id (p_broc_nr, p_leverancier_nr, p_factuur_datum); -- Unsanitized p_broc_nr!
IF p_ckey IS NULL
THEN
- p_okey := try_getopdracht_id (sanitized_broc_nr, p_leverancier_nr);
- IF p_okey IS NULL
+ sanitized_broc_nr := sanitizereferentiestring (p_broc_nr);
+ IF LENGTH (sanitized_broc_nr) > 0
THEN
- p_bkey := try_getbestelling_id (sanitized_broc_nr, p_leverancier_nr);
+ p_okey := try_getopdracht_id (sanitized_broc_nr, p_leverancier_nr);
+ IF p_okey IS NULL
+ THEN
+ p_bkey := try_getbestelling_id (sanitized_broc_nr, p_leverancier_nr);
+ END IF;
END IF;
END IF;
- END IF;
+ END IF;
END;
FUNCTION try_getkostensoort (p_ckey IN NUMBER, p_okey IN NUMBER, p_bkey IN NUMBER)
diff --git a/FAC/FAC_SET.SRC b/FAC/FAC_SET.SRC
index 8d9fbd29..7be261aa 100644
--- a/FAC/FAC_SET.SRC
+++ b/FAC/FAC_SET.SRC
@@ -576,6 +576,7 @@ DEFINE_SETTING('FIN', 0001, 'WEB_PRSSYS', 'fin_factuur_flags'
DEFINE_SETTING('FIN', 0001, 'WEB_PRSSYS', 'fin_factuur_flags_list_usage' , 'number' , '0' , 'Set rights that readonly can/cannot edit markings (bolletjes) toe {0=no | 1=yes}')
DEFINE_SETTING('FIN', 0001, 'WEB_PRSSYS', 'fin_factuur_verlegdmode' , 'number' , '0' , 'Use and validation of field fin_factuur_gbedrag: {0=field invisible | &1=visible and enterable | &2=required if invoicelines has a shifted VAT-value | &4=all invoicelines must have shifted VAT-value or must have standard VAT values (=not shifted)}')
DEFINE_SETTING('FIN', 0001, 'WEB_PRSSYS', 'fin_kostensoort_verplicht' , 'number' , '0' , 'Is kostensoort required? {0=not required | 1=required}')
+DEFINE_SETTING('FIN', 0001, 'WEB_PRSSYS', 'fin_factuur_import_sanitize_id' , 'string' , '([A-Za-z]{0,3}\d{1,10}(\/\d+)?)', 'Regexp for sanitizing imported invoice ID''s (removes unwanted characters)')
DEFINE_SETTING('FIN', 0001, 'WEB_PRSSYS', 'fin_match_lowerlimit' , 'number' , '0' , 'Check lowerlimit also for matching {0=Only upperlimit (invoice