@flowselections/floriday-voorraad 1.0.139 → 1.0.143

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist-lib/components/voorraad/NieuwArtikelPage.d.ts.map +1 -1
  2. package/dist-lib/components/voorraad/NieuwArtikelPage.js +22 -3
  3. package/dist-lib/components/voorraad/StockMutationHistoryCard.d.ts.map +1 -1
  4. package/dist-lib/components/voorraad/StockMutationHistoryCard.js +3 -2
  5. package/dist-lib/components/voorraad/VoorraadPage.d.ts.map +1 -1
  6. package/dist-lib/components/voorraad/VoorraadPage.js +2 -0
  7. package/dist-lib/components/voorraad/VoorraadStockCard.d.ts.map +1 -1
  8. package/dist-lib/components/voorraad/VoorraadStockCard.js +28 -60
  9. package/dist-lib/hooks/useEnsureVoorraadDefaults.d.ts +7 -0
  10. package/dist-lib/hooks/useEnsureVoorraadDefaults.d.ts.map +1 -0
  11. package/dist-lib/hooks/useEnsureVoorraadDefaults.js +25 -0
  12. package/dist-lib/hooks/useTradeItemStock.d.ts +4 -1
  13. package/dist-lib/hooks/useTradeItemStock.d.ts.map +1 -1
  14. package/dist-lib/hooks/useTradeItemStock.js +31 -44
  15. package/dist-lib/integrations/supabase/types.d.ts +421 -0
  16. package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
  17. package/dist-lib/lib/__tests__/release-140.test.d.ts +2 -0
  18. package/dist-lib/lib/__tests__/release-140.test.d.ts.map +1 -0
  19. package/dist-lib/lib/__tests__/release-140.test.js +42 -0
  20. package/dist-lib/lib/db-error-message.d.ts +7 -0
  21. package/dist-lib/lib/db-error-message.d.ts.map +1 -0
  22. package/dist-lib/lib/db-error-message.js +36 -0
  23. package/dist-lib/lib/engine-carrier.d.ts +15 -0
  24. package/dist-lib/lib/engine-carrier.d.ts.map +1 -0
  25. package/dist-lib/lib/engine-carrier.js +27 -0
  26. package/dist-lib/lib/simple-packing.d.ts +2 -4
  27. package/dist-lib/lib/simple-packing.d.ts.map +1 -1
  28. package/dist-lib/lib/simple-packing.js +5 -12
  29. package/dist-lib/lib/stock-save.d.ts +11 -0
  30. package/dist-lib/lib/stock-save.d.ts.map +1 -1
  31. package/dist-lib/lib/stock-save.js +17 -0
  32. package/package.json +4 -2
  33. package/sql/AGENTS.md +4 -0
  34. package/sql/floriday-voorraad-schema.sql +441 -82
@@ -1,4 +1,5 @@
1
- -- @flowselections/floriday-voorraad 1.0.136 – volledig schema (idempotent, geen gegevens).
1
+ -- @flowselections/floriday-voorraad 1.0.142 – volledig schema (idempotent, geen gegevens).
2
+ -- Laatste migratie: 20261102125718_08100bc6-2bc9-4905-9e62-4c7aca9ce3ff.sql
2
3
  -- Gegenereerd uit de database met scripts/generate-voorraad-schema.py. Niet met de hand wijzigen.
3
4
  -- Volgorde 20. Ontbrekende tabellen van andere modules worden overgeslagen met een NOTICE; draai opnieuw na die module.
4
5
  -- De statuscontrole van floriday_continuous_stock_queue is van Voorraad en wordt hier opnieuw gemaakt.
@@ -530,6 +531,13 @@ ALTER TABLE public.voorraad_custom_fields ADD COLUMN IF NOT EXISTS sort_order in
530
531
  ALTER TABLE public.voorraad_custom_fields ADD COLUMN IF NOT EXISTS created_at timestamp with time zone DEFAULT now() NOT NULL;
531
532
  ALTER TABLE public.voorraad_custom_fields ADD COLUMN IF NOT EXISTS updated_at timestamp with time zone DEFAULT now() NOT NULL;
532
533
 
534
+ -- voorraad_defaults_state
535
+ CREATE TABLE IF NOT EXISTS public.voorraad_defaults_state ();
536
+ ALTER TABLE public.voorraad_defaults_state ADD COLUMN IF NOT EXISTS id boolean DEFAULT true NOT NULL;
537
+ ALTER TABLE public.voorraad_defaults_state ADD COLUMN IF NOT EXISTS versie integer NOT NULL;
538
+ ALTER TABLE public.voorraad_defaults_state ADD COLUMN IF NOT EXISTS toegepast_at timestamp with time zone DEFAULT now() NOT NULL;
539
+ ALTER TABLE public.voorraad_defaults_state ADD COLUMN IF NOT EXISTS resultaat jsonb DEFAULT '{}'::jsonb NOT NULL;
540
+
533
541
  -- voorraad_load_carrier_types
534
542
  CREATE TABLE IF NOT EXISTS public.voorraad_load_carrier_types ();
535
543
  ALTER TABLE public.voorraad_load_carrier_types ADD COLUMN IF NOT EXISTS code text NOT NULL;
@@ -537,6 +545,8 @@ ALTER TABLE public.voorraad_load_carrier_types ADD COLUMN IF NOT EXISTS naam tex
537
545
  ALTER TABLE public.voorraad_load_carrier_types ADD COLUMN IF NOT EXISTS volgorde integer NOT NULL;
538
546
  ALTER TABLE public.voorraad_load_carrier_types ADD COLUMN IF NOT EXISTS created_at timestamp with time zone DEFAULT now() NOT NULL;
539
547
  ALTER TABLE public.voorraad_load_carrier_types ADD COLUMN IF NOT EXISTS updated_at timestamp with time zone DEFAULT now() NOT NULL;
548
+ ALTER TABLE public.voorraad_load_carrier_types ADD COLUMN IF NOT EXISTS actief boolean DEFAULT true NOT NULL;
549
+ ALTER TABLE public.voorraad_load_carrier_types ADD COLUMN IF NOT EXISTS naam_aangepast boolean DEFAULT false NOT NULL;
540
550
 
541
551
  -- voorraad_local_context
542
552
  CREATE TABLE IF NOT EXISTS public.voorraad_local_context ();
@@ -2258,6 +2268,7 @@ AS $function$
2258
2268
  DECLARE n integer := 0; v_batch int;
2259
2269
  BEGIN
2260
2270
  PERFORM public.voorraad_vereis('server', 'drain_inventory_recompute_queue');
2271
+ BEGIN PERFORM public.voorraad_ensure_defaults(); EXCEPTION WHEN others THEN NULL; END;
2261
2272
  SELECT drain_batch INTO v_batch FROM public.inventory_recompute_limits WHERE id;
2262
2273
  PERFORM set_config('inventory.inline_overflow', '0', true);
2263
2274
  n := public.process_inventory_recompute_queue(COALESCE(v_batch, 500));
@@ -2291,7 +2302,6 @@ BEGIN
2291
2302
  RETURN NEW;
2292
2303
  END IF;
2293
2304
 
2294
- -- Alleen gekoppelde artikelen: Floriday-id op het artikel, of bekend in de Floriday-cache.
2295
2305
  SELECT p.id INTO v_pid FROM public.products p WHERE p.floriday_trade_item_id = NEW.trade_item_key LIMIT 1;
