@flowselections/floriday-voorraad 1.0.125 → 1.0.127

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.
@@ -0,0 +1,19 @@
1
+ export declare function voorraadPageHead(title: string, description: string): {
2
+ meta: ({
3
+ title: string;
4
+ name?: undefined;
5
+ content?: undefined;
6
+ property?: undefined;
7
+ } | {
8
+ name: string;
9
+ content: string;
10
+ title?: undefined;
11
+ property?: undefined;
12
+ } | {
13
+ property: string;
14
+ content: string;
15
+ title?: undefined;
16
+ name?: undefined;
17
+ })[];
18
+ };
19
+ //# sourceMappingURL=voorraad-page-head.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voorraad-page-head.d.ts","sourceRoot":"","sources":["../../src/lib/voorraad-page-head.ts"],"names":[],"mappings":"AAAA,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;;;;;;;;;;;;;;;;;EAUlE"}
@@ -0,0 +1,11 @@
1
+ export function voorraadPageHead(title, description) {
2
+ const fullTitle = `${title} — Floriday Voorraad`;
3
+ return { meta: [
4
+ { title: fullTitle },
5
+ { name: "description", content: description },
6
+ { property: "og:title", content: fullTitle },
7
+ { property: "og:description", content: description },
8
+ { property: "og:type", content: "website" },
9
+ { name: "twitter:card", content: "summary" },
10
+ ] };
11
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowselections/floriday-voorraad",
3
- "version": "1.0.125",
3
+ "version": "1.0.127",
4
4
  "sideEffects": false,
5
5
  "type": "module",
6
6
  "main": "./dist-lib/index.js",
@@ -1,4 +1,4 @@
1
- -- @flowselections/floriday-voorraad 1.0.124 – volledig schema (idempotent, geen gegevens).
1
+ -- @flowselections/floriday-voorraad 1.0.126 – volledig schema (idempotent, geen gegevens).
2
2
  -- Gegenereerd uit de database met scripts/generate-voorraad-schema.py. Niet met de hand wijzigen.
3
3
  -- Volgorde 20. Ontbrekende tabellen van andere modules worden overgeslagen met een NOTICE; draai opnieuw na die module.
4
4
  -- De statuscontrole van floriday_continuous_stock_queue is van Voorraad en wordt hier opnieuw gemaakt.
@@ -1145,8 +1145,8 @@ BEGIN
1145
1145
  END;
1146
1146
 
1147
1147
  SELECT COALESCE(
1148
- NULLIF(trim(COALESCE(p.floriday_trade_item_id, '')), ''),
1149
1148
  NULLIF(trim(COALESCE(p.trade_item_key, '')), ''),
1149
+ NULLIF(trim(COALESCE(p.floriday_trade_item_id, '')), ''),
1150
1150
  p.id::text
1151
1151
  )
1152
1152
  INTO v_canonical
@@ -4193,7 +4193,7 @@ BEGIN
4193
4193
  IF auth.uid() IS NULL AND NOT public.voorraad_is_server() THEN RAISE EXCEPTION 'Niet ingelogd' USING ERRCODE = '42501'; END IF;
4194
4194
  SELECT NULLIF(trim(COALESCE(p.floriday_trade_item_id, '')), ''), NULLIF(trim(COALESCE(p.trade_item_key, '')), '')
4195
4195
  INTO v_floriday_key, v_product_key FROM public.products p WHERE p.id = p_product_id;
4196
- v_key := COALESCE(v_floriday_key, v_product_key, 'product:' || p_product_id::text);
4196
+ v_key := COALESCE(v_product_key, v_floriday_key, 'product:' || p_product_id::text);
4197
4197
  SELECT * INTO v_ctx FROM public.get_stock_context();
4198
4198
  v_connection_id := v_ctx.connection_id;
4199
4199
 
@@ -5982,7 +5982,7 @@ BEGIN
5982
5982
  SELECT NULLIF(trim(COALESCE(p.floriday_trade_item_id, '')), ''), NULLIF(trim(COALESCE(p.trade_item_key, '')), '')
5983
5983
  INTO v_floriday_key, v_product_key FROM public.products p WHERE p.id = p_product_id;
5984
5984
  IF NOT FOUND THEN RAISE EXCEPTION 'Product niet gevonden'; END IF;
5985
- v_key := COALESCE(v_floriday_key, v_product_key, 'product:' || p_product_id::text);
5985
+ v_key := COALESCE(v_product_key, v_floriday_key, 'product:' || p_product_id::text);
5986
5986
 
5987
5987
  -- Context: Floriday-koppeling (omgeving, anders de enige actieve) of de lokale context.
5988
5988
  SELECT * INTO v_ctx FROM public.get_stock_context(true);
@@ -6463,53 +6463,18 @@ CREATE OR REPLACE FUNCTION public.sync_products_quantity_from_stock()
6463
6463
  SECURITY DEFINER
6464
6464
  SET search_path TO 'public'
6465
6465
  AS $function$
6466
- DECLARE
6467
- v_key text;
6468
- v_qty integer;
6469
- v_uuid uuid;
6466
+ DECLARE k text; c uuid;
6470
6467
  BEGIN
6471
- IF TG_OP = 'DELETE' THEN
6472
- v_key := OLD.trade_item_key;
6473
- v_qty := 0;
6474
- ELSE
6475
- v_key := NEW.trade_item_key;
6476
- v_qty := COALESCE(NEW.physical_stock, 0);
6477
- END IF;
6478
-
6479
- IF v_key IS NULL THEN
6480
- RETURN COALESCE(NEW, OLD);
6481
- END IF;
6482
-
6483
- -- Oude vorm `product:<uuid>`
6484
- IF position('product:' in v_key) = 1 THEN
6485
- BEGIN
6486
- v_uuid := substring(v_key from 9)::uuid;
6487
- EXCEPTION WHEN others THEN
6488
- v_uuid := NULL;
6489
- END;
6490
- IF v_uuid IS NOT NULL THEN
6491
- UPDATE public.products SET quantity = v_qty WHERE id = v_uuid;
6492
- END IF;
6493
- RETURN COALESCE(NEW, OLD);
6494
- END IF;
6495
-
6496
- -- Canonieke vorm: eigen sleutel of Floriday-artikel-ID
6497
- UPDATE public.products
6498
- SET quantity = v_qty
6499
- WHERE trade_item_key = v_key
6500
- OR floriday_trade_item_id::text = v_key;
6501
-
6502
- RETURN COALESCE(NEW, OLD);
6503
- END;
6504
- $function$
6468
+ PERFORM public.voorraad_vereis('ingelogd','sync_products_quantity_from_stock');
6469
+ k:=CASE WHEN TG_OP='DELETE' THEN OLD.trade_item_key ELSE NEW.trade_item_key END;
6470
+ c:=CASE WHEN TG_OP='DELETE' THEN OLD.connection_id ELSE NEW.connection_id END;
6471
+ UPDATE public.products p SET quantity=COALESCE((SELECT s.physical_stock FROM public.trade_item_stock s WHERE s.connection_id=c AND s.trade_item_key=COALESCE(NULLIF(btrim(p.trade_item_key),''),NULLIF(btrim(p.floriday_trade_item_id),''),'product:'||p.id::text)),0)
6472
+ WHERE p.trade_item_key=k OR p.floriday_trade_item_id=k OR 'product:'||p.id::text=k;
6473
+ RETURN COALESCE(NEW,OLD);
6474
+ END $function$
6505
6475
  ;
6506
6476
  REVOKE ALL ON FUNCTION sync_products_quantity_from_stock() FROM PUBLIC;
6507
6477
  REVOKE ALL ON FUNCTION sync_products_quantity_from_stock() FROM anon;
6508
- REVOKE EXECUTE ON FUNCTION sync_products_quantity_from_stock() FROM PUBLIC;
6509
- GRANT EXECUTE ON FUNCTION sync_products_quantity_from_stock() TO authenticated;
6510
- GRANT EXECUTE ON FUNCTION sync_products_quantity_from_stock() TO service_role;
6511
- REVOKE EXECUTE ON FUNCTION sync_products_quantity_from_stock() FROM anon;
6512
- GRANT EXECUTE ON FUNCTION sync_products_quantity_from_stock() TO authenticated;
6513
6478
  GRANT EXECUTE ON FUNCTION sync_products_quantity_from_stock() TO service_role;
6514
6479
  CREATE OR REPLACE FUNCTION public.touch_fust_types_updated_at()
6515
6480
  RETURNS trigger
@@ -7723,6 +7688,26 @@ GRANT EXECUTE ON FUNCTION trg_trade_items_cache_autolink_fn() TO service_role;
7723
7688
  REVOKE EXECUTE ON FUNCTION trg_trade_items_cache_autolink_fn() FROM anon;
7724
7689
  GRANT EXECUTE ON FUNCTION trg_trade_items_cache_autolink_fn() TO authenticated;
7725
7690
  GRANT EXECUTE ON FUNCTION trg_trade_items_cache_autolink_fn() TO service_role;
7691
+ CREATE OR REPLACE FUNCTION public.trg_voorraad_link_primary_packing()
7692
+ RETURNS trigger
7693
+ LANGUAGE plpgsql
7694
+ SECURITY DEFINER
7695
+ SET search_path TO 'public'
7696
+ AS $function$
7697
+ BEGIN
7698
+ PERFORM public.voorraad_vereis('ingelogd','trg_voorraad_link_primary_packing');
7699
+ IF NULLIF(btrim(NEW.floriday_trade_item_id),'') IS NOT NULL THEN
7700
+ IF TG_OP='INSERT' OR NEW.floriday_trade_item_id IS DISTINCT FROM OLD.floriday_trade_item_id THEN
7701
+ PERFORM public.voorraad_packing_from_floriday(NEW.id,true);
7702
+ END IF;
7703
+ END IF;
7704
+ RETURN NEW;
7705
+ END $function$
7706
+ ;
7707
+ REVOKE ALL ON FUNCTION trg_voorraad_link_primary_packing() FROM PUBLIC;
7708
+ REVOKE ALL ON FUNCTION trg_voorraad_link_primary_packing() FROM anon;
7709
+ GRANT EXECUTE ON FUNCTION trg_voorraad_link_primary_packing() TO authenticated;
7710
+ GRANT EXECUTE ON FUNCTION trg_voorraad_link_primary_packing() TO service_role;
7726
7711
  CREATE OR REPLACE FUNCTION public.update_updated_at_column()
7727
7712
  RETURNS trigger
7728
7713
  LANGUAGE plpgsql
@@ -8546,47 +8531,88 @@ CREATE OR REPLACE FUNCTION public.voorraad_correctie_1124(p_uitvoeren boolean DE
8546
8531
  SECURITY DEFINER
8547
8532
  SET search_path TO 'public'
8548
8533
  AS $function$
8549
- DECLARE
8550
- c_product constant uuid := '4e62fc60-e9b7-468f-8cc4-cdf64b938f57';
8551
- c_fid constant text := 'c3406752-b5e0-438b-b3a9-109b58b9e970';
8552
- c_prijs constant numeric := 2.40;
8553
- v_p record; v_ander int; v_voor jsonb; v_na jsonb; v_status text; v_fid_rows int;
8554
- BEGIN
8555
- PERFORM public.voorraad_vereis('server', 'voorraad_correctie_1124');
8556
- SELECT * INTO v_p FROM public.products WHERE id = c_product FOR UPDATE;
8557
- SELECT count(*) INTO v_ander FROM public.products WHERE id <> c_product AND floriday_trade_item_id = c_fid;
8558
- SELECT count(*) INTO v_fid_rows FROM public.trade_item_stock WHERE trade_item_key = c_fid;
8559
- SELECT COALESCE(jsonb_agg(jsonb_build_object('id', s.id, 'sleutel', s.trade_item_key, 'koppeling', s.connection_id,
8560
- 'fysiek', s.physical_stock, 'gereserveerd', s.reserved_stock, 'inkomend', s.incoming_stock) ORDER BY s.trade_item_key), '[]'::jsonb)
8561
- INTO v_voor FROM public.trade_item_stock s WHERE s.trade_item_key IN (c_fid, 'product:' || c_product::text, c_product::text);
8562
- IF v_p.id IS NULL THEN v_status := 'overgeslagen: artikel niet in deze database';
8563
- ELSIF v_ander > 0 THEN v_status := 'overgeslagen: Floriday-artikel al aan ander artikel gekoppeld';
8564
- ELSIF v_p.floriday_trade_item_id IS NOT NULL AND v_p.floriday_trade_item_id <> c_fid THEN v_status := 'overgeslagen: al aan ander Floriday-artikel gekoppeld';
8565
- ELSIF v_fid_rows <> 1 THEN v_status := 'overgeslagen: verwacht precies één voorraadrij op de Floriday-sleutel, gevonden ' || v_fid_rows;
8566
- ELSIF v_p.floriday_trade_item_id = c_fid AND v_p.sale_price = c_prijs THEN v_status := 'al uitgevoerd';
8567
- ELSE v_status := CASE WHEN p_uitvoeren THEN 'uitgevoerd' ELSE 'voorstel' END;
8568
- END IF;
8569
- IF v_status = 'uitgevoerd' THEN
8570
- UPDATE public.products SET floriday_trade_item_id = COALESCE(floriday_trade_item_id, c_fid), sale_price = c_prijs, updated_at = now()
8571
- WHERE id = c_product;
8572
- SELECT COALESCE(jsonb_agg(jsonb_build_object('id', s.id, 'sleutel', s.trade_item_key, 'koppeling', s.connection_id,
8573
- 'fysiek', s.physical_stock, 'gereserveerd', s.reserved_stock, 'inkomend', s.incoming_stock) ORDER BY s.trade_item_key), '[]'::jsonb)
8574
- INTO v_na FROM public.trade_item_stock s WHERE s.trade_item_key IN (c_fid, 'product:' || c_product::text, c_product::text);
8575
- INSERT INTO public.voorraad_correcties(correctie, uitgevoerd_door, proef, aantallen, hash_ok)
8576
- VALUES ('voorraad_correctie_1124', COALESCE(auth.uid()::text, session_user::text), false,
8577
- jsonb_build_object('artikel', c_product, 'floriday_id', c_fid, 'prijs_voor', v_p.sale_price, 'prijs_na', c_prijs,
8578
- 'voorraad_voor', v_voor, 'voorraad_na', v_na), NULL);
8579
- END IF;
8580
- RETURN jsonb_build_object('ok', true, 'proef', NOT p_uitvoeren, 'status', v_status,
8581
- 'artikel', jsonb_build_object('id', c_product, 'code', v_p.article_number, 'floriday_id_voor', v_p.floriday_trade_item_id,
8582
- 'floriday_id_na', c_fid, 'prijs_voor', v_p.sale_price, 'prijs_na', c_prijs),
8583
- 'voorraad_voor', v_voor, 'voorraad_na', COALESCE(v_na, v_voor),
8584
- 'uitleg', 'Lijst en Floriday-publicatie lezen na koppelen de Floriday-sleutel (500). De rij op de eigen sleutel staat op 0 en telt dus niet dubbel.');
8534
+ BEGIN
8535
+ PERFORM public.voorraad_vereis('server','voorraad_correctie_1124');
8536
+ RETURN public.voorraad_correctie_1126(p_uitvoeren);
8585
8537
  END $function$
8586
8538
  ;
8587
8539
  REVOKE ALL ON FUNCTION voorraad_correctie_1124(boolean) FROM PUBLIC;
8588
8540
  REVOKE ALL ON FUNCTION voorraad_correctie_1124(boolean) FROM anon;
8589
8541
  GRANT EXECUTE ON FUNCTION voorraad_correctie_1124(boolean) TO service_role;
8542
+ CREATE OR REPLACE FUNCTION public.voorraad_correctie_1126(p_uitvoeren boolean DEFAULT false)
8543
+ RETURNS jsonb
8544
+ LANGUAGE plpgsql
8545
+ SECURITY DEFINER
8546
+ SET search_path TO 'public'
8547
+ AS $function$
8548
+ DECLARE
8549
+ pid constant uuid:='4e62fc60-e9b7-468f-8cc4-cdf64b938f57'; fid constant text:='c3406752-b5e0-438b-b3a9-109b58b9e970';
8550
+ p record; ctx record; ownrow record; fdrow record; before_rows jsonb; after_rows jsonb; ch text; qh text; unchanged boolean; status text; result jsonb; handled text;
8551
+ BEGIN
8552
+ PERFORM public.voorraad_vereis('server','voorraad_correctie_1126');
8553
+ PERFORM pg_advisory_xact_lock(hashtextextended('voorraad_correctie_1126',0));
8554
+ SELECT * INTO p FROM public.products WHERE id=pid FOR UPDATE;
8555
+ SELECT * INTO ctx FROM public.get_stock_context();
8556
+ PERFORM 1 FROM public.trade_item_stock WHERE connection_id=ctx.connection_id AND trade_item_key IN(p.trade_item_key,fid) ORDER BY id FOR UPDATE;
8557
+ SELECT * INTO ownrow FROM public.trade_item_stock WHERE connection_id=ctx.connection_id AND trade_item_key=p.trade_item_key;
8558
+ SELECT * INTO fdrow FROM public.trade_item_stock WHERE connection_id=ctx.connection_id AND trade_item_key=fid;
8559
+ SELECT jsonb_agg(to_jsonb(s) ORDER BY s.id) INTO before_rows FROM public.trade_item_stock s WHERE s.id IN(ownrow.id,fdrow.id);
8560
+ SELECT md5(COALESCE(string_agg(t::text,'|' ORDER BY t::text),'')) INTO ch FROM public.floriday_trade_items_cache t;
8561
+ SELECT md5(COALESCE(string_agg(t::text,'|' ORDER BY t::text),'')) INTO qh FROM public.floriday_continuous_stock_queue t;
8562
+ IF p.id IS NULL OR p.article_number IS DISTINCT FROM 'TQA2710G' OR p.floriday_trade_item_id IS DISTINCT FROM fid OR p.trade_item_key IS DISTINCT FROM 'product:'||pid::text THEN status:='overgeslagen: artikel/koppeling/sleutel wijkt af';
8563
+ ELSIF ownrow.id IS NULL OR fdrow.id IS NULL OR ownrow.reserved_stock<>0 OR fdrow.reserved_stock<>0 OR ownrow.incoming_stock<>0 OR fdrow.incoming_stock<>0 THEN status:='overgeslagen: voorraadrij ontbreekt of reservering/inkomend gewijzigd';
8564
+ ELSIF ownrow.physical_stock=500 AND fdrow.physical_stock=0 THEN status:='al uitgevoerd';
8565
+ ELSIF ownrow.physical_stock<>0 OR fdrow.physical_stock<>500 OR p.sale_price<>2.40 THEN status:='overgeslagen: stand of prijs gewijzigd';
8566
+ ELSE status:=CASE WHEN p_uitvoeren THEN 'uitgevoerd' ELSE 'voorstel' END; END IF;
8567
+ IF status='uitgevoerd' THEN
8568
+ handled:=COALESCE(NULLIF(current_setting('stock.log_handled',true),''),';');
8569
+ PERFORM set_config('stock.log_handled',handled||ctx.connection_id||'|'||fid||'|0|0;'||ctx.connection_id||'|'||p.trade_item_key||'|500|0;',true);
8570
+ UPDATE public.trade_item_stock SET physical_stock=0,change_source='FLORIDAY_PUBLICATION',updated_at=now() WHERE id=fdrow.id;
8571
+ UPDATE public.trade_item_stock SET physical_stock=500,change_source='FLORIDAY_PUBLICATION',updated_at=now() WHERE id=ownrow.id;
8572
+ INSERT INTO public.stock_mutation_log(trade_item_key,connection_id,mutation_type,qty_delta,physical_before,physical_after,reserved_before,reserved_after,reason,created_by)
8573
+ VALUES(fid,ctx.connection_id,'manual_correction',-500,500,0,0,0,'[correctie_1126] TQA2710G tegenboeking verkeerde Floriday-sleutel; voorraad naar eigen leessleutel',auth.uid()),
8574
+ (p.trade_item_key,ctx.connection_id,'manual_correction',500,0,500,0,0,'[correctie_1126] TQA2710G 500 op eigen leessleutel; geen dubbele voorraad',auth.uid());
8575
+ PERFORM set_config('stock.log_handled',handled,true);
8576
+ END IF;
8577
+ SELECT jsonb_agg(to_jsonb(s) ORDER BY s.id) INTO after_rows FROM public.trade_item_stock s WHERE s.id IN(ownrow.id,fdrow.id);
8578
+ unchanged:=ch=(SELECT md5(COALESCE(string_agg(t::text,'|' ORDER BY t::text),'')) FROM public.floriday_trade_items_cache t) AND qh=(SELECT md5(COALESCE(string_agg(t::text,'|' ORDER BY t::text),'')) FROM public.floriday_continuous_stock_queue t);
8579
+ IF NOT unchanged THEN RAISE EXCEPTION 'Floriday-kopie of wachtrij gewijzigd; correctie teruggedraaid'; END IF;
8580
+ result:=jsonb_build_object('ok',status NOT LIKE 'overgeslagen%','status',status,'voor',before_rows,'na',after_rows,'hash_ok',unchanged,'prijs',p.sale_price,'sleutel',p.trade_item_key);
8581
+ INSERT INTO public.voorraad_correcties(correctie,uitgevoerd_door,proef,aantallen,hash_ok) VALUES('voorraad_correctie_1126',COALESCE(auth.uid()::text,session_user::text),NOT p_uitvoeren,result,unchanged);
8582
+ RETURN result;
8583
+ END $function$
8584
+ ;
8585
+ REVOKE ALL ON FUNCTION voorraad_correctie_1126(boolean) FROM PUBLIC;
8586
+ REVOKE ALL ON FUNCTION voorraad_correctie_1126(boolean) FROM anon;
8587
+ GRANT EXECUTE ON FUNCTION voorraad_correctie_1126(boolean) TO service_role;
8588
+ CREATE OR REPLACE FUNCTION public.voorraad_correctie_1127(p_uitvoeren boolean DEFAULT false)
8589
+ RETURNS jsonb
8590
+ LANGUAGE plpgsql
8591
+ SECURITY DEFINER
8592
+ SET search_path TO 'public'
8593
+ AS $function$
8594
+ DECLARE pid constant uuid:='4e62fc60-e9b7-468f-8cc4-cdf64b938f57'; r jsonb; ch text; qh text; okhash boolean;
8595
+ BEGIN
8596
+ PERFORM public.voorraad_vereis('server','voorraad_correctie_1127');
8597
+ PERFORM 1 FROM public.products WHERE id=pid FOR UPDATE;
8598
+ SELECT md5(COALESCE(string_agg(t::text,'|' ORDER BY t::text),'')) INTO ch FROM public.floriday_trade_items_cache t;
8599
+ SELECT md5(COALESCE(string_agg(t::text,'|' ORDER BY t::text),'')) INTO qh FROM public.floriday_continuous_stock_queue t;
8600
+ r:=public.voorraad_packing_from_floriday(pid,false);
8601
+ IF NOT EXISTS(SELECT 1 FROM public.product_packings WHERE product_id=pid AND is_primary) THEN
8602
+ IF NOT COALESCE((r->>'ok')::boolean,false) OR (r#>>'{packing,package,vbnPackageCode}',r#>>'{packing,piecesPerPackage}',r#>>'{packing,packagesPerLayer}',r#>>'{packing,layersPerLoadCarrier}',r#>>'{packing,loadCarrier}') IS DISTINCT FROM ('412','12','5','8','DANISH_TROLLEY') THEN
8603
+ RAISE EXCEPTION 'Floriday-belading wijkt af van het goedgekeurde overzicht; niets overgenomen';
8604
+ END IF;
8605
+ END IF;
8606
+ IF p_uitvoeren THEN r:=public.voorraad_packing_from_floriday(pid,true); END IF;
8607
+ okhash:=ch=(SELECT md5(COALESCE(string_agg(t::text,'|' ORDER BY t::text),'')) FROM public.floriday_trade_items_cache t) AND qh=(SELECT md5(COALESCE(string_agg(t::text,'|' ORDER BY t::text),'')) FROM public.floriday_continuous_stock_queue t);
8608
+ IF NOT okhash THEN RAISE EXCEPTION 'Floriday-kopie of wachtrij gewijzigd; correctie teruggedraaid'; END IF;
8609
+ INSERT INTO public.voorraad_correcties(correctie,uitgevoerd_door,proef,aantallen,hash_ok) VALUES('voorraad_correctie_1127',COALESCE(auth.uid()::text,session_user::text),NOT p_uitvoeren,r,okhash);
8610
+ RETURN r||jsonb_build_object('hash_ok',okhash);
8611
+ END $function$
8612
+ ;
8613
+ REVOKE ALL ON FUNCTION voorraad_correctie_1127(boolean) FROM PUBLIC;
8614
+ REVOKE ALL ON FUNCTION voorraad_correctie_1127(boolean) FROM anon;
8615
+ GRANT EXECUTE ON FUNCTION voorraad_correctie_1127(boolean) TO service_role;
8590
8616
  CREATE OR REPLACE FUNCTION public.voorraad_correctie_status(p_correctie text DEFAULT '1098'::text)
8591
8617
  RETURNS jsonb
8592
8618
  LANGUAGE plpgsql
@@ -8895,8 +8921,8 @@ CREATE OR REPLACE FUNCTION public.voorraad_install_check()
8895
8921
  STABLE SECURITY DEFINER
8896
8922
  SET search_path TO 'public'
8897
8923
  AS $function$
8898
- DECLARE v_f text[] := ARRAY['voorraad_fust_juist','voorraad_correctie_1121','voorraad_correctie_1121_regels','voorraad_correctie_1123','voorraad_correctie_1124','voorraad_load_carriers','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'];
8899
- v_t text[] := ARRAY['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'];
8924
+ DECLARE v_f text[] := ARRAY['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'];
8925
+ 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'];
8900
8926
  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'];
8901
8927
  v_open text[] := ARRAY['voorraad_is_server','voorraad_vereis'];
8902
8928
  v_func jsonb; v_trig jsonb; v_pol jsonb;
@@ -9021,6 +9047,69 @@ GRANT EXECUTE ON FUNCTION voorraad_order_geannuleerd(text,timestamp with time zo
9021
9047
  REVOKE EXECUTE ON FUNCTION voorraad_order_geannuleerd(text,timestamp with time zone,timestamp with time zone) FROM anon;
9022
9048
  GRANT EXECUTE ON FUNCTION voorraad_order_geannuleerd(text,timestamp with time zone,timestamp with time zone) TO authenticated;
9023
9049
  GRANT EXECUTE ON FUNCTION voorraad_order_geannuleerd(text,timestamp with time zone,timestamp with time zone) TO service_role;
9050
+ CREATE OR REPLACE FUNCTION public.voorraad_packing_from_floriday(p_product_id uuid, p_uitvoeren boolean)
9051
+ RETURNS jsonb
9052
+ LANGUAGE plpgsql
9053
+ SET search_path TO 'public'
9054
+ AS $function$
9055
+ DECLARE p record; ctx record; cfg jsonb; d jsonb; missing text[]:='{}'; n int; f uuid; result jsonb; msg text; copied boolean:=false;
9056
+ BEGIN
9057
+ PERFORM public.voorraad_vereis('ingelogd','voorraad_packing_from_floriday');
9058
+ IF NOT public.voorraad_can_write() AND NOT public.voorraad_is_server() THEN RAISE EXCEPTION 'Geen toestemming om belading op te slaan' USING ERRCODE='42501'; END IF;
9059
+ SELECT * INTO p FROM public.products WHERE id=p_product_id FOR UPDATE;
9060
+ IF NOT FOUND THEN RAISE EXCEPTION 'Artikel niet gevonden' USING ERRCODE='P0001'; END IF;
9061
+ IF EXISTS(SELECT 1 FROM public.product_packings WHERE product_id=p_product_id AND is_primary) THEN
9062
+ RETURN jsonb_build_object('ok',true,'copied',false,'melding','Hoofdverpakking bestaat al; niets overschreven');
9063
+ END IF;
9064
+ SELECT * INTO ctx FROM public.get_stock_context();
9065
+ SELECT c.data INTO d FROM public.floriday_trade_items_cache c WHERE c.connection_id=ctx.connection_id AND c.floriday_id=p.floriday_trade_item_id AND NOT COALESCE(c.is_deleted,false);
9066
+ IF d IS NULL THEN msg:='Hoofdverpakking niet overgenomen: artikel ontbreekt in de Floriday-kopie';
9067
+ ELSE
9068
+ SELECT count(*),jsonb_agg(e)->0 INTO n,cfg FROM jsonb_array_elements(CASE WHEN jsonb_typeof(d->'packingConfigurations')='array' THEN d->'packingConfigurations' ELSE '[]'::jsonb END) e WHERE e->'primary'='true'::jsonb;
9069
+ IF n<>1 THEN msg:='Hoofdverpakking niet overgenomen: verwacht één primaire Floriday-verpakking, gevonden '||n;
9070
+ ELSE
9071
+ missing:=public.voorraad_packing_missing(cfg);IF cardinality(missing)>0 THEN msg:='Hoofdverpakking niet overgenomen: ontbrekend of ongeldig: '||array_to_string(missing,', ');
9072
+ ELSE
9073
+ SELECT public.voorraad_active_fust_id(NULL,ft.id) INTO f FROM public.fust_types ft WHERE ft.vbn_code::text=cfg#>>'{package,vbnPackageCode}' AND ft.merged_into IS NULL ORDER BY ft.id LIMIT 1;
9074
+ IF p_uitvoeren THEN
9075
+ INSERT INTO public.product_packings(product_id,source,floriday_packing_id,vbn_package_code,fust_type_id,load_carrier,pieces_per_package,packages_per_layer,layers_per_load_carrier,is_primary,customer_organization_ids)
9076
+ VALUES(p_product_id,'floriday',COALESCE(cfg->>'packingConfigurationId',cfg->>'id'),(cfg#>>'{package,vbnPackageCode}')::int,f,cfg->>'loadCarrier',(cfg->>'piecesPerPackage')::int,(cfg->>'packagesPerLayer')::int,(cfg->>'layersPerLoadCarrier')::int,true,ARRAY(SELECT jsonb_array_elements_text(COALESCE(cfg->'allowedCustomerOrganizationIds','[]'::jsonb))));
9077
+ copied:=true;
9078
+ END IF;
9079
+ msg:=CASE WHEN p_uitvoeren THEN 'Hoofdverpakking overgenomen uit Floriday' ELSE 'Volledige hoofdverpakking beschikbaar om over te nemen' END;
9080
+ END IF;
9081
+ END IF;
9082
+ END IF;
9083
+ result:=jsonb_build_object('ok',msg NOT LIKE 'Hoofdverpakking niet%','copied',copied,'melding',msg,'missing',to_jsonb(missing),'packing',cfg);
9084
+ IF p_uitvoeren THEN UPDATE public.products SET custom_fields=jsonb_set(COALESCE(custom_fields,'{}'::jsonb),'{voorraad_packing_link}',result,true) WHERE id=p_product_id; END IF;
9085
+ RETURN result;
9086
+ END $function$
9087
+ ;
9088
+ REVOKE ALL ON FUNCTION voorraad_packing_from_floriday(uuid,boolean) FROM PUBLIC;
9089
+ REVOKE ALL ON FUNCTION voorraad_packing_from_floriday(uuid,boolean) FROM anon;
9090
+ GRANT EXECUTE ON FUNCTION voorraad_packing_from_floriday(uuid,boolean) TO authenticated;
9091
+ GRANT EXECUTE ON FUNCTION voorraad_packing_from_floriday(uuid,boolean) TO service_role;
9092
+ CREATE OR REPLACE FUNCTION public.voorraad_packing_missing(p_packing jsonb)
9093
+ RETURNS text[]
9094
+ LANGUAGE plpgsql
9095
+ STABLE
9096
+ SET search_path TO 'public'
9097
+ AS $function$
9098
+ DECLARE missing text[]:='{}';
9099
+ BEGIN
9100
+ PERFORM public.voorraad_vereis('ingelogd','voorraad_packing_missing');
9101
+ IF COALESCE(p_packing#>>'{package,vbnPackageCode}','') !~ '^[1-9][0-9]{0,8}$' THEN missing:=array_append(missing,'fust (vbnPackageCode)'); END IF;
9102
+ IF COALESCE(p_packing->>'piecesPerPackage','') !~ '^[1-9][0-9]{0,8}$' THEN missing:=array_append(missing,'planten per fust'); END IF;
9103
+ IF COALESCE(p_packing->>'packagesPerLayer','') !~ '^[1-9][0-9]{0,8}$' THEN missing:=array_append(missing,'fusten per laag'); END IF;
9104
+ IF COALESCE(p_packing->>'layersPerLoadCarrier','') !~ '^[1-9][0-9]{0,8}$' THEN missing:=array_append(missing,'lagen per kar'); END IF;
9105
+ IF NOT EXISTS(SELECT 1 FROM public.voorraad_load_carrier_types WHERE code=p_packing->>'loadCarrier') THEN missing:=array_append(missing,'ladingdrager'); END IF;
9106
+ RETURN missing;
9107
+ END $function$
9108
+ ;
9109
+ REVOKE ALL ON FUNCTION voorraad_packing_missing(jsonb) FROM PUBLIC;
9110
+ REVOKE ALL ON FUNCTION voorraad_packing_missing(jsonb) FROM anon;
9111
+ GRANT EXECUTE ON FUNCTION voorraad_packing_missing(jsonb) TO authenticated;
9112
+ GRANT EXECUTE ON FUNCTION voorraad_packing_missing(jsonb) TO service_role;
9024
9113
  CREATE OR REPLACE FUNCTION public.voorraad_production_enabled()
9025
9114
  RETURNS boolean
9026
9115
  LANGUAGE sql
@@ -9917,6 +10006,7 @@ DO $g$ BEGIN IF to_regclass('public.products') IS NULL THEN RAISE NOTICE 'Voorra
9917
10006
  DO $g$ BEGIN IF to_regclass('public.products') IS NULL THEN RAISE NOTICE 'Voorraad: products (core) ontbreekt, triggers overgeslagen; draai de schema-update opnieuw na die module'; ELSE EXECUTE $q$CREATE TRIGGER trg_products_floriday_link_enqueue AFTER UPDATE ON public.products REFERENCING OLD TABLE AS old_rows NEW TABLE AS new_rows FOR EACH STATEMENT EXECUTE FUNCTION trg_products_floriday_link_enqueue()$q$; END IF; END $g$;
9918
10007
  DO $g$ BEGIN IF to_regclass('public.products') IS NULL THEN RAISE NOTICE 'Voorraad: products (core) ontbreekt, triggers overgeslagen; draai de schema-update opnieuw na die module'; ELSE EXECUTE $q$CREATE TRIGGER trg_products_seed_stock AFTER INSERT OR UPDATE OF trade_item_key ON public.products FOR EACH ROW EXECUTE FUNCTION trg_products_seed_stock_fn()$q$; END IF; END $g$;
9919
10008
  DO $g$ BEGIN IF to_regclass('public.products') IS NULL THEN RAISE NOTICE 'Voorraad: products (core) ontbreekt, triggers overgeslagen; draai de schema-update opnieuw na die module'; ELSE EXECUTE $q$CREATE TRIGGER trg_requeue_skipped_no_price AFTER UPDATE OF sale_price, unit ON public.products FOR EACH ROW EXECUTE FUNCTION trg_requeue_skipped_no_price()$q$; END IF; END $g$;
10009
+ DO $g$ BEGIN IF to_regclass('public.products') IS NULL THEN RAISE NOTICE 'Voorraad: products (core) ontbreekt, triggers overgeslagen; draai de schema-update opnieuw na die module'; ELSE EXECUTE $q$CREATE TRIGGER trg_voorraad_link_primary_packing AFTER INSERT OR UPDATE OF floriday_trade_item_id ON public.products FOR EACH ROW EXECUTE FUNCTION trg_voorraad_link_primary_packing()$q$; END IF; END $g$;
9920
10010
  DROP TRIGGER IF EXISTS trg_stock_mutation_alert ON public.stock_mutation_log;
9921
10011
  CREATE TRIGGER trg_stock_mutation_alert AFTER INSERT ON public.stock_mutation_log FOR EACH ROW EXECUTE FUNCTION trg_stock_mutation_alert_fn();
9922
10012
  DROP TRIGGER IF EXISTS trg_prevent_duplicate_product_draft ON public.trade_item_drafts;