2296
2306
  IF v_pid IS NULL AND NOT EXISTS (
2297
2307
  SELECT 1 FROM public.floriday_trade_items_cache c
@@ -2300,21 +2310,30 @@ BEGIN
2300
2310
  RETURN NEW;
2301
2311
  END IF;
2302
2312
 
2303
- UPDATE public.floriday_continuous_stock_queue q
2304
- SET status = 'superseded', updated_at = now()
2305
- WHERE q.connection_id = NEW.connection_id
2306
- AND q.trade_item_id = v_uuid
2307
- AND q.status = 'pending'
2308
- AND q.target_year IS NULL
2309
- AND q.target_week IS NULL;
2310
-
2311
- INSERT INTO public.floriday_continuous_stock_queue (
2312
- user_id, connection_id, trade_item_id, product_id, number_of_pieces,
2313
- desired_available, status, next_attempt_at
2314
- ) VALUES (
2315
- NEW.user_id, NEW.connection_id, v_uuid, v_pid, COALESCE(NEW.physical_stock, 0),
2316
- COALESCE(NEW.physical_stock, 0) > 0, 'pending', now()
2317
- );
2313
+ -- Lokaal opslaan hangt nooit af van de Floriday-poort: dicht = niets klaarzetten.
2314
+ IF NOT public.voorraad_floriday_klaarzetten_toegestaan() THEN
2315
+ RETURN NEW;
2316
+ END IF;
2317
+
2318
+ BEGIN
2319
+ UPDATE public.floriday_continuous_stock_queue q
2320
+ SET status = 'superseded', updated_at = now()
2321
+ WHERE q.connection_id = NEW.connection_id
2322
+ AND q.trade_item_id = v_uuid
2323
+ AND q.status = 'pending'
2324
+ AND q.target_year IS NULL
2325
+ AND q.target_week IS NULL;
2326
+
2327
+ INSERT INTO public.floriday_continuous_stock_queue (
2328
+ user_id, connection_id, trade_item_id, product_id, number_of_pieces,
2329
+ desired_available, status, next_attempt_at
2330
+ ) VALUES (
2331
+ NEW.user_id, NEW.connection_id, v_uuid, v_pid, COALESCE(NEW.physical_stock, 0),
2332
+ COALESCE(NEW.physical_stock, 0) > 0, 'pending', now()
2333
+ );
2334
+ EXCEPTION WHEN OTHERS THEN
2335
+ RAISE WARNING '[voorraad] niet klaargezet voor Floriday: %', SQLERRM;
2336
+ END;
2318
2337
 
2319
2338
  RETURN NEW;
2320
2339
  END;
@@ -2343,27 +2362,23 @@ BEGIN
2343
2362
  RETURN NEW;
2344
2363
  END;
2345
2364
 
2346
- IF TG_OP = 'UPDATE'
2347
- AND NEW.warehouse_id IS NOT DISTINCT FROM OLD.warehouse_id THEN
2365
+ IF TG_OP = 'UPDATE' AND NEW.warehouse_id IS NOT DISTINCT FROM OLD.warehouse_id THEN
2348
2366
  RETURN NEW;
2349
2367
  END IF;
2350
2368
 
2351
- INSERT INTO public.floriday_continuous_stock_queue (
2352
- user_id,
2353
- connection_id,
2354
- trade_item_id,
2355
- number_of_pieces,
2356
- status
2357
- )
2358
- SELECT
2359
- s.user_id,
2360
- s.connection_id,
2361
- v_trade_item_uuid,
2362
- s.physical_stock,
2363
- 'pending'
2364
- FROM public.trade_item_stock s
2365
- WHERE s.connection_id = NEW.connection_id
2366
- AND s.trade_item_key = NEW.trade_item_id;
2369
+ IF NOT public.voorraad_floriday_klaarzetten_toegestaan() THEN
2370
+ RETURN NEW;
2371
+ END IF;
2372
+
2373
+ BEGIN
2374
+ INSERT INTO public.floriday_continuous_stock_queue (user_id, connection_id, trade_item_id, number_of_pieces, status)
2375
+ SELECT s.user_id, s.connection_id, v_trade_item_uuid, s.physical_stock, 'pending'
2376
+ FROM public.trade_item_stock s
2377
+ WHERE s.connection_id = NEW.connection_id
2378
+ AND s.trade_item_key = NEW.trade_item_id;
2379
+ EXCEPTION WHEN OTHERS THEN
2380
+ RAISE WARNING '[voorraad] niet klaargezet voor Floriday: %', SQLERRM;
2381
+ END;
2367
2382
 
2368
2383
  RETURN NEW;
2369
2384
  END;
@@ -3582,21 +3597,26 @@ BEGIN
3582
3597
  WHERE id = s.id;
3583
3598
 
3584
3599
  IF NOT v_changed OR v_item IS NULL THEN RETURN; END IF;
3600
+ IF NOT public.voorraad_floriday_klaarzetten_toegestaan() THEN RETURN; END IF;
3585
3601
 
3586
- FOR v_offset IN 0..v_horizon LOOP
3587
- v_date := ((now() AT TIME ZONE 'Europe/Amsterdam')::date + (v_offset * 7));
3588
- v_year := to_char(v_date, 'IYYY')::int;
3589
- v_week := to_char(v_date, 'IW')::int;
3590
- UPDATE public.floriday_continuous_stock_queue q
3591
- SET status = 'superseded', updated_at = now()
3592
- WHERE q.connection_id = p_connection_id AND q.trade_item_id = v_item
3593
- AND q.status = 'pending' AND q.target_year = v_year AND q.target_week = v_week;
3594
- INSERT INTO public.floriday_continuous_stock_queue (
3595
- user_id, connection_id, trade_item_id, product_id, number_of_pieces, desired_available,
3596
- stock_mode, target_year, target_week, status, next_attempt_at
3597
- ) VALUES (v_user, p_connection_id, v_item, p_product_id, calc.desired_quantity, calc.desired_availability,
3598
- calc.stock_mode, v_year, v_week, 'pending', now());
3599
- END LOOP;
3602
+ BEGIN
3603
+ FOR v_offset IN 0..v_horizon LOOP
3604
+ v_date := ((now() AT TIME ZONE 'Europe/Amsterdam')::date + (v_offset * 7));
3605
+ v_year := to_char(v_date, 'IYYY')::int;
3606
+ v_week := to_char(v_date, 'IW')::int;
3607
+ UPDATE public.floriday_continuous_stock_queue q
3608
+ SET status = 'superseded', updated_at = now()
3609
+ WHERE q.connection_id = p_connection_id AND q.trade_item_id = v_item
3610
+ AND q.status = 'pending' AND q.target_year = v_year AND q.target_week = v_week;
3611
+ INSERT INTO public.floriday_continuous_stock_queue (
3612
+ user_id, connection_id, trade_item_id, product_id, number_of_pieces, desired_available,
3613
+ stock_mode, target_year, target_week, status, next_attempt_at
3614
+ ) VALUES (v_user, p_connection_id, v_item, p_product_id, calc.desired_quantity, calc.desired_availability,
3615
+ calc.stock_mode, v_year, v_week, 'pending', now());
3616
+ END LOOP;
3617
+ EXCEPTION WHEN OTHERS THEN
3618
+ RAISE WARNING '[voorraad] niet klaargezet voor Floriday: %', SQLERRM;
3619
+ END;
3600
3620
  END;
3601
3621
  $function$
3602
3622
  ;
@@ -4915,6 +4935,7 @@ DECLARE
4915
4935
  v_frozen_ids uuid[];
4916
4936
  BEGIN
4917
4937
  PERFORM public.voorraad_vereis('ingelogd', 'recompute_all_reserved_stock');
4938
+ BEGIN PERFORM public.voorraad_ensure_defaults(); EXCEPTION WHEN others THEN NULL; END;
4918
4939
  IF current_setting('app.recomputing_reserved', true) = 'on' THEN RETURN; END IF;
4919
4940
  PERFORM set_config('app.recomputing_reserved', 'on', true);
4920
4941
 
@@ -5944,6 +5965,7 @@ AS $function$
5944
5965
  #variable_conflict use_column
5945
5966
  DECLARE
5946
5967
  v_user_id uuid := auth.uid(); v_ctx record; v_connection_id uuid; v_key text; v_row_key text; v_product_key text; v_floriday_key text; v_source text;
5968
+ v_keep boolean := COALESCE(current_setting('stock.keep_notes', true), '') = '1';
5947
5969
  BEGIN
5948
5970
  PERFORM public.voorraad_vereis('ingelogd', 'set_product_stock');
5949
5971
  IF v_user_id IS NULL THEN RAISE EXCEPTION 'Niet ingelogd' USING ERRCODE = '42501'; END IF;
@@ -5951,8 +5973,7 @@ BEGIN
5951
5973
  IF p_physical_stock < 0 OR p_minimum_stock < 0 OR p_incoming_stock < 0 THEN
5952
5974
  RAISE EXCEPTION 'Voorraadaantallen mogen niet negatief zijn'; END IF;
5953
5975
  IF p_change_source IS NOT NULL AND btrim(p_change_source) <> '' THEN
5954
- IF btrim(p_change_source) !~ '^[A-Za-z_]{2,64}$' THEN
5955
- RAISE EXCEPTION 'Ongeldige bronaanduiding'; END IF;
5976
+ IF btrim(p_change_source) !~ '^[A-Za-z_]{2,64}$' THEN RAISE EXCEPTION 'Ongeldige bronaanduiding'; END IF;
5956
5977
  v_source := btrim(p_change_source);
5957
5978
  PERFORM set_config('stock.change_source', v_source, true);
5958
5979
  END IF;
@@ -5960,27 +5981,22 @@ BEGIN
5960
5981
  INTO v_floriday_key, v_product_key FROM public.products p WHERE p.id = p_product_id;
5961
5982
  IF NOT FOUND THEN RAISE EXCEPTION 'Product niet gevonden'; END IF;
5962
5983
  v_key := COALESCE(v_product_key, v_floriday_key, 'product:' || p_product_id::text);
5963
-
5964
- -- Context: Floriday-koppeling (omgeving, anders de enige actieve) of de lokale context.
5965
5984
  SELECT * INTO v_ctx FROM public.get_stock_context(true);
5966
5985
  v_connection_id := v_ctx.connection_id;
5967
5986
  IF v_connection_id IS NULL THEN RAISE EXCEPTION 'Geen voorraadcontext beschikbaar' USING ERRCODE = 'VR004'; END IF;
5968
-
5969
5987
  SELECT s.trade_item_key INTO v_row_key FROM public.trade_item_stock s
5970
5988
  WHERE s.connection_id = v_connection_id
5971
5989
  AND s.trade_item_key IN (v_key, v_floriday_key, v_product_key, 'product:' || p_product_id::text, p_product_id::text)
5972
5990
  ORDER BY CASE WHEN s.trade_item_key = v_key THEN 0 ELSE 1 END, s.updated_at DESC NULLS LAST LIMIT 1;
5973
5991
  v_row_key := COALESCE(v_row_key, v_key);
5974
-
5975
5992
  INSERT INTO public.trade_item_stock AS t (user_id, connection_id, trade_item_key, physical_stock, minimum_stock, reserved_stock, incoming_stock, notes, change_source)
5976
5993
  VALUES (v_user_id, v_connection_id, v_row_key, p_physical_stock, COALESCE(p_minimum_stock, 0), 0, COALESCE(p_incoming_stock, 0), p_notes, COALESCE(v_source, 'MANUAL_STOCK'))
5977
5994
  ON CONFLICT (connection_id, trade_item_key) DO UPDATE
5978
5995
  SET physical_stock = EXCLUDED.physical_stock,
5979
5996
  minimum_stock = COALESCE(p_minimum_stock, t.minimum_stock, 0),
5980
5997
  incoming_stock = COALESCE(p_incoming_stock, t.incoming_stock, 0),
5981
- notes = EXCLUDED.notes, updated_at = now(),
5998
+ notes = CASE WHEN v_keep THEN t.notes ELSE EXCLUDED.notes END, updated_at = now(),
5982
5999
  change_source = COALESCE(v_source, t.change_source);
5983
-
5984
6000
  RETURN QUERY
5985
6001
  SELECT p_product_id, s.connection_id, s.trade_item_key, s.physical_stock::numeric, s.minimum_stock::numeric,
5986
6002
  s.reserved_stock::numeric, s.incoming_stock::numeric, s.notes, s.updated_at
@@ -6055,7 +6071,7 @@ BEGIN
6055
6071
  v_user := COALESCE(v_uid, v_ctx.user_id);
6056
6072
  SELECT import_chunk_size, import_new_chunk_size, import_max_rows, import_max_bytes INTO l FROM public.inventory_recompute_limits WHERE id;
6057
6073
  v_cs := GREATEST(COALESCE(l.import_chunk_size, 200), 1);
6058
- v_ncs := LEAST(GREATEST(COALESCE(l.import_new_chunk_size, 40), 1), v_cs);
6074
+ v_ncs := LEAST(GREATEST(COALESCE(l.import_new_chunk_size, 20), 1), v_cs);
6059
6075
  IF p_rows IS NULL OR jsonb_typeof(p_rows) <> 'array' OR jsonb_array_length(p_rows) = 0 THEN
6060
6076
  RETURN jsonb_build_object('ok', false, 'code', 'IMPORT_EMPTY', 'message', 'Het bestand bevat geen rijen.');
6061
6077
  END IF;
@@ -7077,6 +7093,8 @@ AS $function$
7077
7093
  DECLARE v_ctx record;
7078
7094
  BEGIN
7079
7095
  BEGIN
7096
+ IF NOT public.voorraad_floriday_klaarzetten_toegestaan() THEN RETURN NULL; END IF;
7097
+
7080
7098
  CREATE TEMP TABLE IF NOT EXISTS _link_enq (product_id uuid, fid uuid, connection_id uuid, user_id uuid, pieces int) ON COMMIT DROP;
7081
7099
  DELETE FROM _link_enq WHERE product_id IS NOT NULL OR product_id IS NULL;
7082
7100
 
@@ -7513,7 +7531,7 @@ CREATE OR REPLACE FUNCTION public.trg_trade_item_stock_log_change()
7513
7531
  SET search_path TO 'public'
7514
7532
  AS $function$
7515
7533
  DECLARE
7516
- v_src text; v_tx text; v_handled text;
7534
+ v_src text; v_tx text; v_handled text; v_note text;
7517
7535
  v_phys_before numeric := CASE WHEN TG_OP = 'UPDATE' THEN COALESCE(OLD.physical_stock, 0) ELSE 0 END;
7518
7536
  v_res_before numeric := CASE WHEN TG_OP = 'UPDATE' THEN COALESCE(OLD.reserved_stock, 0) ELSE 0 END;
7519
7537
  v_inc_before numeric := CASE WHEN TG_OP = 'UPDATE' THEN COALESCE(OLD.incoming_stock, 0) ELSE 0 END;
@@ -7524,33 +7542,23 @@ DECLARE
7524
7542
  BEGIN
7525
7543
  IF NEW.trade_item_key IS NULL OR NEW.trade_item_key = '' THEN RETURN NULL; END IF;
7526
7544
  IF v_phys_before = v_phys_after AND v_res_before = v_res_after AND v_inc_before = v_inc_after THEN RETURN NULL; END IF;
7527
-
7528
7545
  v_handled := COALESCE(current_setting('stock.log_handled', true), '');
7529
7546
  IF v_handled <> '' AND position(';' || NEW.connection_id || '|' || NEW.trade_item_key || '|' || v_phys_after || '|' || v_res_after || ';' IN v_handled) > 0 THEN
7530
7547
  RETURN NULL;
7531
7548
  END IF;
7532
-
7533
- IF TG_OP = 'INSERT' OR NEW.change_source IS DISTINCT FROM OLD.change_source THEN
7534
- v_src := COALESCE(NEW.change_source, '');
7535
- ELSE
7536
- v_src := '';
7537
- END IF;
7549
+ IF TG_OP = 'INSERT' OR NEW.change_source IS DISTINCT FROM OLD.change_source THEN v_src := COALESCE(NEW.change_source, '');
7550
+ ELSE v_src := ''; END IF;
7538
7551
  IF v_src = '' THEN
7539
7552
  BEGIN v_tx := btrim(COALESCE(current_setting('stock.change_source', true), ''));
7540
7553
  EXCEPTION WHEN others THEN v_tx := ''; END;
7541
7554
  IF v_tx ~ '^[A-Za-z_]{2,64}$' THEN v_src := v_tx; END IF;
7542
7555
  END IF;
7543
-
7544
7556
  IF v_phys_before = v_phys_after AND EXISTS (
7545
7557
  SELECT 1 FROM public.stock_mutation_log l
7546
- WHERE l.trade_item_key = NEW.trade_item_key
7547
- AND l.created_at >= now() - interval '30 seconds'
7548
- AND COALESCE(l.physical_after, 0) = v_phys_after
7549
- AND COALESCE(l.reserved_after, 0) = v_res_after
7558
+ WHERE l.trade_item_key = NEW.trade_item_key AND l.created_at >= now() - interval '30 seconds'
7559
+ AND COALESCE(l.physical_after, 0) = v_phys_after AND COALESCE(l.reserved_after, 0) = v_res_after
7550
7560
  ) THEN RETURN NULL; END IF;
7551
-
7552
7561
  v_delta := CASE WHEN v_phys_after <> v_phys_before THEN v_phys_after - v_phys_before ELSE v_res_after - v_res_before END;
7553
-
7554
7562
  IF v_src = '' THEN v_type := 'unknown'; v_reason := 'Bron onbekend';
7555
7563
  ELSIF v_src = 'NEW_ARTICLE' THEN v_type := 'new_article'; v_reason := 'Nieuw artikel';
7556
7564
  ELSIF v_src = 'RESERVATION_RECOMPUTE' THEN v_type := 'reservation_recompute'; v_reason := 'Reservering herberekend van ' || v_res_before || ' naar ' || v_res_after;
@@ -7564,9 +7572,9 @@ BEGIN
7564
7572
  v_reason := v_reason || ' — reservering van ' || v_res_before || ' naar ' || v_res_after; END IF;
7565
7573
  IF v_phys_after <> v_phys_before THEN v_reason := v_reason || ' — fysiek van ' || v_phys_before || ' naar ' || v_phys_after; END IF;
7566
7574
  IF v_inc_after <> v_inc_before THEN v_reason := v_reason || ' — inkomend van ' || v_inc_before || ' naar ' || v_inc_after; END IF;
7567
- IF v_src <> 'NEW_ARTICLE' AND COALESCE(NEW.notes, '') <> '' AND (TG_OP = 'INSERT' OR NEW.notes IS DISTINCT FROM OLD.notes) THEN
7568
- v_reason := v_reason || ' — notitie: ' || NEW.notes; END IF;
7569
-
7575
+ BEGIN v_note := btrim(COALESCE(current_setting('stock.change_note', true), ''));
7576
+ EXCEPTION WHEN others THEN v_note := ''; END;
7577
+ IF v_note <> '' THEN v_reason := v_reason || ' — notitie: ' || left(v_note, 500); END IF;
7570
7578
  INSERT INTO public.stock_mutation_log(trade_item_key, connection_id, mutation_type, qty_delta,
7571
7579
  physical_before, physical_after, reserved_before, reserved_after, reason, created_by)
7572
7580
  VALUES (NEW.trade_item_key, NEW.connection_id, v_type, v_delta,
@@ -7747,6 +7755,67 @@ REVOKE ALL ON FUNCTION voorraad_active_fust_id(text,uuid) FROM PUBLIC;
7747
7755
  REVOKE ALL ON FUNCTION voorraad_active_fust_id(text,uuid) FROM anon;
7748
7756
  GRANT EXECUTE ON FUNCTION voorraad_active_fust_id(text,uuid) TO authenticated;
7749
7757
  GRANT EXECUTE ON FUNCTION voorraad_active_fust_id(text,uuid) TO service_role;
7758
+ CREATE OR REPLACE FUNCTION public.voorraad_afboeken(p_connection_id uuid, p_trade_item_key text, p_aantal numeric, p_reden text, p_notitie text DEFAULT NULL::text)
7759
+ RETURNS jsonb
7760
+ LANGUAGE plpgsql
7761
+ SECURITY DEFINER
7762
+ SET search_path TO 'public'
7763
+ AS $function$
7764
+ DECLARE
7765
+ r public.trade_item_stock%ROWTYPE;
7766
+ v_label text;
7767
+ v_after numeric;
7768
+ BEGIN
7769
+ PERFORM public.voorraad_vereis('ingelogd', 'voorraad_afboeken');
7770
+ IF NOT public.voorraad_can_write() THEN
7771
+ RAISE EXCEPTION 'Je hebt geen schrijfrechten op de voorraad.' USING ERRCODE = '42501';
7772
+ END IF;
7773
+ v_label := CASE p_reden WHEN 'derving' THEN 'derving' WHEN 'kapot' THEN 'kapot'
7774
+ WHEN 'eigen_gebruik' THEN 'eigen gebruik' WHEN 'overig' THEN 'overig' END;
7775
+ IF v_label IS NULL THEN
7776
+ RAISE EXCEPTION 'Kies een reden: derving, kapot, eigen gebruik of overig.' USING ERRCODE = '22023';
7777
+ END IF;
7778
+ IF p_aantal IS NULL OR p_aantal <= 0 THEN
7779
+ RAISE EXCEPTION 'Vul een aantal groter dan 0 in.' USING ERRCODE = '22023';
7780
+ END IF;
7781
+
7782
+ SELECT * INTO r FROM public.trade_item_stock
7783
+ WHERE connection_id IS NOT DISTINCT FROM p_connection_id AND trade_item_key = p_trade_item_key
7784
+ ORDER BY id FOR UPDATE;
7785
+ IF r.id IS NULL THEN
7786
+ RAISE EXCEPTION 'Geen voorraadregel gevonden voor dit artikel.' USING ERRCODE = 'P0002';
7787
+ END IF;
7788
+ IF p_aantal > COALESCE(r.physical_stock, 0) THEN
7789
+ RAISE EXCEPTION 'Je kunt niet meer afboeken (%) dan er ligt (%).', p_aantal, COALESCE(r.physical_stock,0) USING ERRCODE = '22023';
7790
+ END IF;
7791
+ v_after := COALESCE(r.physical_stock, 0) - p_aantal;
7792
+
7793
+ -- Eigen logregel; de algemene logtrigger slaat deze wijziging over.
7794
+ PERFORM set_config('stock.log_handled',
7795
+ COALESCE(current_setting('stock.log_handled', true), '') || ';' || r.connection_id || '|' || r.trade_item_key || '|' || v_after || '|' || COALESCE(r.reserved_stock,0) || ';', true);
7796
+ PERFORM set_config('stock.change_source', 'MANUAL_WRITEOFF', true);
7797
+
7798
+ UPDATE public.trade_item_stock SET physical_stock = v_after, updated_at = now() WHERE id = r.id;
7799
+
7800
+ INSERT INTO public.stock_mutation_log(trade_item_key, connection_id, mutation_type, qty_delta,
7801
+ physical_before, physical_after, reserved_before, reserved_after, reason, created_by)
7802
+ VALUES (r.trade_item_key, r.connection_id, 'manual_writeoff', -p_aantal,
7803
+ r.physical_stock, v_after, r.reserved_stock, r.reserved_stock,
7804
+ 'Afgeboekt: ' || v_label || ' — fysiek van ' || COALESCE(r.physical_stock,0) || ' naar ' || v_after
7805
+ || CASE WHEN COALESCE(btrim(p_notitie),'') <> '' THEN ' — notitie: ' || btrim(p_notitie) ELSE '' END,
7806
+ auth.uid());
7807
+
7808
+ RETURN jsonb_build_object('physical_before', r.physical_stock, 'physical_after', v_after, 'reden', p_reden);
7809
+ END $function$
7810
+ ;
7811
+ REVOKE ALL ON FUNCTION voorraad_afboeken(uuid,text,numeric,text,text) FROM PUBLIC;
7812
+ REVOKE ALL ON FUNCTION voorraad_afboeken(uuid,text,numeric,text,text) FROM anon;
7813
+ REVOKE EXECUTE ON FUNCTION voorraad_afboeken(uuid,text,numeric,text,text) FROM PUBLIC;
7814
+ GRANT EXECUTE ON FUNCTION voorraad_afboeken(uuid,text,numeric,text,text) TO authenticated;
7815
+ GRANT EXECUTE ON FUNCTION voorraad_afboeken(uuid,text,numeric,text,text) TO service_role;
7816
+ REVOKE EXECUTE ON FUNCTION voorraad_afboeken(uuid,text,numeric,text,text) FROM anon;
7817
+ GRANT EXECUTE ON FUNCTION voorraad_afboeken(uuid,text,numeric,text,text) TO authenticated;
7818
+ GRANT EXECUTE ON FUNCTION voorraad_afboeken(uuid,text,numeric,text,text) TO service_role;
7750
7819
  CREATE OR REPLACE FUNCTION public.voorraad_alert_floriday_not_updated(p_key text, p_qty numeric, p_order_id uuid, p_order_item_id uuid)
7751
7820
  RETURNS void
7752
7821
  LANGUAGE plpgsql
@@ -8822,6 +8891,40 @@ GRANT EXECUTE ON FUNCTION voorraad_correctie_1136(boolean) TO service_role;
8822
8891
  REVOKE EXECUTE ON FUNCTION voorraad_correctie_1136(boolean) FROM anon;
8823
8892
  GRANT EXECUTE ON FUNCTION voorraad_correctie_1136(boolean) TO authenticated;
8824
8893
  GRANT EXECUTE ON FUNCTION voorraad_correctie_1136(boolean) TO service_role;
8894
+ CREATE OR REPLACE FUNCTION public.voorraad_correctie_1140(p_uitvoeren boolean DEFAULT false)
8895
+ RETURNS jsonb
8896
+ LANGUAGE plpgsql
8897
+ SECURITY DEFINER
8898
+ SET search_path TO 'public'
8899
+ AS $function$
8900
+ DECLARE pid constant uuid := '90209296-f569-44fd-9750-dc7033872b64'; p record; v_keys text[]; v_rows jsonb; v_status text; v_n int; v_result jsonb;
8901
+ BEGIN
8902
+ PERFORM public.voorraad_vereis('server', 'voorraad_correctie_1140');
8903
+ PERFORM pg_advisory_xact_lock(hashtextextended('voorraad_correctie_1140', 0));
8904
+ SELECT id, name, article_number, NULLIF(btrim(COALESCE(trade_item_key,'')),'') tk, NULLIF(btrim(COALESCE(floriday_trade_item_id,'')),'') fk
8905
+ INTO p FROM public.products WHERE id = pid;
8906
+ v_keys := array_remove(ARRAY[p.tk, p.fk, 'product:' || pid::text, pid::text], NULL);
8907
+ SELECT COALESCE(jsonb_agg(jsonb_build_object('id', s.id, 'trade_item_key', s.trade_item_key, 'connection_id', s.connection_id, 'notitie', s.notes) ORDER BY s.id), '[]'::jsonb),
8908
+ count(*) FILTER (WHERE COALESCE(btrim(s.notes),'') <> '')
8909
+ INTO v_rows, v_n
8910
+ FROM public.trade_item_stock s WHERE s.trade_item_key = ANY(v_keys);
8911
+ IF p.id IS NULL AND jsonb_array_length(v_rows) = 0 THEN v_status := 'niets te doen: artikel bestaat niet';
8912
+ ELSIF v_n = 0 THEN v_status := 'niets te doen: notitie is al leeg';
8913
+ ELSE v_status := CASE WHEN p_uitvoeren THEN 'uitgevoerd' ELSE 'voorstel' END; END IF;
8914
+ IF v_status = 'uitgevoerd' THEN
8915
+ UPDATE public.trade_item_stock s SET notes = NULL, updated_at = now()
8916
+ WHERE s.id IN (SELECT (e->>'id')::uuid FROM jsonb_array_elements(v_rows) e WHERE COALESCE(btrim(e->>'notitie'),'') <> '');
8917
+ END IF;
8918
+ v_result := jsonb_build_object('ok', true, 'status', v_status, 'artikel', pid, 'naam', p.name, 'artikelnummer', p.article_number,
8919
+ 'regels_met_notitie', v_n, 'voor', v_rows);
8920
+ INSERT INTO public.voorraad_correcties(correctie, uitgevoerd_door, proef, aantallen, hash_ok)
8921
+ VALUES ('voorraad_correctie_1140', COALESCE(auth.uid()::text, session_user::text), NOT p_uitvoeren, v_result, true);
8922
+ RETURN v_result;
8923
+ END $function$
8924
+ ;
8925
+ REVOKE ALL ON FUNCTION voorraad_correctie_1140(boolean) FROM PUBLIC;
8926
+ REVOKE ALL ON FUNCTION voorraad_correctie_1140(boolean) FROM anon;
8927
+ GRANT EXECUTE ON FUNCTION voorraad_correctie_1140(boolean) TO service_role;
8825
8928
  CREATE OR REPLACE FUNCTION public.voorraad_correctie_status(p_correctie text DEFAULT '1098'::text)
8826
8929
  RETURNS jsonb
8827
8930
  LANGUAGE plpgsql
@@ -8845,6 +8948,56 @@ REVOKE ALL ON FUNCTION voorraad_correctie_status(text) FROM PUBLIC;
8845
8948
  REVOKE ALL ON FUNCTION voorraad_correctie_status(text) FROM anon;
8846
8949
  GRANT EXECUTE ON FUNCTION voorraad_correctie_status(text) TO authenticated;
8847
8950
  GRANT EXECUTE ON FUNCTION voorraad_correctie_status(text) TO service_role;
8951
+ CREATE OR REPLACE FUNCTION public.voorraad_defaults_check()
8952
+ RETURNS jsonb
8953
+ LANGUAGE plpgsql
8954
+ STABLE SECURITY DEFINER
8955
+ SET search_path TO 'public'
8956
+ AS $function$
8957
+ DECLARE v_vert jsonb := '[]'::jsonb; r record; v_res jsonb; v_engine boolean;
8958
+ BEGIN
8959
+ PERFORM public.voorraad_vereis('ingelogd', 'voorraad_defaults_check');
8960
+ v_engine := to_regprocedure('public.logistics_ladingdrager_resolve(text)') IS NOT NULL;
8961
+ IF v_engine THEN
8962
+ FOR r IN SELECT code FROM public.voorraad_load_carrier_types WHERE actief ORDER BY volgorde, code LOOP
8963
+ BEGIN
8964
+ EXECUTE 'SELECT public.logistics_ladingdrager_resolve($1)' INTO v_res USING r.code;
8965
+ EXCEPTION WHEN others THEN v_res := jsonb_build_object('code', NULL, 'fout', SQLERRM);
8966
+ END;
8967
+ IF v_res->>'code' IS NULL THEN
8968
+ v_vert := v_vert || jsonb_build_object('code', r.code, 'reden', COALESCE(v_res->>'fout', 'onbekend'));
8969
+ END IF;
8970
+ END LOOP;
8971
+ END IF;
8972
+ RETURN jsonb_build_object(
8973
+ 'versie_code', public.voorraad_defaults_versie(),
8974
+ 'versie_toegepast', (SELECT versie FROM public.voorraad_defaults_state WHERE id),
8975
+ 'plaatshoudercodes', (SELECT count(*) FROM public.voorraad_placeholder_codes),
8976
+ 'ladingdragers_actief', (SELECT count(*) FROM public.voorraad_load_carrier_types WHERE actief),
8977
+ 'herberekenlimieten_aanwezig', EXISTS (SELECT 1 FROM public.inventory_recompute_limits WHERE id),
8978
+ 'engine_vertaling_aanwezig', v_engine,
8979
+ 'ladingdragers_niet_vertaalbaar', CASE WHEN v_engine THEN v_vert ELSE NULL END);
8980
+ END $function$
8981
+ ;
8982
+ REVOKE ALL ON FUNCTION voorraad_defaults_check() FROM PUBLIC;
8983
+ REVOKE ALL ON FUNCTION voorraad_defaults_check() FROM anon;
8984
+ GRANT EXECUTE ON FUNCTION voorraad_defaults_check() TO authenticated;
8985
+ GRANT EXECUTE ON FUNCTION voorraad_defaults_check() TO service_role;
8986
+ CREATE OR REPLACE FUNCTION public.voorraad_defaults_versie()
8987
+ RETURNS integer
8988
+ LANGUAGE sql
8989
+ IMMUTABLE
8990
+ SET search_path TO 'public'
8991
+ AS $function$ SELECT 1 $function$
8992
+ ;
8993
+ REVOKE ALL ON FUNCTION voorraad_defaults_versie() FROM PUBLIC;
8994
+ REVOKE ALL ON FUNCTION voorraad_defaults_versie() FROM anon;
8995
+ REVOKE EXECUTE ON FUNCTION voorraad_defaults_versie() FROM PUBLIC;
8996
+ GRANT EXECUTE ON FUNCTION voorraad_defaults_versie() TO authenticated;
8997
+ GRANT EXECUTE ON FUNCTION voorraad_defaults_versie() TO service_role;
8998
+ REVOKE EXECUTE ON FUNCTION voorraad_defaults_versie() FROM anon;
8999
+ GRANT EXECUTE ON FUNCTION voorraad_defaults_versie() TO authenticated;
9000
+ GRANT EXECUTE ON FUNCTION voorraad_defaults_versie() TO service_role;
8848
9001
  CREATE OR REPLACE FUNCTION public.voorraad_dubbele_voorraadregels()
8849
9002
  RETURNS jsonb
8850
9003
  LANGUAGE plpgsql
@@ -8872,6 +9025,68 @@ REVOKE ALL ON FUNCTION voorraad_dubbele_voorraadregels() FROM PUBLIC;
8872
9025
  REVOKE ALL ON FUNCTION voorraad_dubbele_voorraadregels() FROM anon;
8873
9026
  GRANT EXECUTE ON FUNCTION voorraad_dubbele_voorraadregels() TO authenticated;
8874
9027
  GRANT EXECUTE ON FUNCTION voorraad_dubbele_voorraadregels() TO service_role;
9028
+ CREATE OR REPLACE FUNCTION public.voorraad_ensure_defaults()
9029
+ RETURNS jsonb
9030
+ LANGUAGE plpgsql
9031
+ SECURITY DEFINER
9032
+ SET search_path TO 'public'
9033
+ AS $function$
9034
+ DECLARE
9035
+ v_versie int := public.voorraad_defaults_versie();
9036
+ -- Systeemgegevens (standaardlijst versie 1). Wijzig je deze lijst: verhoog voorraad_defaults_versie().
9037
+ v_ph text[] := ARRAY['artikelcode','artikelnummer','naam','name','code','article code','articlecode','test','-','x','nvt','n.v.t.','tbd','todo'];
9038
+ v_lc jsonb := '[{"code":"AUCTION_TROLLEY","naam":"Stapelwagen","volgorde":1},{"code":"DANISH_TROLLEY","naam":"Deense container","volgorde":2},{"code":"EURO_TROLLEY","naam":"Euro-rolcontainer","volgorde":3},{"code":"PALLET","naam":"Pallet","volgorde":4},{"code":"EURO_PALLET","naam":"Euro-pallet","volgorde":5},{"code":"NONE","naam":"Geen ladingdrager","volgorde":6}]';
9039
+ -- Standaardcodes die vervallen zijn: worden op niet actief gezet, nooit verwijderd.
9040
+ v_vervallen text[] := ARRAY[]::text[];
9041
+ n_ph int := 0; n_lc_nieuw int := 0; n_lc_bij int := 0; n_lc_uit int := 0; n_lim int := 0; v_res jsonb;
9042
+ BEGIN
9043
+ PERFORM public.voorraad_vereis('ingelogd', 'voorraad_ensure_defaults');
9044
+ BEGIN
9045
+ IF EXISTS (SELECT 1 FROM public.voorraad_defaults_state s WHERE s.id AND s.versie = v_versie)
9046
+ AND EXISTS (SELECT 1 FROM public.inventory_recompute_limits l WHERE l.id)
9047
+ AND EXISTS (SELECT 1 FROM public.voorraad_placeholder_codes)
9048
+ AND EXISTS (SELECT 1 FROM public.voorraad_load_carrier_types) THEN
9049
+ RETURN jsonb_build_object('ok', true, 'versie', v_versie, 'overgeslagen', true);
9050
+ END IF;
9051
+ PERFORM pg_advisory_xact_lock(hashtext('voorraad_ensure_defaults'));
9052
+
9053
+ INSERT INTO public.voorraad_placeholder_codes(code) SELECT c FROM unnest(v_ph) c ON CONFLICT (code) DO NOTHING;
9054
+ GET DIAGNOSTICS n_ph = ROW_COUNT;
9055
+
9056
+ INSERT INTO public.voorraad_load_carrier_types(code, naam, volgorde)
9057
+ SELECT e->>'code', e->>'naam', (e->>'volgorde')::int FROM jsonb_array_elements(v_lc) e
9058
+ ON CONFLICT (code) DO NOTHING;
9059
+ GET DIAGNOSTICS n_lc_nieuw = ROW_COUNT;
9060
+ UPDATE public.voorraad_load_carrier_types t
9061
+ SET volgorde = (e->>'volgorde')::int,
9062
+ naam = CASE WHEN t.naam_aangepast THEN t.naam ELSE e->>'naam' END,
9063
+ updated_at = now()
9064
+ FROM jsonb_array_elements(v_lc) e
9065
+ WHERE t.code = e->>'code'
9066
+ AND (t.volgorde IS DISTINCT FROM (e->>'volgorde')::int OR (NOT t.naam_aangepast AND t.naam IS DISTINCT FROM e->>'naam'));
9067
+ GET DIAGNOSTICS n_lc_bij = ROW_COUNT;
9068
+ UPDATE public.voorraad_load_carrier_types t SET actief = false, updated_at = now()
9069
+ WHERE t.code = ANY(v_vervallen) AND t.actief;
9070
+ GET DIAGNOSTICS n_lc_uit = ROW_COUNT;
9071
+
9072
+ -- Klantinstelling: alleen aanmaken als hij ontbreekt, met de kolomstandaarden.
9073
+ INSERT INTO public.inventory_recompute_limits DEFAULT VALUES ON CONFLICT (id) DO NOTHING;
9074
+ GET DIAGNOSTICS n_lim = ROW_COUNT;
9075
+
9076
+ v_res := jsonb_build_object('plaatshoudercodes_toegevoegd', n_ph, 'ladingdragers_toegevoegd', n_lc_nieuw,
9077
+ 'ladingdragers_bijgewerkt', n_lc_bij, 'ladingdragers_niet_actief', n_lc_uit, 'herberekenlimieten_aangemaakt', n_lim);
9078
+ INSERT INTO public.voorraad_defaults_state(id, versie, toegepast_at, resultaat) VALUES (true, v_versie, now(), v_res)
9079
+ ON CONFLICT (id) DO UPDATE SET versie = EXCLUDED.versie, toegepast_at = EXCLUDED.toegepast_at, resultaat = EXCLUDED.resultaat;
9080
+ RETURN jsonb_build_object('ok', true, 'versie', v_versie, 'overgeslagen', false) || v_res;
9081
+ EXCEPTION WHEN others THEN
9082
+ RETURN jsonb_build_object('ok', false, 'versie', v_versie, 'melding', 'Standaardgegevens konden niet worden aangevuld', 'detail', SQLERRM);
9083
+ END;
9084
+ END $function$
9085
+ ;
9086
+ REVOKE ALL ON FUNCTION voorraad_ensure_defaults() FROM PUBLIC;
9087
+ REVOKE ALL ON FUNCTION voorraad_ensure_defaults() FROM anon;
9088
+ GRANT EXECUTE ON FUNCTION voorraad_ensure_defaults() TO authenticated;
9089
+ GRANT EXECUTE ON FUNCTION voorraad_ensure_defaults() TO service_role;
8875
9090
  CREATE OR REPLACE FUNCTION public.voorraad_external_fulfilled_ids(p_cf jsonb)
8876
9091
  RETURNS text[]
8877
9092
  LANGUAGE sql
@@ -8909,6 +9124,31 @@ REVOKE ALL ON FUNCTION voorraad_fcsq_local_guard() FROM PUBLIC;
8909
9124
  REVOKE ALL ON FUNCTION voorraad_fcsq_local_guard() FROM anon;
8910
9125
  GRANT EXECUTE ON FUNCTION voorraad_fcsq_local_guard() TO authenticated;
8911
9126
  GRANT EXECUTE ON FUNCTION voorraad_fcsq_local_guard() TO service_role;
9127
+ CREATE OR REPLACE FUNCTION public.voorraad_floriday_klaarzetten_toegestaan()
9128
+ RETURNS boolean
9129
+ LANGUAGE plpgsql
9130
+ STABLE SECURITY DEFINER
9131
+ SET search_path TO 'public'
9132
+ AS $function$
9133
+ DECLARE v boolean;
9134
+ BEGIN
9135
+ PERFORM public.voorraad_vereis('ingelogd', 'voorraad_floriday_klaarzetten_toegestaan');
9136
+ BEGIN
9137
+ EXECUTE 'SELECT public.logistics_floriday_write_allowed($1)' INTO v USING 'stock_publish';
9138
+ EXCEPTION WHEN OTHERS THEN
9139
+ v := false; -- poort onleesbaar = niets klaarzetten
9140
+ END;
9141
+ RETURN COALESCE(v, false);
9142
+ END $function$
9143
+ ;
9144
+ REVOKE ALL ON FUNCTION voorraad_floriday_klaarzetten_toegestaan() FROM PUBLIC;
9145
+ REVOKE ALL ON FUNCTION voorraad_floriday_klaarzetten_toegestaan() FROM anon;
9146
+ REVOKE EXECUTE ON FUNCTION voorraad_floriday_klaarzetten_toegestaan() FROM PUBLIC;
9147
+ GRANT EXECUTE ON FUNCTION voorraad_floriday_klaarzetten_toegestaan() TO authenticated;
9148
+ GRANT EXECUTE ON FUNCTION voorraad_floriday_klaarzetten_toegestaan() TO service_role;
9149
+ REVOKE EXECUTE ON FUNCTION voorraad_floriday_klaarzetten_toegestaan() FROM anon;
9150
+ GRANT EXECUTE ON FUNCTION voorraad_floriday_klaarzetten_toegestaan() TO authenticated;
9151
+ GRANT EXECUTE ON FUNCTION voorraad_floriday_klaarzetten_toegestaan() TO service_role;
8912
9152
  CREATE OR REPLACE FUNCTION public.voorraad_floriday_leads_key(p_key text)
8913
9153
  RETURNS boolean
8914
9154
  LANGUAGE sql
@@ -9185,9 +9425,9 @@ CREATE OR REPLACE FUNCTION public.voorraad_install_check()
9185
9425
  STABLE SECURITY DEFINER
9186
9426
  SET search_path TO 'public'
9187
9427
  AS $function$
9188
- DECLARE v_f text[] := ARRAY['voorraad_canoniek_artikel','voorraad_canoniek_sleutel','voorraad_artikel_prijs','voorraad_dubbele_voorraadregels','voorraad_correctie_1131','voorraad_correctie_1132','voorraad_gateway_routes_check','voorraad_placeholder_code_reason','trg_products_placeholder_code','voorraad_fust_juist','voorraad_correctie_1121','voorraad_correctie_1121_regels','voorraad_correctie_1123','voorraad_correctie_1124','voorraad_load_carriers','voorraad_packing_from_floriday','voorraad_packing_missing','voorraad_correctie_1126','voorraad_correctie_1127','trg_voorraad_link_primary_packing','voorraad_order_geannuleerd','voorraad_article_vbn','voorraad_correctie_1112','voorraad_reverse_order_mutations','voorraad_withdraw_stock_row','ensure_voorraad_local_context','get_stock_context','voorraad_stock_context_status','voorraad_fcsq_local_guard','_floriday_queue_cleanup_batch','_migrate_rewrite_stock_key','_stock_import_caller','apply_fust_stock_mutation','apply_stock_consumption','apply_stock_reservation','autolink_product_to_floriday','backfill_open_order_reservations','calculate_floriday_desired_stock','calculate_structure_available','canonicalize_trade_item_stock_key','check_product_structure','claim_floriday_base_supply','claim_floriday_stock_queue','cleanup_floriday_stock_queue','cleanup_voorraad_module_history','complete_floriday_base_supply','complete_floriday_stock_queue','complete_floriday_stock_queue_outcome','consume_bom_for_production','consume_order_item','drain_inventory_recompute_queue','enqueue_floriday_continuous_stock','enqueue_floriday_continuous_stock_after_warehouse_preference','enqueue_structure_recompute','ensure_inventory_recompute_drain','ensure_trade_item_stock_row','ensure_trade_item_stock_row_key','fcsq_block_disabled','fcsq_fallback_supersede','fcsq_wake_base_supply','find_trade_item_key','floriday_adopt_connection','floriday_autoheal_connections','floriday_capture_stock_snapshot','floriday_cleanup_stock_queue_v2','floriday_compact_stock_snapshots','floriday_default_owner','floriday_desired_stock_regression_check','floriday_ensure_inventory_settings','floriday_erp_leading_preview','floriday_fill_publish_horizon','floriday_follow_apply','floriday_ingest_sales_orders','floriday_leading_summary','floriday_make_erp_leading','floriday_norm_offer_forms','floriday_orphan_settings_count','floriday_publish_horizon_weeks','floriday_queue_erp_guard','floriday_queue_first_positive','floriday_recompute_inventory','floriday_relink_products','floriday_requeue_dead_letters','floriday_settings_change_recompute','floriday_settings_change_recompute_stmt','floriday_stock_change_recompute','floriday_stock_queue_supersede','floriday_takeover_apply','floriday_takeover_fetch_state','floriday_takeover_store_forms','floriday_takeover_undo','fust_negative_stock_report','fust_types_duplicate_guard','get_active_floriday_context','get_group_allocation_keys','get_group_head_key','get_product_stock','get_product_structure_totals','get_product_structure_totals_batch','inventory_inline_budget_ok','merge_products','normalize_order_source','process_inventory_recompute_queue','produce_designed_product','product_active_group_id','product_id_from_ref','product_is_set','product_label','product_member_group_ids','product_own_available','product_packings_derive','product_packings_replace','product_packings_sync_from_floriday','product_primary_pieces','product_set_depth_above','product_set_depth_below','product_structure_ancestors','product_structure_max_depth','product_structure_path','product_tray_stickers_touch','product_type','promote_trade_item_key','recompute_all_reserved_stock','recompute_order_status','recompute_reserved_for_order','recompute_reserved_stock','requeue_skipped_stock_rows','reset_stalled_floriday_stock_queue','resolve_group_allocation','resolve_group_member_stock_key','resolve_product_id_for_item','resolve_stock_trade_item_key','reverse_production','run_floriday_base_supply_process','run_floriday_continuous_stock_sync','run_floriday_follow','run_floriday_stock_queue_process','run_floriday_stock_reconcile','run_logistics_tasks_dispatch','self_heal_floriday_links','set_module_runtime_config_updated_at','set_product_bom_tenant','set_product_stock','set_updated_at_order_fust_bookings','stock_import_cleanup','stock_import_create','stock_import_process_chunk','stock_import_stop','stock_import_undo_chunk','sync_order_item_fusten','sync_products_quantity_from_stock','touch_fust_types_updated_at','trade_item_drafts_readonly','trade_item_prices_touch_updated_at','trade_item_stock_duplicates','trg_cart_numbers_sync_order_status_fn','trg_cart_session_consume_fn','trg_check_product_structure','trg_floriday_cache_relink_fn','trg_floriday_trade_items_autolink_fn','trg_order_items_autolink_fn','trg_order_items_fusten','trg_order_items_reserve_fn','trg_orders_cancel_release_fn','trg_orders_consume_on_complete_fn','trg_orders_default_phase_fn','trg_orders_external_fulfilled_fn','trg_orders_recompute_reserved_fn','trg_pgi_assign_sort_order','trg_pgi_order_taken_check','trg_process_recompute_on_commit','trg_product_packings_derive_fn','trg_products_autolink_fn','trg_products_floriday_link_enqueue','trg_products_seed_stock_fn','trg_requeue_no_warehouse_cache','trg_requeue_no_warehouse_connection','trg_requeue_no_warehouse_item_pref','trg_requeue_skipped_no_price','trg_stock_structure_recompute_ins','trg_stock_structure_recompute_upd','trg_structure_change_recompute','trg_trade_item_drafts_autolink_fn','trg_trade_item_stock_auto_bom','trg_trade_item_stock_auto_bom_reverse','trg_trade_item_stock_log_change','trg_trade_item_stock_reserve_fn','trg_trade_item_stock_zero_watch','trg_trade_items_cache_autolink_fn','update_updated_at_column','voorraad_alert_floriday_not_updated','voorraad_can_write','voorraad_cleanup_old_rows','voorraad_consume_external_fulfilled','voorraad_correctie_1098','voorraad_correctie_status','voorraad_external_fulfilled_ids','voorraad_floriday_leads_key','voorraad_fust_dimensions','voorraad_hook_base_url','voorraad_hook_on','voorraad_hook_post','voorraad_hook_switch_jobs','voorraad_install_check','voorraad_is_server','voorraad_mark_floriday_sold_before_switch','voorraad_production_enabled','voorraad_schema_ddl','voorraad_touch_updated_at','voorraad_vereis','voorraad_week_is_past'];
9428
+ DECLARE v_f text[] := ARRAY['voorraad_ensure_defaults','voorraad_defaults_check','voorraad_defaults_versie','voorraad_canoniek_artikel','voorraad_canoniek_sleutel','voorraad_artikel_prijs','voorraad_dubbele_voorraadregels','voorraad_correctie_1131','voorraad_correctie_1132','voorraad_gateway_routes_check','voorraad_placeholder_code_reason','trg_products_placeholder_code','voorraad_fust_juist','voorraad_correctie_1121','voorraad_correctie_1121_regels','voorraad_correctie_1123','voorraad_correctie_1124','voorraad_load_carriers','voorraad_packing_from_floriday','voorraad_packing_missing','voorraad_correctie_1126','voorraad_correctie_1127','trg_voorraad_link_primary_packing','voorraad_order_geannuleerd','voorraad_article_vbn','voorraad_correctie_1112','voorraad_reverse_order_mutations','voorraad_withdraw_stock_row','voorraad_floriday_klaarzetten_toegestaan','voorraad_afboeken','voorraad_voorraad_opslaan','voorraad_correctie_1140','voorraad_overzicht_orderregel_koppeling','voorraad_orderregel_sleutel','ensure_voorraad_local_context','get_stock_context','voorraad_stock_context_status','voorraad_fcsq_local_guard','_floriday_queue_cleanup_batch','_migrate_rewrite_stock_key','_stock_import_caller','apply_fust_stock_mutation','apply_stock_consumption','apply_stock_reservation','autolink_product_to_floriday','backfill_open_order_reservations','calculate_floriday_desired_stock','calculate_structure_available','canonicalize_trade_item_stock_key','check_product_structure','claim_floriday_base_supply','claim_floriday_stock_queue','cleanup_floriday_stock_queue','cleanup_voorraad_module_history','complete_floriday_base_supply','complete_floriday_stock_queue','complete_floriday_stock_queue_outcome','consume_bom_for_production','consume_order_item','drain_inventory_recompute_queue','enqueue_floriday_continuous_stock','enqueue_floriday_continuous_stock_after_warehouse_preference','enqueue_structure_recompute','ensure_inventory_recompute_drain','ensure_trade_item_stock_row','ensure_trade_item_stock_row_key','fcsq_block_disabled','fcsq_fallback_supersede','fcsq_wake_base_supply','find_trade_item_key','floriday_adopt_connection','floriday_autoheal_connections','floriday_capture_stock_snapshot','floriday_cleanup_stock_queue_v2','floriday_compact_stock_snapshots','floriday_default_owner','floriday_desired_stock_regression_check','floriday_ensure_inventory_settings','floriday_erp_leading_preview','floriday_fill_publish_horizon','floriday_follow_apply','floriday_ingest_sales_orders','floriday_leading_summary','floriday_make_erp_leading','floriday_norm_offer_forms','floriday_orphan_settings_count','floriday_publish_horizon_weeks','floriday_queue_erp_guard','floriday_queue_first_positive','floriday_recompute_inventory','floriday_relink_products','floriday_requeue_dead_letters','floriday_settings_change_recompute','floriday_settings_change_recompute_stmt','floriday_stock_change_recompute','floriday_stock_queue_supersede','floriday_takeover_apply','floriday_takeover_fetch_state','floriday_takeover_store_forms','floriday_takeover_undo','fust_negative_stock_report','fust_types_duplicate_guard','get_active_floriday_context','get_group_allocation_keys','get_group_head_key','get_product_stock','get_product_structure_totals','get_product_structure_totals_batch','inventory_inline_budget_ok','merge_products','normalize_order_source','process_inventory_recompute_queue','produce_designed_product','product_active_group_id','product_id_from_ref','product_is_set','product_label','product_member_group_ids','product_own_available','product_packings_derive','product_packings_replace','product_packings_sync_from_floriday','product_primary_pieces','product_set_depth_above','product_set_depth_below','product_structure_ancestors','product_structure_max_depth','product_structure_path','product_tray_stickers_touch','product_type','promote_trade_item_key','recompute_all_reserved_stock','recompute_order_status','recompute_reserved_for_order','recompute_reserved_stock','requeue_skipped_stock_rows','reset_stalled_floriday_stock_queue','resolve_group_allocation','resolve_group_member_stock_key','resolve_product_id_for_item','resolve_stock_trade_item_key','reverse_production','run_floriday_base_supply_process','run_floriday_continuous_stock_sync','run_floriday_follow','run_floriday_stock_queue_process','run_floriday_stock_reconcile','run_logistics_tasks_dispatch','self_heal_floriday_links','set_module_runtime_config_updated_at','set_product_bom_tenant','set_product_stock','set_updated_at_order_fust_bookings','stock_import_cleanup','stock_import_create','stock_import_process_chunk','stock_import_stop','stock_import_undo_chunk','sync_order_item_fusten','sync_products_quantity_from_stock','touch_fust_types_updated_at','trade_item_drafts_readonly','trade_item_prices_touch_updated_at','trade_item_stock_duplicates','trg_cart_numbers_sync_order_status_fn','trg_cart_session_consume_fn','trg_check_product_structure','trg_floriday_cache_relink_fn','trg_floriday_trade_items_autolink_fn','trg_order_items_autolink_fn','trg_order_items_fusten','trg_order_items_reserve_fn','trg_orders_cancel_release_fn','trg_orders_consume_on_complete_fn','trg_orders_default_phase_fn','trg_orders_external_fulfilled_fn','trg_orders_recompute_reserved_fn','trg_pgi_assign_sort_order','trg_pgi_order_taken_check','trg_process_recompute_on_commit','trg_product_packings_derive_fn','trg_products_autolink_fn','trg_products_floriday_link_enqueue','trg_products_seed_stock_fn','trg_requeue_no_warehouse_cache','trg_requeue_no_warehouse_connection','trg_requeue_no_warehouse_item_pref','trg_requeue_skipped_no_price','trg_stock_structure_recompute_ins','trg_stock_structure_recompute_upd','trg_structure_change_recompute','trg_trade_item_drafts_autolink_fn','trg_trade_item_stock_auto_bom','trg_trade_item_stock_auto_bom_reverse','trg_trade_item_stock_log_change','trg_trade_item_stock_reserve_fn','trg_trade_item_stock_zero_watch','trg_trade_items_cache_autolink_fn','update_updated_at_column','voorraad_alert_floriday_not_updated','voorraad_can_write','voorraad_cleanup_old_rows','voorraad_consume_external_fulfilled','voorraad_correctie_1098','voorraad_correctie_status','voorraad_external_fulfilled_ids','voorraad_floriday_leads_key','voorraad_fust_dimensions','voorraad_hook_base_url','voorraad_hook_on','voorraad_hook_post','voorraad_hook_switch_jobs','voorraad_install_check','voorraad_is_server','voorraad_mark_floriday_sold_before_switch','voorraad_production_enabled','voorraad_schema_ddl','voorraad_touch_updated_at','voorraad_vereis','voorraad_week_is_past'];
9189
9429
  v_t text[] := ARRAY['trg_voorraad_link_primary_packing@products','aa0_fcsq_local_context_guard@floriday_continuous_stock_queue','aa_fcsq_erp_leading_guard@floriday_continuous_stock_queue','aa_fis_norm_offer_forms@floriday_inventory_settings','aa_pgi_assign_sort_order@product_group_items','fcsq_block_disabled@floriday_continuous_stock_queue','fcsq_wake_base_supply_ins@floriday_continuous_stock_queue','fcsq_wake_base_supply_upd@floriday_continuous_stock_queue','fust_stock_mutations_apply@fust_stock_mutations','fust_types_duplicate_guard@fust_types','fust_types_touch@fust_types','product_packings_derive_trg@product_packings','product_packings_updated_at@product_packings','set_product_bom_tenant_trigger@product_bom_items','trade_item_prices_set_updated_at@trade_item_prices','trg_cart_numbers_sync_order_status@cart_numbers','trg_cart_session_consume@cart_control_sessions','trg_check_product_structure@product_bom_items','trg_check_product_structure@product_group_items','trg_check_product_structure@product_groups','trg_fcs_queue_updated_at@floriday_continuous_stock_queue','trg_fcsq_fallback_supersede@floriday_continuous_stock_queue','trg_fcsq_supersede@floriday_continuous_stock_queue','trg_floriday_cache_relink@floriday_trade_items_cache','trg_floriday_ensure_inventory_settings@products','trg_floriday_gate_stock_queue@floriday_continuous_stock_queue','trg_floriday_settings_change_recompute_ins@floriday_inventory_settings','trg_floriday_settings_change_recompute_upd@floriday_inventory_settings','trg_floriday_stock_change_recompute@trade_item_stock','trg_floriday_takeover_runs_updated_at@floriday_takeover_runs','trg_floriday_trade_items_autolink@floriday_trade_items_cache','trg_fust_types_requeue_blocked@fust_types','trg_module_runtime_config_updated_at@module_runtime_config','trg_order_fust_bookings_updated_at@order_fust_bookings','trg_order_items_autolink@order_items','trg_order_items_fusten_aiud@order_items','trg_order_items_reserve@order_items','trg_orders_cancel_release@orders','trg_orders_consume_on_complete@orders','trg_orders_default_phase@orders','trg_orders_external_fulfilled@orders','trg_orders_recompute_reserved@orders','trg_prevent_duplicate_product_draft@trade_item_drafts','trg_product_tray_stickers_touch@product_tray_stickers','trg_products_autolink@products','trg_products_floriday_link_enqueue@products','trg_products_seed_stock@products','trg_requeue_no_warehouse_cache@floriday_trade_items_cache','trg_requeue_no_warehouse_connection@floriday_connections','trg_requeue_no_warehouse_item_pref@trade_item_warehouse_preferences','trg_requeue_skipped_no_price@products','trg_stock_mutation_alert@stock_mutation_log','trg_stock_structure_recompute_ins@trade_item_stock','trg_stock_structure_recompute_upd@trade_item_stock','trg_structure_change_recompute@product_bom_items','trg_structure_change_recompute@product_group_items','trg_structure_change_recompute@product_groups','trg_sync_layer_stock_from_trade_stock@trade_item_stock','trg_sync_products_quantity_from_stock_del@trade_item_stock','trg_sync_products_quantity_from_stock_iu@trade_item_stock','trg_trade_item_drafts_autolink@trade_item_drafts','trg_trade_item_drafts_readonly@trade_item_drafts','trg_trade_item_stock_canonical_key@trade_item_stock','trg_trade_item_stock_publish@trade_item_stock','trg_trade_item_stock_reserve@trade_item_stock','trg_trade_item_stock_updated_at@trade_item_stock','trg_trade_item_stock_zero_watch@trade_item_stock','trg_trade_item_supply_lines_touch@trade_item_supply_lines','trg_trade_item_warehouse_preference_enqueue_stock@trade_item_warehouse_preferences','trg_trade_items_cache_autolink@floriday_trade_items_cache','trg_voorraad_buffer_state_updated_at@voorraad_buffer_state','trg_voorraad_event_log_updated_at@voorraad_logistics_event_log','update_trade_item_drafts_updated_at@trade_item_drafts','update_trade_item_warehouse_preferences_updated_at@trade_item_warehouse_preferences','update_voorraad_custom_fields_updated_at@voorraad_custom_fields','update_voorraad_publish_jobs_updated_at@voorraad_publish_jobs','update_voorraad_publish_learnings_updated_at@voorraad_publish_learnings','update_voorraad_publish_steps_updated_at@voorraad_publish_steps','voorraad_hook_switch_jobs@module_runtime_config','zz_fcsq_first_positive@floriday_continuous_stock_queue'];
9190
- v_p text[] := ARRAY['Authenticated can add learnings@voorraad_publish_learnings','Authenticated can delete voorraad custom fields@voorraad_custom_fields','Authenticated can insert vbn required characteristics@floriday_vbn_required_characteristics','Authenticated can insert voorraad custom fields@voorraad_custom_fields','Authenticated can read continuous stock cache@floriday_continuous_stock_cache','Authenticated can read learnings@voorraad_publish_learnings','Authenticated can read vbn required characteristics@floriday_vbn_required_characteristics','Authenticated can read voorraad custom fields@voorraad_custom_fields','Authenticated can update learnings@voorraad_publish_learnings','Authenticated can update vbn required characteristics@floriday_vbn_required_characteristics','Authenticated can update voorraad custom fields@voorraad_custom_fields','Authenticated delete trade_item_warehouse_preferences@trade_item_warehouse_preferences','Authenticated insert trade_item_warehouse_preferences@trade_item_warehouse_preferences','Authenticated select trade_item_warehouse_preferences@trade_item_warehouse_preferences','Authenticated update trade_item_warehouse_preferences@trade_item_warehouse_preferences','Eigen momentopnamen lezen@inventory_stock_snapshots','Eigen voorraadinstellingen beheren@floriday_inventory_settings','Eigenaar leest importporties@stock_import_chunks','Eigenaar leest importregels@stock_import_rows','Fust mutations delete@fust_stock_mutations','Fust mutations insert@fust_stock_mutations','Fust mutations read@fust_stock_mutations','Fust mutations update@fust_stock_mutations','Fust types delete@fust_types','Fust types insert@fust_types','Fust types read@fust_types','Fust types update@fust_types','Ingelogde gebruikers kunnen bufferstatus lezen@voorraad_buffer_state','Ingelogde gebruikers kunnen de eventlog lezen@voorraad_logistics_event_log','Ingelogde gebruikers kunnen fustboekingen lezen@order_fust_bookings','Ingelogde gebruikers lezen drempels@inventory_recompute_limits','Ingelogde gebruikers lezen opruimlogboek@structure_cleanup_log','Ingelogde gebruikers lezen opruimruns@floriday_queue_cleanup_runs','Ingelogden beheren traystickers@product_tray_stickers','Ingelogden lezen herberekenwachtrij@inventory_recompute_queue','Ingelogden lezen voorraadmeldingen@stock_integrity_alerts','Ingelogden markeren voorraadmeldingen als gezien@stock_integrity_alerts','Own queue rows select@floriday_continuous_stock_queue','Owner delete trade_item_drafts@trade_item_drafts','Owner insert trade_item_drafts@trade_item_drafts','Owner select trade_item_drafts@trade_item_drafts','Owner update trade_item_drafts@trade_item_drafts','Signed-in users read reconcile runs@floriday_reconcile_runs','Stock delete@trade_item_stock','Stock insert@trade_item_stock','Stock read@trade_item_stock','Stock update@trade_item_stock','Synchronisatieposities lezen@floriday_sync_cursors','Users can insert own publish attempts@voorraad_publish_attempts','Users can read own publish attempts@voorraad_publish_attempts','Users can read own stock mutations@stock_mutation_log','Users manage own import runs@stock_import_runs','Users manage own supply lines@trade_item_supply_lines','Users manage own trade item prices@trade_item_prices','Users manage their own publish jobs@voorraad_publish_jobs','Users manage their own publish steps@voorraad_publish_steps','Verwerkte orders lezen@floriday_sales_order_ingest','Voorraadschrijvers lezen overnameregels@floriday_takeover_items','Voorraadschrijvers lezen overnames@floriday_takeover_runs','authenticated can insert merge log@product_merge_log','authenticated can read merge log@product_merge_log','service role only@voorraad_media_upload_failures','product_packings_read@product_packings','product_packings_write@product_packings'];
9430
+ v_p text[] := ARRAY['Authenticated can add learnings@voorraad_publish_learnings','Authenticated can delete voorraad custom fields@voorraad_custom_fields','Authenticated can insert vbn required characteristics@floriday_vbn_required_characteristics','Authenticated can insert voorraad custom fields@voorraad_custom_fields','Authenticated can read continuous stock cache@floriday_continuous_stock_cache','Authenticated can read learnings@voorraad_publish_learnings','Authenticated can read vbn required characteristics@floriday_vbn_required_characteristics','Authenticated can read voorraad custom fields@voorraad_custom_fields','Authenticated can update learnings@voorraad_publish_learnings','Authenticated can update vbn required characteristics@floriday_vbn_required_characteristics','Authenticated can update voorraad custom fields@voorraad_custom_fields','Authenticated delete trade_item_warehouse_preferences@trade_item_warehouse_preferences','Authenticated insert trade_item_warehouse_preferences@trade_item_warehouse_preferences','Authenticated select trade_item_warehouse_preferences@trade_item_warehouse_preferences','Authenticated update trade_item_warehouse_preferences@trade_item_warehouse_preferences','Eigen momentopnamen lezen@inventory_stock_snapshots','Eigen voorraadinstellingen beheren@floriday_inventory_settings','Eigenaar leest importporties@stock_import_chunks','Eigenaar leest importregels@stock_import_rows','Fust mutations delete@fust_stock_mutations','Fust mutations insert@fust_stock_mutations','Fust mutations read@fust_stock_mutations','Fust mutations update@fust_stock_mutations','Fust types delete@fust_types','Fust types insert@fust_types','Fust types read@fust_types','Fust types update@fust_types','Ingelogde gebruikers kunnen bufferstatus lezen@voorraad_buffer_state','Ingelogde gebruikers kunnen de eventlog lezen@voorraad_logistics_event_log','Ingelogde gebruikers kunnen fustboekingen lezen@order_fust_bookings','Ingelogde gebruikers lezen drempels@inventory_recompute_limits','Ingelogd mag standaardstatus lezen@voorraad_defaults_state','Ingelogde gebruikers lezen opruimlogboek@structure_cleanup_log','Ingelogde gebruikers lezen opruimruns@floriday_queue_cleanup_runs','Ingelogden beheren traystickers@product_tray_stickers','Ingelogden lezen herberekenwachtrij@inventory_recompute_queue','Ingelogden lezen voorraadmeldingen@stock_integrity_alerts','Ingelogden markeren voorraadmeldingen als gezien@stock_integrity_alerts','Own queue rows select@floriday_continuous_stock_queue','Owner delete trade_item_drafts@trade_item_drafts','Owner insert trade_item_drafts@trade_item_drafts','Owner select trade_item_drafts@trade_item_drafts','Owner update trade_item_drafts@trade_item_drafts','Signed-in users read reconcile runs@floriday_reconcile_runs','Stock delete@trade_item_stock','Stock insert@trade_item_stock','Stock read@trade_item_stock','Stock update@trade_item_stock','Synchronisatieposities lezen@floriday_sync_cursors','Users can insert own publish attempts@voorraad_publish_attempts','Users can read own publish attempts@voorraad_publish_attempts','Users can read own stock mutations@stock_mutation_log','Users manage own import runs@stock_import_runs','Users manage own supply lines@trade_item_supply_lines','Users manage own trade item prices@trade_item_prices','Users manage their own publish jobs@voorraad_publish_jobs','Users manage their own publish steps@voorraad_publish_steps','Verwerkte orders lezen@floriday_sales_order_ingest','Voorraadschrijvers lezen overnameregels@floriday_takeover_items','Voorraadschrijvers lezen overnames@floriday_takeover_runs','authenticated can insert merge log@product_merge_log','authenticated can read merge log@product_merge_log','service role only@voorraad_media_upload_failures','product_packings_read@product_packings','product_packings_write@product_packings'];
9191
9431
  v_open text[] := ARRAY['voorraad_is_server','voorraad_vereis'];
9192
9432
  v_func jsonb; v_trig jsonb; v_pol jsonb;
9193
9433
  BEGIN
@@ -9213,7 +9453,7 @@ BEGIN
9213
9453
  SELECT jsonb_agg(jsonb_build_object('policy', split_part(t, '@', 1), 'tabel', split_part(t, '@', 2),
9214
9454
  'aanwezig', EXISTS (SELECT 1 FROM pg_policies x WHERE x.schemaname = 'public' AND x.policyname = split_part(t, '@', 1)
9215
9455
  AND x.tablename = split_part(t, '@', 2))) ORDER BY t) INTO v_pol FROM unnest(v_p) t;
9216
- RETURN jsonb_build_object('dubbele_voorraadregels', public.voorraad_dubbele_voorraadregels(), 'gateway_routes', public.voorraad_gateway_routes_check(),
9456
+ RETURN jsonb_build_object('standaardgegevens', public.voorraad_defaults_check(), 'dubbele_voorraadregels', public.voorraad_dubbele_voorraadregels(), 'gateway_routes', public.voorraad_gateway_routes_check(),
9217
9457
  'samenvatting', jsonb_build_object(
9218
9458
  'functies', jsonb_array_length(v_func),
9219
9459
  'functies_ontbrekend', (SELECT count(*) FROM jsonb_array_elements(v_func) e WHERE NOT (e->>'aanwezig')::boolean),
@@ -9251,12 +9491,12 @@ GRANT EXECUTE ON FUNCTION voorraad_is_server() TO service_role;
9251
9491
  CREATE OR REPLACE FUNCTION public.voorraad_load_carriers()
9252
9492
  RETURNS TABLE(code text, naam text, volgorde integer)
9253
9493
  LANGUAGE plpgsql
9254
- STABLE
9494
+ STABLE SECURITY DEFINER
9255
9495
  SET search_path TO 'public'
9256
9496
  AS $function$
9257
9497
  BEGIN
9258
9498
  PERFORM public.voorraad_vereis('ingelogd', 'voorraad_load_carriers');
9259
- RETURN QUERY SELECT t.code, t.naam, t.volgorde FROM public.voorraad_load_carrier_types t ORDER BY t.volgorde, t.code;
9499
+ RETURN QUERY SELECT t.code, t.naam, t.volgorde FROM public.voorraad_load_carrier_types t WHERE t.actief ORDER BY t.volgorde, t.code;
9260
9500
  END $function$
9261
9501
  ;
9262
9502
  REVOKE ALL ON FUNCTION voorraad_load_carriers() FROM PUBLIC;
@@ -9333,6 +9573,69 @@ REVOKE ALL ON FUNCTION voorraad_orderregel_sleutel(text) FROM PUBLIC;
9333
9573
  REVOKE ALL ON FUNCTION voorraad_orderregel_sleutel(text) FROM anon;
9334
9574
  GRANT EXECUTE ON FUNCTION voorraad_orderregel_sleutel(text) TO authenticated;
9335
9575
  GRANT EXECUTE ON FUNCTION voorraad_orderregel_sleutel(text) TO service_role;
9576
+ CREATE OR REPLACE FUNCTION public.voorraad_overzicht_orderregel_koppeling(p_voorbeelden integer DEFAULT 5)
9577
+ RETURNS jsonb
9578
+ LANGUAGE plpgsql
9579
+ STABLE SECURITY DEFINER
9580
+ SET search_path TO 'public'
9581
+ AS $function$
9582
+ DECLARE v jsonb;
9583
+ BEGIN
9584
+ PERFORM public.voorraad_vereis('ingelogd', 'voorraad_overzicht_orderregel_koppeling');
9585
+ WITH regels AS (
9586
+ SELECT oi.id AS order_item_id, o.id AS order_id, o.order_number, oi.product_id, oi.product_name,
9587
+ oi.source_line_key, oi.quantity,
9588
+ CASE WHEN jsonb_typeof(o.custom_fields->'floriday_lines') = 'array'
9589
+ THEN jsonb_array_length(o.custom_fields->'floriday_lines') ELSE 0 END AS n_fl,
9590
+ (SELECT count(DISTINCT l->>'sales_order_id') FROM jsonb_array_elements(
9591
+ CASE WHEN jsonb_typeof(o.custom_fields->'floriday_lines')='array' THEN o.custom_fields->'floriday_lines' ELSE '[]'::jsonb END) l) AS n_so,
9592
+ (SELECT count(*) FROM order_items x WHERE x.order_id = o.id) AS n_regels,
9593
+ (SELECT array_agg(DISTINCT l->>'trade_item_id') FROM jsonb_array_elements(
9594
+ CASE WHEN jsonb_typeof(o.custom_fields->'floriday_lines')='array' THEN o.custom_fields->'floriday_lines' ELSE '[]'::jsonb END) l
9595
+ WHERE oi.source_line_key IS NOT NULL AND l->>'sales_order_id' = oi.source_line_key
9596
+ AND COALESCE(l->>'trade_item_id','') <> '') AS kandidaten
9597
+ FROM order_items oi JOIN orders o ON o.id = oi.order_id
9598
+ ), ingedeeld AS (
9599
+ SELECT r.*,
9600
+ CASE
9601
+ WHEN r.product_id IS NOT NULL THEN 'heeft_product_id'
9602
+ WHEN r.n_fl = 0 THEN 'geen_floriday_lines'
9603
+ WHEN r.source_line_key IS NULL THEN 'geen_source_line_key'
9604
+ WHEN r.kandidaten IS NULL THEN 'geen_match_op_source_line_key'
9605
+ WHEN array_length(r.kandidaten,1) > 1 THEN 'meerdere_kandidaten'
9606
+ WHEN public.voorraad_orderregel_sleutel(r.kandidaten[1]) IS NULL THEN 'trade_item_onbekend'
9607
+ WHEN NOT EXISTS (SELECT 1 FROM trade_item_stock s WHERE s.trade_item_key = public.voorraad_orderregel_sleutel(r.kandidaten[1])) THEN 'eenduidig_zonder_voorraadrij'
9608
+ ELSE 'eenduidig_met_voorraadrij'
9609
+ END AS categorie
9610
+ FROM regels r
9611
+ )
9612
+ SELECT jsonb_build_object(
9613
+ 'totaal', (SELECT count(*) FROM ingedeeld),
9614
+ 'per_categorie', (SELECT jsonb_object_agg(categorie, n) FROM (SELECT categorie, count(*) n FROM ingedeeld GROUP BY 1) c),
9615
+ 'samengevoegde_orders', jsonb_build_object(
9616
+ 'orders', (SELECT count(DISTINCT order_id) FROM ingedeeld WHERE n_so > 1),
9617
+ 'regels_per_categorie', (SELECT jsonb_object_agg(categorie, n) FROM (SELECT categorie, count(*) n FROM ingedeeld WHERE n_so > 1 GROUP BY 1) c)),
9618
+ 'meerregelige_orders', jsonb_build_object(
9619
+ 'orders', (SELECT count(DISTINCT order_id) FROM ingedeeld WHERE n_regels > 1),
9620
+ 'regels_per_categorie', (SELECT jsonb_object_agg(categorie, n) FROM (SELECT categorie, count(*) n FROM ingedeeld WHERE n_regels > 1 GROUP BY 1) c)),
9621
+ 'voorbeelden', (SELECT jsonb_object_agg(categorie, vb) FROM (
9622
+ SELECT categorie, jsonb_agg(jsonb_build_object('order', order_number, 'order_item_id', order_item_id,
9623
+ 'product_name', product_name, 'source_line_key', source_line_key, 'kandidaten', kandidaten,
9624
+ 'floriday_orders_in_order', n_so, 'regels_in_order', n_regels)) vb
9625
+ FROM (SELECT *, row_number() OVER (PARTITION BY categorie ORDER BY (n_so > 1) DESC, (n_regels > 1) DESC, order_number) rn FROM ingedeeld) z
9626
+ WHERE rn <= GREATEST(p_voorbeelden, 1) GROUP BY categorie) e)
9627
+ ) INTO v;
9628
+ RETURN v;
9629
+ END $function$
9630
+ ;
9631
+ REVOKE ALL ON FUNCTION voorraad_overzicht_orderregel_koppeling(integer) FROM PUBLIC;
9632
+ REVOKE ALL ON FUNCTION voorraad_overzicht_orderregel_koppeling(integer) FROM anon;
9633
+ REVOKE EXECUTE ON FUNCTION voorraad_overzicht_orderregel_koppeling(integer) FROM PUBLIC;
9634
+ GRANT EXECUTE ON FUNCTION voorraad_overzicht_orderregel_koppeling(integer) TO authenticated;
9635
+ GRANT EXECUTE ON FUNCTION voorraad_overzicht_orderregel_koppeling(integer) TO service_role;
9636
+ REVOKE EXECUTE ON FUNCTION voorraad_overzicht_orderregel_koppeling(integer) FROM anon;
9637
+ GRANT EXECUTE ON FUNCTION voorraad_overzicht_orderregel_koppeling(integer) TO authenticated;
9638
+ GRANT EXECUTE ON FUNCTION voorraad_overzicht_orderregel_koppeling(integer) TO service_role;
9336
9639
  CREATE OR REPLACE FUNCTION public.voorraad_packing_from_floriday(p_product_id uuid, p_uitvoeren boolean)
9337
9640
  RETURNS jsonb
9338
9641
  LANGUAGE plpgsql
@@ -9702,6 +10005,51 @@ GRANT EXECUTE ON FUNCTION voorraad_vereis(text,text) TO service_role;
9702
10005
  GRANT EXECUTE ON FUNCTION voorraad_vereis(text,text) TO anon;
9703
10006
  GRANT EXECUTE ON FUNCTION voorraad_vereis(text,text) TO authenticated;
9704
10007
  GRANT EXECUTE ON FUNCTION voorraad_vereis(text,text) TO service_role;
10008
+ CREATE OR REPLACE FUNCTION public.voorraad_voorraad_opslaan(p_product_id uuid, p_connection_id uuid, p_trade_item_key text, p_physical_stock numeric, p_minimum_stock numeric, p_incoming_stock numeric, p_wijziging_notitie text DEFAULT NULL::text, p_artikel_notitie text DEFAULT NULL::text, p_artikel_notitie_wijzigen boolean DEFAULT false)
10009
+ RETURNS jsonb
10010
+ LANGUAGE plpgsql
10011
+ SECURITY DEFINER
10012
+ SET search_path TO 'public'
10013
+ AS $function$
10014
+ DECLARE r record; v_klaar boolean;
10015
+ BEGIN
10016
+ PERFORM public.voorraad_vereis('ingelogd', 'voorraad_voorraad_opslaan');
10017
+ IF NOT public.voorraad_can_write() THEN
10018
+ RAISE EXCEPTION 'Je hebt geen schrijfrechten op de voorraad.' USING ERRCODE = '42501'; END IF;
10019
+ IF p_physical_stock IS NULL OR p_physical_stock < 0 OR COALESCE(p_minimum_stock,0) < 0 OR COALESCE(p_incoming_stock,0) < 0 THEN
10020
+ RAISE EXCEPTION 'Voorraadaantallen mogen niet negatief zijn' USING ERRCODE = '22023'; END IF;
10021
+ PERFORM set_config('stock.change_note', left(btrim(COALESCE(p_wijziging_notitie, '')), 500), true);
10022
+ PERFORM set_config('stock.keep_notes', CASE WHEN p_artikel_notitie_wijzigen THEN '0' ELSE '1' END, true);
10023
+ IF p_product_id IS NOT NULL THEN
10024
+ SELECT * INTO r FROM public.set_product_stock(p_product_id => p_product_id, p_physical_stock => p_physical_stock,
10025
+ p_minimum_stock => p_minimum_stock, p_incoming_stock => p_incoming_stock,
10026
+ p_notes => NULLIF(btrim(COALESCE(p_artikel_notitie, '')), ''), p_change_source => 'MANUAL_STOCK');
10027
+ ELSE
10028
+ IF p_connection_id IS NULL OR COALESCE(btrim(p_trade_item_key), '') = '' THEN
10029
+ RAISE EXCEPTION 'Geen voorraadregel opgegeven' USING ERRCODE = '22023'; END IF;
10030
+ PERFORM set_config('stock.change_source', 'MANUAL_STOCK', true);
10031
+ INSERT INTO public.trade_item_stock AS t (user_id, connection_id, trade_item_key, physical_stock, minimum_stock, reserved_stock, incoming_stock, notes, change_source)
10032
+ VALUES (auth.uid(), p_connection_id, p_trade_item_key, p_physical_stock, COALESCE(p_minimum_stock,0), 0, COALESCE(p_incoming_stock,0),
10033
+ CASE WHEN p_artikel_notitie_wijzigen THEN NULLIF(btrim(COALESCE(p_artikel_notitie,'')), '') END, 'MANUAL_STOCK')
10034
+ ON CONFLICT (connection_id, trade_item_key) DO UPDATE
10035
+ SET physical_stock = EXCLUDED.physical_stock, minimum_stock = EXCLUDED.minimum_stock, incoming_stock = EXCLUDED.incoming_stock,
10036
+ notes = CASE WHEN p_artikel_notitie_wijzigen THEN EXCLUDED.notes ELSE t.notes END,
10037
+ change_source = 'MANUAL_STOCK', updated_at = now()
10038
+ RETURNING t.connection_id, t.trade_item_key, t.physical_stock, t.minimum_stock, t.reserved_stock, t.incoming_stock, t.notes, t.updated_at INTO r;
10039
+ END IF;
10040
+ -- De geschiedenis wordt bij afronden geschreven (uitgestelde trigger); notitie blijft tot einde transactie.
10041
+ BEGIN v_klaar := public.voorraad_floriday_klaarzetten_toegestaan();
10042
+ EXCEPTION WHEN others THEN v_klaar := false; END;
10043
+ RETURN jsonb_build_object('opgeslagen', true, 'floriday_klaargezet_toegestaan', COALESCE(v_klaar, false),
10044
+ 'connection_id', r.connection_id, 'trade_item_key', r.trade_item_key, 'physical_stock', r.physical_stock,
10045
+ 'minimum_stock', r.minimum_stock, 'reserved_stock', r.reserved_stock, 'incoming_stock', r.incoming_stock,
10046
+ 'notes', r.notes, 'updated_at', r.updated_at);
10047
+ END $function$
10048
+ ;
10049
+ REVOKE ALL ON FUNCTION voorraad_voorraad_opslaan(uuid,uuid,text,numeric,numeric,numeric,text,text,boolean) FROM PUBLIC;
10050
+ REVOKE ALL ON FUNCTION voorraad_voorraad_opslaan(uuid,uuid,text,numeric,numeric,numeric,text,text,boolean) FROM anon;
10051
+ GRANT EXECUTE ON FUNCTION voorraad_voorraad_opslaan(uuid,uuid,text,numeric,numeric,numeric,text,text,boolean) TO authenticated;
10052
+ GRANT EXECUTE ON FUNCTION voorraad_voorraad_opslaan(uuid,uuid,text,numeric,numeric,numeric,text,text,boolean) TO service_role;
9705
10053
  CREATE OR REPLACE FUNCTION public.voorraad_week_is_past(p_year integer, p_week integer)
9706
10054
  RETURNS boolean
9707
10055
  LANGUAGE sql
@@ -9811,6 +10159,7 @@ DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'trade_i
9811
10159
  DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_buffer_state_pkey' AND conrelid = 'public.voorraad_buffer_state'::regclass) THEN ALTER TABLE public.voorraad_buffer_state ADD CONSTRAINT voorraad_buffer_state_pkey PRIMARY KEY (buffer_id); END IF; END $c$;
9812
10160
  DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_correcties_pkey' AND conrelid = 'public.voorraad_correcties'::regclass) THEN ALTER TABLE public.voorraad_correcties ADD CONSTRAINT voorraad_correcties_pkey PRIMARY KEY (id); END IF; END $c$;
9813
10161
  DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_custom_fields_pkey' AND conrelid = 'public.voorraad_custom_fields'::regclass) THEN ALTER TABLE public.voorraad_custom_fields ADD CONSTRAINT voorraad_custom_fields_pkey PRIMARY KEY (id); END IF; END $c$;
10162
+ DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_defaults_state_pkey' AND conrelid = 'public.voorraad_defaults_state'::regclass) THEN ALTER TABLE public.voorraad_defaults_state ADD CONSTRAINT voorraad_defaults_state_pkey PRIMARY KEY (id); END IF; END $c$;
9814
10163
  DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_load_carrier_types_pkey' AND conrelid = 'public.voorraad_load_carrier_types'::regclass) THEN ALTER TABLE public.voorraad_load_carrier_types ADD CONSTRAINT voorraad_load_carrier_types_pkey PRIMARY KEY (code); END IF; END $c$;
9815
10164
  DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_local_context_pkey' AND conrelid = 'public.voorraad_local_context'::regclass) THEN ALTER TABLE public.voorraad_local_context ADD CONSTRAINT voorraad_local_context_pkey PRIMARY KEY (id); END IF; END $c$;
9816
10165
  DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_logistics_event_log_pkey' AND conrelid = 'public.voorraad_logistics_event_log'::regclass) THEN ALTER TABLE public.voorraad_logistics_event_log ADD CONSTRAINT voorraad_logistics_event_log_pkey PRIMARY KEY (event_id); END IF; END $c$;
@@ -9874,9 +10223,11 @@ ALTER TABLE public.stock_import_runs ADD CONSTRAINT stock_import_runs_status_che
9874
10223
  ALTER TABLE public.stock_integrity_alerts DROP CONSTRAINT IF EXISTS stock_integrity_alerts_kind_check;
9875
10224
  ALTER TABLE public.stock_integrity_alerts ADD CONSTRAINT stock_integrity_alerts_kind_check CHECK ((alert_kind = ANY (ARRAY['ZERO_BATCH'::text, 'NEGATIVE_STOCK'::text, 'FLORIDAY_NOT_UPDATED'::text])));
9876
10225
  ALTER TABLE public.stock_mutation_log DROP CONSTRAINT IF EXISTS stock_mutation_log_mutation_type_check;
9877
- ALTER TABLE public.stock_mutation_log ADD CONSTRAINT stock_mutation_log_mutation_type_check CHECK ((mutation_type = ANY (ARRAY['reservation'::text, 'reservation_release'::text, 'consumption'::text, 'stock_check'::text, 'reservation_skipped'::text, 'consumption_skipped'::text, 'consumption_blocked'::text, 'production_consume'::text, 'production_output'::text, 'production_reverse'::text, 'manual_correction'::text, 'order_sync'::text, 'import'::text, 'production'::text, 'stock_update'::text, 'reservation_recompute'::text, 'unknown'::text, 'consumption_done'::text, 'new_article'::text])));
10226
+ ALTER TABLE public.stock_mutation_log ADD CONSTRAINT stock_mutation_log_mutation_type_check CHECK ((mutation_type = ANY (ARRAY['reservation'::text, 'reservation_release'::text, 'consumption'::text, 'stock_check'::text, 'reservation_skipped'::text, 'consumption_skipped'::text, 'consumption_blocked'::text, 'production_consume'::text, 'production_output'::text, 'production_reverse'::text, 'manual_correction'::text, 'order_sync'::text, 'import'::text, 'production'::text, 'stock_update'::text, 'reservation_recompute'::text, 'unknown'::text, 'consumption_done'::text, 'new_article'::text, 'manual_writeoff'::text])));
9878
10227
  ALTER TABLE public.trade_item_drafts DROP CONSTRAINT IF EXISTS trade_item_drafts_link_status_chk;
9879
10228
  ALTER TABLE public.trade_item_drafts ADD CONSTRAINT trade_item_drafts_link_status_chk CHECK ((floriday_link_status = ANY (ARRAY['unlinked'::text, 'linked'::text, 'waiting_for_data'::text, 'ready_to_publish'::text, 'publish_failed'::text, 'ambiguous_match'::text, 'published'::text])));
10229
+ ALTER TABLE public.voorraad_defaults_state DROP CONSTRAINT IF EXISTS voorraad_defaults_state_id_check;
10230
+ ALTER TABLE public.voorraad_defaults_state ADD CONSTRAINT voorraad_defaults_state_id_check CHECK (id);
9880
10231
  ALTER TABLE public.voorraad_local_context DROP CONSTRAINT IF EXISTS voorraad_local_context_singleton_check;
9881
10232
  ALTER TABLE public.voorraad_local_context ADD CONSTRAINT voorraad_local_context_singleton_check CHECK (singleton);
9882
10233
  DO $g$ BEGIN IF to_regclass('public.products') IS NULL THEN RAISE NOTICE 'Voorraad: products (core) ontbreekt, controles overgeslagen; draai de schema-update opnieuw na die module'; ELSE EXECUTE $q$DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'floriday_inventory_settings_product_id_fkey' AND conrelid = 'public.floriday_inventory_settings'::regclass) THEN ALTER TABLE public.floriday_inventory_settings ADD CONSTRAINT floriday_inventory_settings_product_id_fkey FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE CASCADE; END IF; END $c$$q$; END IF; END $g$;
@@ -10067,6 +10418,10 @@ ALTER TABLE public.voorraad_custom_fields ENABLE ROW LEVEL SECURITY;
10067
10418
  REVOKE ALL ON public.voorraad_custom_fields FROM anon;
10068
10419
  GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_custom_fields TO authenticated;
10069
10420
  GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_custom_fields TO service_role;
10421
+ ALTER TABLE public.voorraad_defaults_state ENABLE ROW LEVEL SECURITY;
10422
+ REVOKE ALL ON public.voorraad_defaults_state FROM anon;
10423
+ GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_defaults_state TO authenticated;
10424
+ GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_defaults_state TO service_role;
10070
10425
  ALTER TABLE public.voorraad_load_carrier_types ENABLE ROW LEVEL SECURITY;
10071
10426
  REVOKE ALL ON public.voorraad_load_carrier_types FROM anon;
10072
10427
  GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_load_carrier_types TO authenticated;
@@ -10218,6 +10573,8 @@ DROP POLICY IF EXISTS "Authenticated can read voorraad custom fields" ON public.
10218
10573
  CREATE POLICY "Authenticated can read voorraad custom fields" ON public.voorraad_custom_fields AS PERMISSIVE FOR SELECT TO authenticated USING (true);
10219
10574
  DROP POLICY IF EXISTS "Authenticated can update voorraad custom fields" ON public.voorraad_custom_fields;
10220
10575
  CREATE POLICY "Authenticated can update voorraad custom fields" ON public.voorraad_custom_fields AS PERMISSIVE FOR UPDATE TO authenticated USING (true) WITH CHECK (true);
10576
+ DROP POLICY IF EXISTS "Ingelogd mag standaardstatus lezen" ON public.voorraad_defaults_state;
10577
+ CREATE POLICY "Ingelogd mag standaardstatus lezen" ON public.voorraad_defaults_state AS PERMISSIVE FOR SELECT TO authenticated USING (true);
10221
10578
  DROP POLICY IF EXISTS "Ingelogd mag ladingdragers lezen" ON public.voorraad_load_carrier_types;
10222
10579
  CREATE POLICY "Ingelogd mag ladingdragers lezen" ON public.voorraad_load_carrier_types AS PERMISSIVE FOR SELECT TO authenticated USING (true);
10223
10580
  DROP POLICY IF EXISTS "Lokale context lezen" ON public.voorraad_local_context;
@@ -10380,6 +10737,8 @@ CREATE TRIGGER update_voorraad_publish_learnings_updated_at BEFORE UPDATE ON pub
10380
10737
  DROP TRIGGER IF EXISTS update_voorraad_publish_steps_updated_at ON public.voorraad_publish_steps;
10381
10738
  CREATE TRIGGER update_voorraad_publish_steps_updated_at BEFORE UPDATE ON public.voorraad_publish_steps FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
10382
10739
 
10740
+ -- standaardgegevens (systeemgegevens bijwerken, klantinstellingen alleen als ze ontbreken)
10741
+ SELECT public.voorraad_ensure_defaults();
10383
10742
  -- vaste taken
10384
10743
  DO $cron$
10385
10744
  BEGIN