@flowselections/floriday-voorraad 1.0.164 → 1.0.165
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.
- package/dist-lib/components/fs-ui/DataTable.d.ts.map +1 -1
- package/dist-lib/components/fs-ui/DataTable.js +2 -2
- package/dist-lib/components/voorraad/VoorraadPage.d.ts.map +1 -1
- package/dist-lib/components/voorraad/VoorraadPage.js +86 -6
- package/dist-lib/components/voorraad/artikel/ArtikelPagina.d.ts.map +1 -1
- package/dist-lib/components/voorraad/artikel/ArtikelPagina.js +10 -2
- package/dist-lib/components/voorraad/lijst/VoorraadLijstTabel.d.ts +3 -1
- package/dist-lib/components/voorraad/lijst/VoorraadLijstTabel.d.ts.map +1 -1
- package/dist-lib/components/voorraad/lijst/VoorraadLijstTabel.js +5 -2
- package/dist-lib/hooks/useVoorraadLijst.d.ts +4 -5
- package/dist-lib/hooks/useVoorraadLijst.d.ts.map +1 -1
- package/dist-lib/hooks/useVoorraadLijst.js +23 -5
- package/dist-lib/hooks-entry.d.ts +1 -0
- package/dist-lib/hooks-entry.d.ts.map +1 -1
- package/dist-lib/hooks-entry.js +1 -0
- package/dist-lib/integrations/supabase/types.d.ts +537 -0
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/lijst-stand.d.ts +31 -0
- package/dist-lib/lib/lijst-stand.d.ts.map +1 -0
- package/dist-lib/lib/lijst-stand.js +77 -0
- package/dist-lib/lib/voorraad-push-melding.d.ts +10 -0
- package/dist-lib/lib/voorraad-push-melding.d.ts.map +1 -0
- package/dist-lib/lib/voorraad-push-melding.js +11 -0
- package/dist-lib/server-hooks/floriday-mutaties.d.ts +3 -0
- package/dist-lib/server-hooks/floriday-mutaties.d.ts.map +1 -0
- package/dist-lib/server-hooks/floriday-mutaties.js +70 -0
- package/dist-lib/server-hooks/guard.d.ts.map +1 -1
- package/dist-lib/server-hooks/guard.js +1 -1
- package/package.json +22 -1
- package/sql/AGENTS.md +2 -0
- package/sql/floriday-voorraad-schema.sql +1454 -902
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
-- @flowselections/floriday-voorraad 1.0.
|
|
2
|
-
-- Laatste migratie:
|
|
1
|
+
-- @flowselections/floriday-voorraad 1.0.164 – volledig schema (idempotent, geen gegevens).
|
|
2
|
+
-- Laatste migratie: 20261107133040_e0b29cec-5ee3-487e-99bd-5f3b66b8da4f.sql
|
|
3
3
|
-- Gegenereerd uit de database met scripts/generate-voorraad-schema.py. Niet met de hand wijzigen.
|
|
4
4
|
-- Volgorde 20. Ontbrekende tabellen van andere modules worden overgeslagen met een NOTICE; draai opnieuw na die module.
|
|
5
5
|
-- De statuscontrole van floriday_continuous_stock_queue is van Voorraad en wordt hier opnieuw gemaakt.
|
|
@@ -61,6 +61,7 @@ ALTER TABLE public.floriday_continuous_stock_queue ADD COLUMN IF NOT EXISTS base
|
|
|
61
61
|
ALTER TABLE public.floriday_continuous_stock_queue ADD COLUMN IF NOT EXISTS price_status text;
|
|
62
62
|
ALTER TABLE public.floriday_continuous_stock_queue ADD COLUMN IF NOT EXISTS price_note text;
|
|
63
63
|
ALTER TABLE public.floriday_continuous_stock_queue ADD COLUMN IF NOT EXISTS price_previous numeric;
|
|
64
|
+
ALTER TABLE public.floriday_continuous_stock_queue ADD COLUMN IF NOT EXISTS voorraad_mutatie boolean DEFAULT false NOT NULL;
|
|
64
65
|
|
|
65
66
|
-- floriday_inventory_settings
|
|
66
67
|
CREATE TABLE IF NOT EXISTS public.floriday_inventory_settings ();
|
|
@@ -348,6 +349,39 @@ ALTER TABLE public.product_tray_stickers ADD COLUMN IF NOT EXISTS bestandsgroott
|
|
|
348
349
|
ALTER TABLE public.product_tray_stickers ADD COLUMN IF NOT EXISTS created_at timestamp with time zone DEFAULT now() NOT NULL;
|
|
349
350
|
ALTER TABLE public.product_tray_stickers ADD COLUMN IF NOT EXISTS updated_at timestamp with time zone DEFAULT now() NOT NULL;
|
|
350
351
|
|
|
352
|
+
-- productie_order_onderdelen
|
|
353
|
+
CREATE TABLE IF NOT EXISTS public.productie_order_onderdelen ();
|
|
354
|
+
ALTER TABLE public.productie_order_onderdelen ADD COLUMN IF NOT EXISTS id uuid DEFAULT gen_random_uuid() NOT NULL;
|
|
355
|
+
ALTER TABLE public.productie_order_onderdelen ADD COLUMN IF NOT EXISTS productie_order_id uuid NOT NULL;
|
|
356
|
+
ALTER TABLE public.productie_order_onderdelen ADD COLUMN IF NOT EXISTS product_id uuid;
|
|
357
|
+
ALTER TABLE public.productie_order_onderdelen ADD COLUMN IF NOT EXISTS trade_item_key text NOT NULL;
|
|
358
|
+
ALTER TABLE public.productie_order_onderdelen ADD COLUMN IF NOT EXISTS naam text;
|
|
359
|
+
ALTER TABLE public.productie_order_onderdelen ADD COLUMN IF NOT EXISTS aantal numeric NOT NULL;
|
|
360
|
+
ALTER TABLE public.productie_order_onderdelen ADD COLUMN IF NOT EXISTS created_at timestamp with time zone DEFAULT now() NOT NULL;
|
|
361
|
+
|
|
362
|
+
-- productie_orders
|
|
363
|
+
CREATE TABLE IF NOT EXISTS public.productie_orders ();
|
|
364
|
+
ALTER TABLE public.productie_orders ADD COLUMN IF NOT EXISTS id uuid DEFAULT gen_random_uuid() NOT NULL;
|
|
365
|
+
ALTER TABLE public.productie_orders ADD COLUMN IF NOT EXISTS nummer text NOT NULL;
|
|
366
|
+
ALTER TABLE public.productie_orders ADD COLUMN IF NOT EXISTS product_id uuid NOT NULL;
|
|
367
|
+
ALTER TABLE public.productie_orders ADD COLUMN IF NOT EXISTS trade_item_key text NOT NULL;
|
|
368
|
+
ALTER TABLE public.productie_orders ADD COLUMN IF NOT EXISTS aantal numeric NOT NULL;
|
|
369
|
+
ALTER TABLE public.productie_orders ADD COLUMN IF NOT EXISTS status text DEFAULT 'open'::text NOT NULL;
|
|
370
|
+
ALTER TABLE public.productie_orders ADD COLUMN IF NOT EXISTS opmerking text;
|
|
371
|
+
ALTER TABLE public.productie_orders ADD COLUMN IF NOT EXISTS aangemaakt_door uuid;
|
|
372
|
+
ALTER TABLE public.productie_orders ADD COLUMN IF NOT EXISTS aangemaakt_op timestamp with time zone DEFAULT now() NOT NULL;
|
|
373
|
+
ALTER TABLE public.productie_orders ADD COLUMN IF NOT EXISTS verwerkt_door uuid;
|
|
374
|
+
ALTER TABLE public.productie_orders ADD COLUMN IF NOT EXISTS verwerkt_op timestamp with time zone;
|
|
375
|
+
ALTER TABLE public.productie_orders ADD COLUMN IF NOT EXISTS geannuleerd_door uuid;
|
|
376
|
+
ALTER TABLE public.productie_orders ADD COLUMN IF NOT EXISTS geannuleerd_op timestamp with time zone;
|
|
377
|
+
ALTER TABLE public.productie_orders ADD COLUMN IF NOT EXISTS teruggedraaid_door uuid;
|
|
378
|
+
ALTER TABLE public.productie_orders ADD COLUMN IF NOT EXISTS teruggedraaid_op timestamp with time zone;
|
|
379
|
+
ALTER TABLE public.productie_orders ADD COLUMN IF NOT EXISTS reden text;
|
|
380
|
+
ALTER TABLE public.productie_orders ADD COLUMN IF NOT EXISTS geprint_op timestamp with time zone;
|
|
381
|
+
ALTER TABLE public.productie_orders ADD COLUMN IF NOT EXISTS waarschuwingen jsonb DEFAULT '[]'::jsonb NOT NULL;
|
|
382
|
+
ALTER TABLE public.productie_orders ADD COLUMN IF NOT EXISTS created_at timestamp with time zone DEFAULT now() NOT NULL;
|
|
383
|
+
ALTER TABLE public.productie_orders ADD COLUMN IF NOT EXISTS updated_at timestamp with time zone DEFAULT now() NOT NULL;
|
|
384
|
+
|
|
351
385
|
-- stock_import_chunks
|
|
352
386
|
CREATE TABLE IF NOT EXISTS public.stock_import_chunks ();
|
|
353
387
|
ALTER TABLE public.stock_import_chunks ADD COLUMN IF NOT EXISTS run_id uuid NOT NULL;
|
|
@@ -592,6 +626,37 @@ ALTER TABLE public.voorraad_floriday_artikel_wachtrij ADD COLUMN IF NOT EXISTS f
|
|
|
592
626
|
ALTER TABLE public.voorraad_floriday_artikel_wachtrij ADD COLUMN IF NOT EXISTS connection_id uuid;
|
|
593
627
|
ALTER TABLE public.voorraad_floriday_artikel_wachtrij ADD COLUMN IF NOT EXISTS aangemeld_at timestamp with time zone DEFAULT now() NOT NULL;
|
|
594
628
|
|
|
629
|
+
-- voorraad_floriday_mutaties
|
|
630
|
+
CREATE TABLE IF NOT EXISTS public.voorraad_floriday_mutaties ();
|
|
631
|
+
ALTER TABLE public.voorraad_floriday_mutaties ADD COLUMN IF NOT EXISTS id uuid DEFAULT gen_random_uuid() NOT NULL;
|
|
632
|
+
ALTER TABLE public.voorraad_floriday_mutaties ADD COLUMN IF NOT EXISTS connection_id uuid;
|
|
633
|
+
ALTER TABLE public.voorraad_floriday_mutaties ADD COLUMN IF NOT EXISTS product_id uuid NOT NULL;
|
|
634
|
+
ALTER TABLE public.voorraad_floriday_mutaties ADD COLUMN IF NOT EXISTS trade_item_id uuid;
|
|
635
|
+
ALTER TABLE public.voorraad_floriday_mutaties ADD COLUMN IF NOT EXISTS trade_item_key text;
|
|
636
|
+
ALTER TABLE public.voorraad_floriday_mutaties ADD COLUMN IF NOT EXISTS order_id uuid;
|
|
637
|
+
ALTER TABLE public.voorraad_floriday_mutaties ADD COLUMN IF NOT EXISTS order_item_id uuid;
|
|
638
|
+
ALTER TABLE public.voorraad_floriday_mutaties ADD COLUMN IF NOT EXISTS referentie text;
|
|
639
|
+
ALTER TABLE public.voorraad_floriday_mutaties ADD COLUMN IF NOT EXISTS delta integer NOT NULL;
|
|
640
|
+
ALTER TABLE public.voorraad_floriday_mutaties ADD COLUMN IF NOT EXISTS bron text NOT NULL;
|
|
641
|
+
ALTER TABLE public.voorraad_floriday_mutaties ADD COLUMN IF NOT EXISTS status text DEFAULT 'open'::text NOT NULL;
|
|
642
|
+
ALTER TABLE public.voorraad_floriday_mutaties ADD COLUMN IF NOT EXISTS pogingen integer DEFAULT 0 NOT NULL;
|
|
643
|
+
ALTER TABLE public.voorraad_floriday_mutaties ADD COLUMN IF NOT EXISTS volgende_poging_at timestamp with time zone DEFAULT now() NOT NULL;
|
|
644
|
+
ALTER TABLE public.voorraad_floriday_mutaties ADD COLUMN IF NOT EXISTS laatste_fout text;
|
|
645
|
+
ALTER TABLE public.voorraad_floriday_mutaties ADD COLUMN IF NOT EXISTS queue_id uuid;
|
|
646
|
+
ALTER TABLE public.voorraad_floriday_mutaties ADD COLUMN IF NOT EXISTS verzonden_at timestamp with time zone;
|
|
647
|
+
ALTER TABLE public.voorraad_floriday_mutaties ADD COLUMN IF NOT EXISTS bevestigd_at timestamp with time zone;
|
|
648
|
+
ALTER TABLE public.voorraad_floriday_mutaties ADD COLUMN IF NOT EXISTS created_at timestamp with time zone DEFAULT now() NOT NULL;
|
|
649
|
+
ALTER TABLE public.voorraad_floriday_mutaties ADD COLUMN IF NOT EXISTS updated_at timestamp with time zone DEFAULT now() NOT NULL;
|
|
650
|
+
|
|
651
|
+
-- voorraad_floriday_stand
|
|
652
|
+
CREATE TABLE IF NOT EXISTS public.voorraad_floriday_stand ();
|
|
653
|
+
ALTER TABLE public.voorraad_floriday_stand ADD COLUMN IF NOT EXISTS connection_id uuid NOT NULL;
|
|
654
|
+
ALTER TABLE public.voorraad_floriday_stand ADD COLUMN IF NOT EXISTS trade_item_id uuid NOT NULL;
|
|
655
|
+
ALTER TABLE public.voorraad_floriday_stand ADD COLUMN IF NOT EXISTS number_of_pieces integer DEFAULT 0 NOT NULL;
|
|
656
|
+
ALTER TABLE public.voorraad_floriday_stand ADD COLUMN IF NOT EXISTS jaar integer;
|
|
657
|
+
ALTER TABLE public.voorraad_floriday_stand ADD COLUMN IF NOT EXISTS week integer;
|
|
658
|
+
ALTER TABLE public.voorraad_floriday_stand ADD COLUMN IF NOT EXISTS opgehaald_at timestamp with time zone DEFAULT now() NOT NULL;
|
|
659
|
+
|
|
595
660
|
-- voorraad_floriday_versie_fouten
|
|
596
661
|
CREATE TABLE IF NOT EXISTS public.voorraad_floriday_versie_fouten ();
|
|
597
662
|
ALTER TABLE public.voorraad_floriday_versie_fouten ADD COLUMN IF NOT EXISTS connection_id uuid NOT NULL;
|
|
@@ -661,6 +726,13 @@ ALTER TABLE public.voorraad_instellingen ADD COLUMN IF NOT EXISTS standaard_stur
|
|
|
661
726
|
ALTER TABLE public.voorraad_instellingen ADD COLUMN IF NOT EXISTS updated_at timestamp with time zone DEFAULT now() NOT NULL;
|
|
662
727
|
ALTER TABLE public.voorraad_instellingen ADD COLUMN IF NOT EXISTS updated_by uuid;
|
|
663
728
|
|
|
729
|
+
-- voorraad_integriteit_runs
|
|
730
|
+
CREATE TABLE IF NOT EXISTS public.voorraad_integriteit_runs ();
|
|
731
|
+
ALTER TABLE public.voorraad_integriteit_runs ADD COLUMN IF NOT EXISTS id uuid DEFAULT gen_random_uuid() NOT NULL;
|
|
732
|
+
ALTER TABLE public.voorraad_integriteit_runs ADD COLUMN IF NOT EXISTS uitgevoerd_op timestamp with time zone DEFAULT now() NOT NULL;
|
|
733
|
+
ALTER TABLE public.voorraad_integriteit_runs ADD COLUMN IF NOT EXISTS samenvatting jsonb DEFAULT '{}'::jsonb NOT NULL;
|
|
734
|
+
ALTER TABLE public.voorraad_integriteit_runs ADD COLUMN IF NOT EXISTS uitkomst jsonb DEFAULT '{}'::jsonb NOT NULL;
|
|
735
|
+
|
|
664
736
|
-- voorraad_koppel_log
|
|
665
737
|
CREATE TABLE IF NOT EXISTS public.voorraad_koppel_log ();
|
|
666
738
|
ALTER TABLE public.voorraad_koppel_log ADD COLUMN IF NOT EXISTS id uuid DEFAULT gen_random_uuid() NOT NULL;
|
|
@@ -734,6 +806,36 @@ ALTER TABLE public.voorraad_media_upload_failures ADD COLUMN IF NOT EXISTS respo
|
|
|
734
806
|
ALTER TABLE public.voorraad_media_upload_failures ADD COLUMN IF NOT EXISTS error_message text;
|
|
735
807
|
ALTER TABLE public.voorraad_media_upload_failures ADD COLUMN IF NOT EXISTS client_user_id uuid;
|
|
736
808
|
|
|
809
|
+
-- voorraad_order_terugdraaiing
|
|
810
|
+
CREATE TABLE IF NOT EXISTS public.voorraad_order_terugdraaiing ();
|
|
811
|
+
ALTER TABLE public.voorraad_order_terugdraaiing ADD COLUMN IF NOT EXISTS order_id uuid NOT NULL;
|
|
812
|
+
ALTER TABLE public.voorraad_order_terugdraaiing ADD COLUMN IF NOT EXISTS order_number text;
|
|
813
|
+
ALTER TABLE public.voorraad_order_terugdraaiing ADD COLUMN IF NOT EXISTS reden text;
|
|
814
|
+
ALTER TABLE public.voorraad_order_terugdraaiing ADD COLUMN IF NOT EXISTS sleutels text[] DEFAULT '{}'::text[] NOT NULL;
|
|
815
|
+
ALTER TABLE public.voorraad_order_terugdraaiing ADD COLUMN IF NOT EXISTS door uuid;
|
|
816
|
+
ALTER TABLE public.voorraad_order_terugdraaiing ADD COLUMN IF NOT EXISTS op timestamp with time zone DEFAULT now() NOT NULL;
|
|
817
|
+
|
|
818
|
+
-- voorraad_orderregel_afboeking
|
|
819
|
+
CREATE TABLE IF NOT EXISTS public.voorraad_orderregel_afboeking ();
|
|
820
|
+
ALTER TABLE public.voorraad_orderregel_afboeking ADD COLUMN IF NOT EXISTS order_item_id uuid NOT NULL;
|
|
821
|
+
ALTER TABLE public.voorraad_orderregel_afboeking ADD COLUMN IF NOT EXISTS trade_item_key text NOT NULL;
|
|
822
|
+
ALTER TABLE public.voorraad_orderregel_afboeking ADD COLUMN IF NOT EXISTS order_id uuid;
|
|
823
|
+
ALTER TABLE public.voorraad_orderregel_afboeking ADD COLUMN IF NOT EXISTS besteld numeric DEFAULT 0 NOT NULL;
|
|
824
|
+
ALTER TABLE public.voorraad_orderregel_afboeking ADD COLUMN IF NOT EXISTS afgeboekt numeric DEFAULT 0 NOT NULL;
|
|
825
|
+
ALTER TABLE public.voorraad_orderregel_afboeking ADD COLUMN IF NOT EXISTS created_at timestamp with time zone DEFAULT now() NOT NULL;
|
|
826
|
+
ALTER TABLE public.voorraad_orderregel_afboeking ADD COLUMN IF NOT EXISTS updated_at timestamp with time zone DEFAULT now() NOT NULL;
|
|
827
|
+
|
|
828
|
+
-- voorraad_orderregel_verzending
|
|
829
|
+
CREATE TABLE IF NOT EXISTS public.voorraad_orderregel_verzending ();
|
|
830
|
+
ALTER TABLE public.voorraad_orderregel_verzending ADD COLUMN IF NOT EXISTS order_item_id uuid NOT NULL;
|
|
831
|
+
ALTER TABLE public.voorraad_orderregel_verzending ADD COLUMN IF NOT EXISTS order_id uuid;
|
|
832
|
+
ALTER TABLE public.voorraad_orderregel_verzending ADD COLUMN IF NOT EXISTS besteld numeric DEFAULT 0 NOT NULL;
|
|
833
|
+
ALTER TABLE public.voorraad_orderregel_verzending ADD COLUMN IF NOT EXISTS verzonden numeric DEFAULT 0 NOT NULL;
|
|
834
|
+
ALTER TABLE public.voorraad_orderregel_verzending ADD COLUMN IF NOT EXISTS meer_dan_besteld boolean DEFAULT false NOT NULL;
|
|
835
|
+
ALTER TABLE public.voorraad_orderregel_verzending ADD COLUMN IF NOT EXISTS afboekregel text;
|
|
836
|
+
ALTER TABLE public.voorraad_orderregel_verzending ADD COLUMN IF NOT EXISTS created_at timestamp with time zone DEFAULT now() NOT NULL;
|
|
837
|
+
ALTER TABLE public.voorraad_orderregel_verzending ADD COLUMN IF NOT EXISTS updated_at timestamp with time zone DEFAULT now() NOT NULL;
|
|
838
|
+
|
|
737
839
|
-- voorraad_placeholder_codes
|
|
738
840
|
CREATE TABLE IF NOT EXISTS public.voorraad_placeholder_codes ();
|
|
739
841
|
ALTER TABLE public.voorraad_placeholder_codes ADD COLUMN IF NOT EXISTS code text NOT NULL;
|
|
@@ -942,55 +1044,15 @@ CREATE OR REPLACE FUNCTION public.apply_stock_consumption(p_trade_item_key text,
|
|
|
942
1044
|
SECURITY DEFINER
|
|
943
1045
|
SET search_path TO 'public'
|
|
944
1046
|
AS $function$
|
|
945
|
-
DECLARE
|
|
946
|
-
v_norm text := public.normalize_order_source(p_source);
|
|
947
|
-
v_src text := CASE WHEN v_norm = 'FO' THEN 'FLORIDAY_ORDER' ELSE 'ORDER_DELIVERY' END;
|
|
948
|
-
v_ctx record; v_key text; r public.trade_item_stock%ROWTYPE; v_after numeric; v_res_after numeric;
|
|
949
1047
|
BEGIN
|
|
950
1048
|
PERFORM public.voorraad_vereis('ingelogd', 'apply_stock_consumption');
|
|
951
|
-
IF
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
INSERT INTO public.stock_mutation_log(trade_item_key, order_id, order_item_id, order_source, mutation_type, qty_delta, reason, created_by)
|
|
956
|
-
VALUES (p_trade_item_key, p_order_id, p_order_item_id, v_norm, 'consumption_skipped', p_qty,
|
|
957
|
-
CASE WHEN v_ctx.connection_id IS NULL THEN 'geen actieve koppeling' ELSE 'geen voorraadrij' END || ' — ' || COALESCE(p_reason,''), auth.uid());
|
|
958
|
-
RETURN;
|
|
959
|
-
END IF;
|
|
960
|
-
SELECT * INTO r FROM public.trade_item_stock WHERE connection_id = v_ctx.connection_id AND trade_item_key = v_key FOR UPDATE;
|
|
961
|
-
IF r.id IS NULL THEN
|
|
962
|
-
INSERT INTO public.stock_mutation_log(trade_item_key, order_id, order_item_id, order_source, mutation_type, qty_delta, reason, created_by)
|
|
963
|
-
VALUES (v_key, p_order_id, p_order_item_id, v_norm, 'consumption_skipped', p_qty, 'geen voorraadrij op de actieve koppeling — ' || COALESCE(p_reason,''), auth.uid());
|
|
1049
|
+
IF p_order_item_id IS NOT NULL THEN
|
|
1050
|
+
-- Orderregel: altijd de ene afboekroute (aantal erbij, nooit boven besteld). De meegegeven sleutel telt niet:
|
|
1051
|
+
-- de regel bepaalt zelf samenstelling of onderdelen, gelijk aan de karroute.
|
|
1052
|
+
PERFORM public.consume_order_item_v2(p_order_id, p_order_item_id, p_qty, p_source, p_reason, 'erbij');
|
|
964
1053
|
RETURN;
|
|
965
1054
|
END IF;
|
|
966
|
-
|
|
967
|
-
v_res_after := GREATEST(COALESCE(r.reserved_stock,0) - p_qty, 0);
|
|
968
|
-
|
|
969
|
-
PERFORM set_config('stock.change_source', v_src, true);
|
|
970
|
-
PERFORM set_config('stock.log_handled',
|
|
971
|
-
COALESCE(NULLIF(current_setting('stock.log_handled', true),''), ';') || r.connection_id || '|' || v_key || '|' || v_after || '|' || v_res_after || ';', true);
|
|
972
|
-
|
|
973
|
-
UPDATE public.trade_item_stock
|
|
974
|
-
SET physical_stock = v_after, reserved_stock = v_res_after, change_source = v_src, updated_at = now()
|
|
975
|
-
WHERE id = r.id;
|
|
976
|
-
|
|
977
|
-
INSERT INTO public.stock_mutation_log(trade_item_key, connection_id, order_id, order_item_id, order_source,
|
|
978
|
-
mutation_type, qty_delta, physical_before, physical_after, reserved_before, reserved_after, reason, created_by)
|
|
979
|
-
VALUES (v_key, r.connection_id, p_order_id, p_order_item_id, v_norm, 'consumption', -p_qty,
|
|
980
|
-
COALESCE(r.physical_stock,0), v_after, COALESCE(r.reserved_stock,0), v_res_after,
|
|
981
|
-
COALESCE(p_reason,'afgeboekt') || ' (' || v_src || ')', auth.uid());
|
|
982
|
-
|
|
983
|
-
IF v_after < 0 THEN
|
|
984
|
-
BEGIN
|
|
985
|
-
INSERT INTO public.stock_integrity_alerts(tx_id, alert_kind, item_count, items)
|
|
986
|
-
VALUES (-txid_current(), 'NEGATIVE_STOCK', 1, jsonb_build_array(jsonb_build_object(
|
|
987
|
-
'trade_item_key', v_key, 'connection_id', r.connection_id, 'physical_before', r.physical_stock,
|
|
988
|
-
'physical_after', v_after, 'order_id', p_order_id, 'order_item_id', p_order_item_id, 'change_source', v_src)))
|
|
989
|
-
ON CONFLICT (tx_id) DO UPDATE SET item_count = public.stock_integrity_alerts.item_count + 1,
|
|
990
|
-
items = public.stock_integrity_alerts.items || EXCLUDED.items, updated_at = now();
|
|
991
|
-
EXCEPTION WHEN others THEN RAISE WARNING '[negative-stock-alert] %', SQLERRM;
|
|
992
|
-
END;
|
|
993
|
-
END IF;
|
|
1055
|
+
PERFORM public.voorraad_afboeken_kern(p_trade_item_key, p_qty, p_order_id, p_order_item_id, p_source, p_reason);
|
|
994
1056
|
END $function$
|
|
995
1057
|
;
|
|
996
1058
|
REVOKE ALL ON FUNCTION apply_stock_consumption(text,numeric,uuid,uuid,text,text) FROM PUBLIC;
|
|
@@ -1514,31 +1576,33 @@ CREATE OR REPLACE FUNCTION public.claim_floriday_stock_queue(p_limit integer DEF
|
|
|
1514
1576
|
SECURITY DEFINER
|
|
1515
1577
|
SET search_path TO 'public'
|
|
1516
1578
|
AS $function$
|
|
1579
|
+
DECLARE v_vers boolean;
|
|
1517
1580
|
BEGIN
|
|
1518
1581
|
PERFORM public.voorraad_vereis('server', 'claim_floriday_stock_queue');
|
|
1582
|
+
v_vers := public.voorraad_floriday_orders_vers();
|
|
1583
|
+
UPDATE public.floriday_continuous_stock_queue q
|
|
1584
|
+
SET result_label = 'Wacht op een verse ophaalronde van Floriday (minder dan 2 minuten oud)', updated_at = now()
|
|
1585
|
+
WHERE q.status = 'pending' AND q.next_attempt_at <= now()
|
|
1586
|
+
AND q.result_label IS DISTINCT FROM 'Wacht op een verse ophaalronde van Floriday (minder dan 2 minuten oud)'
|
|
1587
|
+
AND (NOT v_vers OR (q.voorraad_mutatie AND public.voorraad_floriday_mutatie_doel(q.product_id) IS NULL));
|
|
1519
1588
|
RETURN QUERY
|
|
1520
1589
|
WITH candidates AS (
|
|
1521
|
-
SELECT q.id
|
|
1522
|
-
FROM public.floriday_continuous_stock_queue q
|
|
1590
|
+
SELECT q.id FROM public.floriday_continuous_stock_queue q
|
|
1523
1591
|
WHERE q.next_attempt_at <= now()
|
|
1524
|
-
AND (
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
)
|
|
1592
|
+
AND (q.status = 'pending' OR (q.status = 'processing' AND q.locked_at < now() - interval '5 minutes'))
|
|
1593
|
+
AND v_vers
|
|
1594
|
+
AND (NOT q.voorraad_mutatie OR public.voorraad_floriday_mutatie_doel(q.product_id) IS NOT NULL)
|
|
1528
1595
|
ORDER BY q.next_attempt_at ASC, q.created_at ASC
|
|
1529
1596
|
LIMIT GREATEST(1, LEAST(p_limit, 200))
|
|
1530
|
-
FOR UPDATE SKIP LOCKED
|
|
1531
|
-
)
|
|
1597
|
+
FOR UPDATE SKIP LOCKED)
|
|
1532
1598
|
UPDATE public.floriday_continuous_stock_queue q
|
|
1533
|
-
SET status = 'processing',
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
FROM candidates c
|
|
1538
|
-
WHERE q.id = c.id
|
|
1599
|
+
SET status = 'processing', locked_at = now(), locked_by = p_worker, updated_at = now(),
|
|
1600
|
+
number_of_pieces = CASE WHEN q.voorraad_mutatie THEN public.voorraad_floriday_mutatie_doel(q.product_id) ELSE q.number_of_pieces END,
|
|
1601
|
+
desired_available = CASE WHEN q.voorraad_mutatie THEN public.voorraad_floriday_mutatie_doel(q.product_id) > 0 ELSE q.desired_available END,
|
|
1602
|
+
result_label = CASE WHEN q.result_label LIKE 'Wacht op een verse ophaalronde%' THEN NULL ELSE q.result_label END
|
|
1603
|
+
FROM candidates c WHERE q.id = c.id
|
|
1539
1604
|
RETURNING q.*;
|
|
1540
|
-
END
|
|
1541
|
-
$function$
|
|
1605
|
+
END $function$
|
|
1542
1606
|
;
|
|
1543
1607
|
REVOKE ALL ON FUNCTION claim_floriday_stock_queue(integer,text) FROM PUBLIC;
|
|
1544
1608
|
REVOKE ALL ON FUNCTION claim_floriday_stock_queue(integer,text) FROM anon;
|
|
@@ -1895,252 +1959,11 @@ CREATE OR REPLACE FUNCTION public.consume_bom_for_production(p_parent_kind text,
|
|
|
1895
1959
|
LANGUAGE plpgsql
|
|
1896
1960
|
SECURITY DEFINER
|
|
1897
1961
|
SET search_path TO 'public'
|
|
1898
|
-
AS $function$
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
v_needed numeric;
|
|
1904
|
-
v_original_needed numeric;
|
|
1905
|
-
v_remaining numeric;
|
|
1906
|
-
v_take numeric;
|
|
1907
|
-
v_current numeric;
|
|
1908
|
-
v_already_planned numeric;
|
|
1909
|
-
v_available numeric;
|
|
1910
|
-
v_group_available numeric;
|
|
1911
|
-
v_before numeric;
|
|
1912
|
-
v_after numeric;
|
|
1913
|
-
v_shortages jsonb := '[]'::jsonb;
|
|
1914
|
-
v_consumed jsonb := '[]'::jsonb;
|
|
1915
|
-
v_component_key text;
|
|
1916
|
-
v_component_name text;
|
|
1917
|
-
v_component_product_id uuid;
|
|
1918
|
-
v_stock_row record;
|
|
1919
|
-
v_connection_id uuid := p_connection_id;
|
|
1920
|
-
BEGIN
|
|
1921
|
-
PERFORM public.voorraad_vereis('ingelogd', 'consume_bom_for_production');
|
|
1922
|
-
IF p_quantity IS NULL OR p_quantity <= 0 THEN
|
|
1923
|
-
RETURN jsonb_build_object('ok', true, 'consumed', '[]'::jsonb);
|
|
1924
|
-
END IF;
|
|
1925
|
-
|
|
1926
|
-
IF p_parent_kind = 'product' THEN
|
|
1927
|
-
v_parent_product_uuid := p_parent_id::uuid;
|
|
1928
|
-
END IF;
|
|
1929
|
-
|
|
1930
|
-
CREATE TEMP TABLE IF NOT EXISTS pg_temp.production_components (
|
|
1931
|
-
component_key text PRIMARY KEY,
|
|
1932
|
-
component_product_id uuid,
|
|
1933
|
-
component_name text,
|
|
1934
|
-
needed numeric NOT NULL DEFAULT 0
|
|
1935
|
-
) ON COMMIT DROP;
|
|
1936
|
-
TRUNCATE pg_temp.production_components;
|
|
1937
|
-
|
|
1938
|
-
FOR v_bom_row IN
|
|
1939
|
-
SELECT b.*,
|
|
1940
|
-
p.product AS product_name,
|
|
1941
|
-
p.trade_item_key AS product_key,
|
|
1942
|
-
p.article_number AS product_article,
|
|
1943
|
-
g.id AS component_group_id,
|
|
1944
|
-
g.name AS component_group_name
|
|
1945
|
-
FROM product_bom_items b
|
|
1946
|
-
LEFT JOIN products p ON p.id = b.component_product_id
|
|
1947
|
-
LEFT JOIN product_groups g ON (
|
|
1948
|
-
g.head_product_id = b.component_product_id
|
|
1949
|
-
OR g.head_trade_item_floriday_id = b.component_trade_item_floriday_id
|
|
1950
|
-
)
|
|
1951
|
-
WHERE (p_parent_kind = 'product' AND b.parent_product_id = v_parent_product_uuid)
|
|
1952
|
-
OR (p_parent_kind = 'floriday' AND b.parent_trade_item_floriday_id = p_parent_id)
|
|
1953
|
-
LOOP
|
|
1954
|
-
v_needed := COALESCE(v_bom_row.quantity, 1) * p_quantity;
|
|
1955
|
-
v_original_needed := v_needed;
|
|
1956
|
-
|
|
1957
|
-
IF v_bom_row.component_group_id IS NOT NULL THEN
|
|
1958
|
-
v_remaining := v_needed;
|
|
1959
|
-
v_group_available := 0;
|
|
1960
|
-
|
|
1961
|
-
FOR v_allocation_row IN
|
|
1962
|
-
SELECT gi.trade_item_id,
|
|
1963
|
-
gi.sort_order,
|
|
1964
|
-
p2.id AS product_id,
|
|
1965
|
-
p2.product AS product_name,
|
|
1966
|
-
p2.trade_item_key AS product_key,
|
|
1967
|
-
f.floriday_id,
|
|
1968
|
-
f.data AS floriday_data,
|
|
1969
|
-
td.id AS draft_id,
|
|
1970
|
-
td.data AS draft_data
|
|
1971
|
-
FROM product_group_items gi
|
|
1972
|
-
LEFT JOIN products p2 ON p2.id::text = gi.trade_item_id
|
|
1973
|
-
LEFT JOIN floriday_trade_items_cache f ON f.floriday_id = gi.trade_item_id
|
|
1974
|
-
LEFT JOIN trade_item_drafts td ON td.id::text = gi.trade_item_id
|
|
1975
|
-
WHERE gi.product_group_id = v_bom_row.component_group_id
|
|
1976
|
-
ORDER BY gi.sort_order ASC NULLS LAST, gi.created_at ASC NULLS LAST
|
|
1977
|
-
LOOP
|
|
1978
|
-
v_component_key := COALESCE(
|
|
1979
|
-
NULLIF(trim(v_allocation_row.product_key), ''),
|
|
1980
|
-
v_allocation_row.floriday_id,
|
|
1981
|
-
CASE WHEN v_allocation_row.draft_id IS NOT NULL THEN 'draft:' || v_allocation_row.draft_id::text END,
|
|
1982
|
-
v_allocation_row.trade_item_id
|
|
1983
|
-
);
|
|
1984
|
-
v_component_product_id := v_allocation_row.product_id;
|
|
1985
|
-
v_component_name := COALESCE(
|
|
1986
|
-
v_allocation_row.product_name,
|
|
1987
|
-
v_allocation_row.floriday_data->'tradeItemName'->>'nl',
|
|
1988
|
-
v_allocation_row.floriday_data->'tradeItemName'->>'en',
|
|
1989
|
-
v_allocation_row.draft_data->>'name',
|
|
1990
|
-
v_allocation_row.draft_data->>'botanicalName',
|
|
1991
|
-
v_allocation_row.draft_data->>'articleCode',
|
|
1992
|
-
v_allocation_row.trade_item_id
|
|
1993
|
-
);
|
|
1994
|
-
|
|
1995
|
-
SELECT COALESCE(ts.physical_stock, 0) INTO v_current
|
|
1996
|
-
FROM trade_item_stock ts
|
|
1997
|
-
WHERE ts.trade_item_key = v_component_key;
|
|
1998
|
-
v_current := COALESCE(v_current, 0);
|
|
1999
|
-
|
|
2000
|
-
SELECT COALESCE(pc.needed, 0) INTO v_already_planned
|
|
2001
|
-
FROM pg_temp.production_components pc
|
|
2002
|
-
WHERE pc.component_key = v_component_key;
|
|
2003
|
-
v_already_planned := COALESCE(v_already_planned, 0);
|
|
2004
|
-
|
|
2005
|
-
v_available := GREATEST(v_current - v_already_planned, 0);
|
|
2006
|
-
v_group_available := v_group_available + v_available;
|
|
2007
|
-
v_take := LEAST(v_remaining, v_available);
|
|
2008
|
-
|
|
2009
|
-
IF v_take > 0 THEN
|
|
2010
|
-
INSERT INTO pg_temp.production_components(component_key, component_product_id, component_name, needed)
|
|
2011
|
-
VALUES (v_component_key, v_component_product_id, v_component_name, v_take)
|
|
2012
|
-
ON CONFLICT (component_key) DO UPDATE
|
|
2013
|
-
SET needed = production_components.needed + EXCLUDED.needed,
|
|
2014
|
-
component_name = EXCLUDED.component_name,
|
|
2015
|
-
component_product_id = COALESCE(production_components.component_product_id, EXCLUDED.component_product_id);
|
|
2016
|
-
v_remaining := v_remaining - v_take;
|
|
2017
|
-
END IF;
|
|
2018
|
-
|
|
2019
|
-
IF v_remaining <= 0 THEN
|
|
2020
|
-
EXIT;
|
|
2021
|
-
END IF;
|
|
2022
|
-
END LOOP;
|
|
2023
|
-
|
|
2024
|
-
IF v_remaining > 0 THEN
|
|
2025
|
-
v_shortages := v_shortages || jsonb_build_object(
|
|
2026
|
-
'name', COALESCE(v_bom_row.component_group_name, v_bom_row.product_name, v_bom_row.component_product_id::text, v_bom_row.component_trade_item_floriday_id),
|
|
2027
|
-
'needed', v_original_needed,
|
|
2028
|
-
'available', v_group_available
|
|
2029
|
-
);
|
|
2030
|
-
END IF;
|
|
2031
|
-
ELSE
|
|
2032
|
-
IF v_bom_row.component_product_id IS NOT NULL THEN
|
|
2033
|
-
v_component_key := COALESCE(NULLIF(trim(v_bom_row.product_key), ''), 'product:' || v_bom_row.component_product_id::text);
|
|
2034
|
-
v_component_product_id := v_bom_row.component_product_id;
|
|
2035
|
-
v_component_name := COALESCE(v_bom_row.product_name, v_bom_row.component_product_id::text);
|
|
2036
|
-
ELSE
|
|
2037
|
-
v_component_key := v_bom_row.component_trade_item_floriday_id;
|
|
2038
|
-
v_component_product_id := NULL;
|
|
2039
|
-
SELECT COALESCE(f.data->'tradeItemName'->>'nl', f.data->'tradeItemName'->>'en', v_component_key)
|
|
2040
|
-
INTO v_component_name
|
|
2041
|
-
FROM floriday_trade_items_cache f
|
|
2042
|
-
WHERE f.floriday_id = v_component_key;
|
|
2043
|
-
v_component_name := COALESCE(v_component_name, v_component_key);
|
|
2044
|
-
END IF;
|
|
2045
|
-
|
|
2046
|
-
INSERT INTO pg_temp.production_components(component_key, component_product_id, component_name, needed)
|
|
2047
|
-
VALUES (v_component_key, v_component_product_id, v_component_name, v_needed)
|
|
2048
|
-
ON CONFLICT (component_key) DO UPDATE
|
|
2049
|
-
SET needed = production_components.needed + EXCLUDED.needed,
|
|
2050
|
-
component_name = EXCLUDED.component_name,
|
|
2051
|
-
component_product_id = COALESCE(production_components.component_product_id, EXCLUDED.component_product_id);
|
|
2052
|
-
END IF;
|
|
2053
|
-
END LOOP;
|
|
2054
|
-
|
|
2055
|
-
-- No BOM? nothing to consume
|
|
2056
|
-
IF NOT EXISTS (SELECT 1 FROM pg_temp.production_components) THEN
|
|
2057
|
-
RETURN jsonb_build_object('ok', true, 'consumed', '[]'::jsonb, 'no_bom', true);
|
|
2058
|
-
END IF;
|
|
2059
|
-
|
|
2060
|
-
IF jsonb_array_length(v_shortages) = 0 THEN
|
|
2061
|
-
FOR v_stock_row IN SELECT * FROM pg_temp.production_components LOOP
|
|
2062
|
-
SELECT COALESCE(ts.physical_stock, 0) INTO v_current
|
|
2063
|
-
FROM trade_item_stock ts
|
|
2064
|
-
WHERE ts.trade_item_key = v_stock_row.component_key;
|
|
2065
|
-
v_current := COALESCE(v_current, 0);
|
|
2066
|
-
|
|
2067
|
-
IF v_current < v_stock_row.needed THEN
|
|
2068
|
-
v_shortages := v_shortages || jsonb_build_object(
|
|
2069
|
-
'name', v_stock_row.component_name,
|
|
2070
|
-
'needed', v_stock_row.needed,
|
|
2071
|
-
'available', v_current
|
|
2072
|
-
);
|
|
2073
|
-
END IF;
|
|
2074
|
-
END LOOP;
|
|
2075
|
-
END IF;
|
|
2076
|
-
|
|
2077
|
-
IF jsonb_array_length(v_shortages) > 0 THEN
|
|
2078
|
-
RAISE EXCEPTION 'Onvoldoende voorraad: %', v_shortages::text;
|
|
2079
|
-
END IF;
|
|
2080
|
-
|
|
2081
|
-
IF v_connection_id IS NULL THEN
|
|
2082
|
-
SELECT ts.connection_id INTO v_connection_id
|
|
2083
|
-
FROM pg_temp.production_components pc
|
|
2084
|
-
JOIN trade_item_stock ts ON ts.trade_item_key = pc.component_key
|
|
2085
|
-
WHERE ts.connection_id IS NOT NULL
|
|
2086
|
-
LIMIT 1;
|
|
2087
|
-
END IF;
|
|
2088
|
-
|
|
2089
|
-
IF v_connection_id IS NULL THEN
|
|
2090
|
-
SELECT fc.id INTO v_connection_id
|
|
2091
|
-
FROM floriday_connections fc
|
|
2092
|
-
WHERE fc.is_active = true
|
|
2093
|
-
ORDER BY fc.created_at DESC NULLS LAST
|
|
2094
|
-
LIMIT 1;
|
|
2095
|
-
END IF;
|
|
2096
|
-
|
|
2097
|
-
FOR v_stock_row IN SELECT * FROM pg_temp.production_components LOOP
|
|
2098
|
-
SELECT COALESCE(ts.physical_stock, 0) INTO v_before
|
|
2099
|
-
FROM trade_item_stock ts
|
|
2100
|
-
WHERE ts.trade_item_key = v_stock_row.component_key;
|
|
2101
|
-
v_before := COALESCE(v_before, 0);
|
|
2102
|
-
v_after := v_before - v_stock_row.needed;
|
|
2103
|
-
|
|
2104
|
-
-- Set flag so the trigger on trade_item_stock does not re-trigger consumption for components
|
|
2105
|
-
PERFORM set_config('app.bom_consume_in_progress', 'on', true);
|
|
2106
|
-
|
|
2107
|
-
INSERT INTO trade_item_stock (connection_id, trade_item_key, physical_stock, user_id)
|
|
2108
|
-
VALUES (v_connection_id, v_stock_row.component_key, v_after::int, p_user_id)
|
|
2109
|
-
ON CONFLICT (connection_id, trade_item_key) DO UPDATE
|
|
2110
|
-
SET physical_stock = EXCLUDED.physical_stock,
|
|
2111
|
-
connection_id = COALESCE(trade_item_stock.connection_id, EXCLUDED.connection_id),
|
|
2112
|
-
user_id = COALESCE(trade_item_stock.user_id, EXCLUDED.user_id),
|
|
2113
|
-
updated_at = now();
|
|
2114
|
-
|
|
2115
|
-
PERFORM set_config('app.bom_consume_in_progress', 'off', true);
|
|
2116
|
-
|
|
2117
|
-
IF v_stock_row.component_product_id IS NOT NULL THEN
|
|
2118
|
-
UPDATE products
|
|
2119
|
-
SET quantity = v_after::int,
|
|
2120
|
-
updated_at = now()
|
|
2121
|
-
WHERE id = v_stock_row.component_product_id;
|
|
2122
|
-
END IF;
|
|
2123
|
-
|
|
2124
|
-
INSERT INTO stock_mutation_log (
|
|
2125
|
-
connection_id, trade_item_key, mutation_type, qty_delta,
|
|
2126
|
-
physical_before, physical_after, reason, created_by
|
|
2127
|
-
) VALUES (
|
|
2128
|
-
v_connection_id, v_stock_row.component_key, 'production_consume', -v_stock_row.needed,
|
|
2129
|
-
v_before, v_after,
|
|
2130
|
-
'Verbruik voor productie van ' || p_parent_key || ' (x' || p_quantity || ')',
|
|
2131
|
-
p_user_id
|
|
2132
|
-
);
|
|
2133
|
-
|
|
2134
|
-
v_consumed := v_consumed || jsonb_build_object(
|
|
2135
|
-
'name', v_stock_row.component_name,
|
|
2136
|
-
'consumed', v_stock_row.needed,
|
|
2137
|
-
'remaining', v_after
|
|
2138
|
-
);
|
|
2139
|
-
END LOOP;
|
|
2140
|
-
|
|
2141
|
-
RETURN jsonb_build_object('ok', true, 'consumed', v_consumed);
|
|
2142
|
-
END;
|
|
2143
|
-
$function$
|
|
1962
|
+
AS $function$
|
|
1963
|
+
BEGIN
|
|
1964
|
+
PERFORM public.voorraad_vereis('ingelogd', 'consume_bom_for_production');
|
|
1965
|
+
RAISE EXCEPTION 'Gebruik Productieorder maken.' USING ERRCODE = 'P0001', HINT = 'Produceren loopt nu via productieorders.';
|
|
1966
|
+
END $function$
|
|
2144
1967
|
;
|
|
2145
1968
|
REVOKE ALL ON FUNCTION consume_bom_for_production(text,text,text,numeric,uuid,uuid) FROM PUBLIC;
|
|
2146
1969
|
REVOKE ALL ON FUNCTION consume_bom_for_production(text,text,text,numeric,uuid,uuid) FROM anon;
|
|
@@ -2150,208 +1973,11 @@ CREATE OR REPLACE FUNCTION public.consume_bom_for_production(p_parent_kind text,
|
|
|
2150
1973
|
LANGUAGE plpgsql
|
|
2151
1974
|
SECURITY DEFINER
|
|
2152
1975
|
SET search_path TO 'public'
|
|
2153
|
-
AS $function$
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
v_needed numeric;
|
|
2159
|
-
v_original_needed numeric;
|
|
2160
|
-
v_remaining numeric;
|
|
2161
|
-
v_take numeric;
|
|
2162
|
-
v_current numeric;
|
|
2163
|
-
v_already_planned numeric;
|
|
2164
|
-
v_available numeric;
|
|
2165
|
-
v_group_available numeric;
|
|
2166
|
-
v_before numeric;
|
|
2167
|
-
v_after numeric;
|
|
2168
|
-
v_shortages jsonb := '[]'::jsonb;
|
|
2169
|
-
v_consumed jsonb := '[]'::jsonb;
|
|
2170
|
-
v_component_key text;
|
|
2171
|
-
v_component_name text;
|
|
2172
|
-
v_component_product_id uuid;
|
|
2173
|
-
v_stock_row record;
|
|
2174
|
-
v_connection_id uuid := p_connection_id;
|
|
2175
|
-
v_batch_id uuid := COALESCE(p_batch_id, gen_random_uuid());
|
|
2176
|
-
BEGIN
|
|
2177
|
-
PERFORM public.voorraad_vereis('ingelogd', 'consume_bom_for_production');
|
|
2178
|
-
IF p_quantity IS NULL OR p_quantity <= 0 THEN
|
|
2179
|
-
RETURN jsonb_build_object('ok', true, 'consumed', '[]'::jsonb, 'batch_id', v_batch_id);
|
|
2180
|
-
END IF;
|
|
2181
|
-
|
|
2182
|
-
IF p_parent_kind = 'product' THEN
|
|
2183
|
-
v_parent_product_uuid := p_parent_id::uuid;
|
|
2184
|
-
END IF;
|
|
2185
|
-
|
|
2186
|
-
CREATE TEMP TABLE IF NOT EXISTS pg_temp.production_components (
|
|
2187
|
-
component_key text PRIMARY KEY,
|
|
2188
|
-
component_product_id uuid,
|
|
2189
|
-
component_name text,
|
|
2190
|
-
needed numeric NOT NULL DEFAULT 0
|
|
2191
|
-
) ON COMMIT DROP;
|
|
2192
|
-
TRUNCATE pg_temp.production_components;
|
|
2193
|
-
|
|
2194
|
-
FOR v_bom_row IN
|
|
2195
|
-
SELECT b.*, p.product AS product_name, p.trade_item_key AS product_key,
|
|
2196
|
-
g.id AS component_group_id, g.name AS component_group_name
|
|
2197
|
-
FROM product_bom_items b
|
|
2198
|
-
LEFT JOIN products p ON p.id = b.component_product_id
|
|
2199
|
-
LEFT JOIN product_groups g ON (
|
|
2200
|
-
g.head_product_id = b.component_product_id
|
|
2201
|
-
OR g.head_trade_item_floriday_id = b.component_trade_item_floriday_id
|
|
2202
|
-
)
|
|
2203
|
-
WHERE (p_parent_kind = 'product' AND b.parent_product_id = v_parent_product_uuid)
|
|
2204
|
-
OR (p_parent_kind = 'floriday' AND b.parent_trade_item_floriday_id = p_parent_id)
|
|
2205
|
-
LOOP
|
|
2206
|
-
v_needed := COALESCE(v_bom_row.quantity, 1) * p_quantity;
|
|
2207
|
-
v_original_needed := v_needed;
|
|
2208
|
-
|
|
2209
|
-
IF v_bom_row.component_group_id IS NOT NULL THEN
|
|
2210
|
-
v_remaining := v_needed;
|
|
2211
|
-
v_group_available := 0;
|
|
2212
|
-
FOR v_allocation_row IN
|
|
2213
|
-
SELECT gi.trade_item_id, gi.sort_order,
|
|
2214
|
-
p2.id AS product_id, p2.product AS product_name, p2.trade_item_key AS product_key,
|
|
2215
|
-
f.floriday_id, f.data AS floriday_data,
|
|
2216
|
-
td.id AS draft_id, td.data AS draft_data
|
|
2217
|
-
FROM product_group_items gi
|
|
2218
|
-
LEFT JOIN products p2 ON p2.id::text = gi.trade_item_id
|
|
2219
|
-
LEFT JOIN floriday_trade_items_cache f ON f.floriday_id = gi.trade_item_id
|
|
2220
|
-
LEFT JOIN trade_item_drafts td ON td.id::text = gi.trade_item_id
|
|
2221
|
-
WHERE gi.product_group_id = v_bom_row.component_group_id
|
|
2222
|
-
ORDER BY gi.sort_order ASC NULLS LAST, gi.created_at ASC NULLS LAST
|
|
2223
|
-
LOOP
|
|
2224
|
-
v_component_key := COALESCE(
|
|
2225
|
-
NULLIF(trim(v_allocation_row.product_key), ''),
|
|
2226
|
-
v_allocation_row.floriday_id,
|
|
2227
|
-
CASE WHEN v_allocation_row.draft_id IS NOT NULL THEN 'draft:' || v_allocation_row.draft_id::text END,
|
|
2228
|
-
v_allocation_row.trade_item_id
|
|
2229
|
-
);
|
|
2230
|
-
v_component_product_id := v_allocation_row.product_id;
|
|
2231
|
-
v_component_name := COALESCE(
|
|
2232
|
-
v_allocation_row.product_name,
|
|
2233
|
-
v_allocation_row.floriday_data->'tradeItemName'->>'nl',
|
|
2234
|
-
v_allocation_row.floriday_data->'tradeItemName'->>'en',
|
|
2235
|
-
v_allocation_row.draft_data->>'name',
|
|
2236
|
-
v_allocation_row.draft_data->>'articleCode',
|
|
2237
|
-
v_allocation_row.trade_item_id
|
|
2238
|
-
);
|
|
2239
|
-
SELECT COALESCE(ts.physical_stock, 0) INTO v_current
|
|
2240
|
-
FROM trade_item_stock ts WHERE ts.trade_item_key = v_component_key;
|
|
2241
|
-
v_current := COALESCE(v_current, 0);
|
|
2242
|
-
SELECT COALESCE(pc.needed, 0) INTO v_already_planned
|
|
2243
|
-
FROM pg_temp.production_components pc WHERE pc.component_key = v_component_key;
|
|
2244
|
-
v_already_planned := COALESCE(v_already_planned, 0);
|
|
2245
|
-
v_available := GREATEST(v_current - v_already_planned, 0);
|
|
2246
|
-
v_group_available := v_group_available + v_available;
|
|
2247
|
-
v_take := LEAST(v_remaining, v_available);
|
|
2248
|
-
IF v_take > 0 THEN
|
|
2249
|
-
INSERT INTO pg_temp.production_components(component_key, component_product_id, component_name, needed)
|
|
2250
|
-
VALUES (v_component_key, v_component_product_id, v_component_name, v_take)
|
|
2251
|
-
ON CONFLICT (component_key) DO UPDATE
|
|
2252
|
-
SET needed = production_components.needed + EXCLUDED.needed,
|
|
2253
|
-
component_name = EXCLUDED.component_name,
|
|
2254
|
-
component_product_id = COALESCE(production_components.component_product_id, EXCLUDED.component_product_id);
|
|
2255
|
-
v_remaining := v_remaining - v_take;
|
|
2256
|
-
END IF;
|
|
2257
|
-
IF v_remaining <= 0 THEN EXIT; END IF;
|
|
2258
|
-
END LOOP;
|
|
2259
|
-
IF v_remaining > 0 THEN
|
|
2260
|
-
v_shortages := v_shortages || jsonb_build_object(
|
|
2261
|
-
'name', COALESCE(v_bom_row.component_group_name, v_bom_row.product_name, v_bom_row.component_trade_item_floriday_id),
|
|
2262
|
-
'needed', v_original_needed, 'available', v_group_available);
|
|
2263
|
-
END IF;
|
|
2264
|
-
ELSE
|
|
2265
|
-
IF v_bom_row.component_product_id IS NOT NULL THEN
|
|
2266
|
-
v_component_key := COALESCE(NULLIF(trim(v_bom_row.product_key), ''), 'product:' || v_bom_row.component_product_id::text);
|
|
2267
|
-
v_component_product_id := v_bom_row.component_product_id;
|
|
2268
|
-
v_component_name := COALESCE(v_bom_row.product_name, v_bom_row.component_product_id::text);
|
|
2269
|
-
ELSE
|
|
2270
|
-
v_component_key := v_bom_row.component_trade_item_floriday_id;
|
|
2271
|
-
v_component_product_id := NULL;
|
|
2272
|
-
SELECT COALESCE(f.data->'tradeItemName'->>'nl', f.data->'tradeItemName'->>'en', v_component_key)
|
|
2273
|
-
INTO v_component_name FROM floriday_trade_items_cache f WHERE f.floriday_id = v_component_key;
|
|
2274
|
-
v_component_name := COALESCE(v_component_name, v_component_key);
|
|
2275
|
-
END IF;
|
|
2276
|
-
INSERT INTO pg_temp.production_components(component_key, component_product_id, component_name, needed)
|
|
2277
|
-
VALUES (v_component_key, v_component_product_id, v_component_name, v_needed)
|
|
2278
|
-
ON CONFLICT (component_key) DO UPDATE
|
|
2279
|
-
SET needed = production_components.needed + EXCLUDED.needed,
|
|
2280
|
-
component_name = EXCLUDED.component_name,
|
|
2281
|
-
component_product_id = COALESCE(production_components.component_product_id, EXCLUDED.component_product_id);
|
|
2282
|
-
END IF;
|
|
2283
|
-
END LOOP;
|
|
2284
|
-
|
|
2285
|
-
IF NOT EXISTS (SELECT 1 FROM pg_temp.production_components) THEN
|
|
2286
|
-
RETURN jsonb_build_object('ok', true, 'consumed', '[]'::jsonb, 'no_bom', true, 'batch_id', v_batch_id);
|
|
2287
|
-
END IF;
|
|
2288
|
-
|
|
2289
|
-
IF jsonb_array_length(v_shortages) = 0 THEN
|
|
2290
|
-
FOR v_stock_row IN SELECT * FROM pg_temp.production_components LOOP
|
|
2291
|
-
SELECT COALESCE(ts.physical_stock, 0) INTO v_current
|
|
2292
|
-
FROM trade_item_stock ts WHERE ts.trade_item_key = v_stock_row.component_key;
|
|
2293
|
-
v_current := COALESCE(v_current, 0);
|
|
2294
|
-
IF v_current < v_stock_row.needed THEN
|
|
2295
|
-
v_shortages := v_shortages || jsonb_build_object(
|
|
2296
|
-
'name', v_stock_row.component_name, 'needed', v_stock_row.needed, 'available', v_current);
|
|
2297
|
-
END IF;
|
|
2298
|
-
END LOOP;
|
|
2299
|
-
END IF;
|
|
2300
|
-
|
|
2301
|
-
IF jsonb_array_length(v_shortages) > 0 THEN
|
|
2302
|
-
RAISE EXCEPTION 'Onvoldoende voorraad: %', v_shortages::text;
|
|
2303
|
-
END IF;
|
|
2304
|
-
|
|
2305
|
-
IF v_connection_id IS NULL THEN
|
|
2306
|
-
SELECT ts.connection_id INTO v_connection_id
|
|
2307
|
-
FROM pg_temp.production_components pc
|
|
2308
|
-
JOIN trade_item_stock ts ON ts.trade_item_key = pc.component_key
|
|
2309
|
-
WHERE ts.connection_id IS NOT NULL LIMIT 1;
|
|
2310
|
-
END IF;
|
|
2311
|
-
IF v_connection_id IS NULL THEN
|
|
2312
|
-
SELECT fc.id INTO v_connection_id FROM floriday_connections fc
|
|
2313
|
-
WHERE fc.is_active = true ORDER BY fc.created_at DESC NULLS LAST LIMIT 1;
|
|
2314
|
-
END IF;
|
|
2315
|
-
|
|
2316
|
-
FOR v_stock_row IN SELECT * FROM pg_temp.production_components LOOP
|
|
2317
|
-
SELECT COALESCE(ts.physical_stock, 0) INTO v_before
|
|
2318
|
-
FROM trade_item_stock ts WHERE ts.trade_item_key = v_stock_row.component_key;
|
|
2319
|
-
v_before := COALESCE(v_before, 0);
|
|
2320
|
-
v_after := v_before - v_stock_row.needed;
|
|
2321
|
-
|
|
2322
|
-
PERFORM set_config('app.bom_consume_in_progress', 'on', true);
|
|
2323
|
-
INSERT INTO trade_item_stock (connection_id, trade_item_key, physical_stock, user_id)
|
|
2324
|
-
VALUES (v_connection_id, v_stock_row.component_key, v_after::int, p_user_id)
|
|
2325
|
-
ON CONFLICT (connection_id, trade_item_key) DO UPDATE
|
|
2326
|
-
SET physical_stock = EXCLUDED.physical_stock,
|
|
2327
|
-
connection_id = COALESCE(trade_item_stock.connection_id, EXCLUDED.connection_id),
|
|
2328
|
-
user_id = COALESCE(trade_item_stock.user_id, EXCLUDED.user_id),
|
|
2329
|
-
updated_at = now();
|
|
2330
|
-
PERFORM set_config('app.bom_consume_in_progress', 'off', true);
|
|
2331
|
-
|
|
2332
|
-
IF v_stock_row.component_product_id IS NOT NULL THEN
|
|
2333
|
-
UPDATE products SET quantity = v_after::int, updated_at = now()
|
|
2334
|
-
WHERE id = v_stock_row.component_product_id;
|
|
2335
|
-
END IF;
|
|
2336
|
-
|
|
2337
|
-
INSERT INTO stock_mutation_log (
|
|
2338
|
-
connection_id, trade_item_key, mutation_type, qty_delta,
|
|
2339
|
-
physical_before, physical_after, reason, created_by,
|
|
2340
|
-
production_batch_id, parent_trade_item_key
|
|
2341
|
-
) VALUES (
|
|
2342
|
-
v_connection_id, v_stock_row.component_key, 'production_consume', -v_stock_row.needed,
|
|
2343
|
-
v_before, v_after,
|
|
2344
|
-
'Verbruik voor productie van ' || p_parent_key || ' (x' || p_quantity || ')',
|
|
2345
|
-
p_user_id, v_batch_id, p_parent_key
|
|
2346
|
-
);
|
|
2347
|
-
|
|
2348
|
-
v_consumed := v_consumed || jsonb_build_object(
|
|
2349
|
-
'name', v_stock_row.component_name, 'consumed', v_stock_row.needed, 'remaining', v_after);
|
|
2350
|
-
END LOOP;
|
|
2351
|
-
|
|
2352
|
-
RETURN jsonb_build_object('ok', true, 'consumed', v_consumed, 'batch_id', v_batch_id);
|
|
2353
|
-
END;
|
|
2354
|
-
$function$
|
|
1976
|
+
AS $function$
|
|
1977
|
+
BEGIN
|
|
1978
|
+
PERFORM public.voorraad_vereis('ingelogd', 'consume_bom_for_production');
|
|
1979
|
+
RAISE EXCEPTION 'Gebruik Productieorder maken.' USING ERRCODE = 'P0001', HINT = 'Produceren loopt nu via productieorders.';
|
|
1980
|
+
END $function$
|
|
2355
1981
|
;
|
|
2356
1982
|
REVOKE ALL ON FUNCTION consume_bom_for_production(text,text,text,numeric,uuid,uuid,uuid) FROM PUBLIC;
|
|
2357
1983
|
REVOKE ALL ON FUNCTION consume_bom_for_production(text,text,text,numeric,uuid,uuid,uuid) FROM anon;
|
|
@@ -2362,45 +1988,131 @@ CREATE OR REPLACE FUNCTION public.consume_order_item(p_order_id uuid, p_order_it
|
|
|
2362
1988
|
SECURITY DEFINER
|
|
2363
1989
|
SET search_path TO 'public'
|
|
2364
1990
|
AS $function$
|
|
2365
|
-
DECLARE
|
|
1991
|
+
DECLARE v jsonb;
|
|
2366
1992
|
BEGIN
|
|
2367
1993
|
PERFORM public.voorraad_vereis('ingelogd', 'consume_order_item');
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
1994
|
+
v := public.consume_order_item_v2(p_order_id, p_order_item_id, NULL, p_source, p_reason, 'totaal');
|
|
1995
|
+
RETURN COALESCE((v->>'afgeboekt_regels')::integer, 0);
|
|
1996
|
+
END $function$
|
|
1997
|
+
;
|
|
1998
|
+
REVOKE ALL ON FUNCTION consume_order_item(uuid,uuid,text,text) FROM PUBLIC;
|
|
1999
|
+
REVOKE ALL ON FUNCTION consume_order_item(uuid,uuid,text,text) FROM anon;
|
|
2000
|
+
GRANT EXECUTE ON FUNCTION consume_order_item(uuid,uuid,text,text) TO service_role;
|
|
2001
|
+
CREATE OR REPLACE FUNCTION public.consume_order_item_v2(p_order_id uuid, p_order_item_id uuid, p_verzonden numeric, p_source text, p_reason text, p_modus text DEFAULT 'totaal'::text)
|
|
2002
|
+
RETURNS jsonb
|
|
2003
|
+
LANGUAGE plpgsql
|
|
2004
|
+
SECURITY DEFINER
|
|
2005
|
+
SET search_path TO 'public'
|
|
2006
|
+
AS $function$
|
|
2007
|
+
DECLARE
|
|
2008
|
+
v_norm text := public.normalize_order_source(p_source);
|
|
2009
|
+
v_besteld numeric; v_order uuid; v_pid uuid; v_prev numeric; v_doel numeric; v_keys text[]; v_regel text;
|
|
2010
|
+
v_pkey text; a record; r record; v_doelkey numeric; v_delta numeric; n integer := 0;
|
|
2011
|
+
v_reason text := COALESCE(NULLIF(p_reason, ''), 'afgeboekt');
|
|
2012
|
+
BEGIN
|
|
2013
|
+
PERFORM public.voorraad_vereis('ingelogd', 'consume_order_item_v2');
|
|
2014
|
+
IF p_order_item_id IS NULL THEN RETURN jsonb_build_object('status', 'geen_regel'); END IF;
|
|
2015
|
+
SELECT oi.quantity, oi.order_id, oi.product_id INTO v_besteld, v_order, v_pid FROM public.order_items oi WHERE oi.id = p_order_item_id;
|
|
2016
|
+
IF NOT FOUND THEN RETURN jsonb_build_object('status', 'regel_niet_gevonden'); END IF;
|
|
2017
|
+
v_order := COALESCE(p_order_id, v_order);
|
|
2018
|
+
v_besteld := COALESCE(v_besteld, 0);
|
|
2019
|
+
|
|
2020
|
+
INSERT INTO public.voorraad_orderregel_verzending(order_item_id, order_id, besteld)
|
|
2021
|
+
VALUES (p_order_item_id, v_order, v_besteld) ON CONFLICT (order_item_id) DO NOTHING;
|
|
2022
|
+
SELECT verzonden, afboekregel INTO v_prev, v_regel FROM public.voorraad_orderregel_verzending WHERE order_item_id = p_order_item_id FOR UPDATE;
|
|
2023
|
+
|
|
2024
|
+
IF NOT EXISTS (SELECT 1 FROM public.voorraad_orderregel_afboeking WHERE order_item_id = p_order_item_id) THEN
|
|
2025
|
+
IF v_pid IS NOT NULL AND EXISTS (SELECT 1 FROM public.product_bom_items b WHERE b.parent_product_id = v_pid) THEN
|
|
2026
|
+
v_pkey := public.ensure_trade_item_stock_row_key(v_pid::text);
|
|
2027
|
+
IF v_pkey IS NOT NULL AND (
|
|
2028
|
+
EXISTS (SELECT 1 FROM public.productie_orders po WHERE po.product_id = v_pid AND po.status IN ('open','verwerkt'))
|
|
2029
|
+
OR COALESCE((SELECT MAX(s.physical_stock) FROM public.trade_item_stock s WHERE s.trade_item_key = v_pkey), 0) > 0) THEN
|
|
2030
|
+
v_regel := 'samenstelling';
|
|
2031
|
+
INSERT INTO public.voorraad_orderregel_afboeking(order_item_id, trade_item_key, order_id, besteld)
|
|
2032
|
+
VALUES (p_order_item_id, v_pkey, v_order, v_besteld) ON CONFLICT DO NOTHING;
|
|
2394
2033
|
END IF;
|
|
2034
|
+
END IF;
|
|
2035
|
+
IF v_regel IS DISTINCT FROM 'samenstelling' THEN
|
|
2036
|
+
v_regel := 'onderdelen';
|
|
2037
|
+
FOR a IN SELECT * FROM public.logistics_order_line_allocation(p_order_item_id) LOOP
|
|
2038
|
+
IF a.source = 'error' OR a.trade_item_key IS NULL OR a.trade_item_key LIKE 'group:%' OR COALESCE(a.qty, 0) <= 0 THEN CONTINUE; END IF;
|
|
2039
|
+
INSERT INTO public.voorraad_orderregel_afboeking(order_item_id, trade_item_key, order_id, besteld)
|
|
2040
|
+
VALUES (p_order_item_id, a.trade_item_key, v_order, a.qty)
|
|
2041
|
+
ON CONFLICT (order_item_id, trade_item_key) DO UPDATE SET besteld = public.voorraad_orderregel_afboeking.besteld + EXCLUDED.besteld;
|
|
2042
|
+
END LOOP;
|
|
2043
|
+
END IF;
|
|
2044
|
+
-- Eerder (oude route) afgeboekt: overnemen, zodat niets twee keer gaat.
|
|
2045
|
+
INSERT INTO public.voorraad_orderregel_afboeking(order_item_id, trade_item_key, order_id, besteld, afgeboekt)
|
|
2046
|
+
SELECT p_order_item_id, l.trade_item_key, v_order, 0, -SUM(l.qty_delta)
|
|
2047
|
+
FROM public.stock_mutation_log l
|
|
2048
|
+
WHERE l.order_item_id = p_order_item_id AND l.mutation_type = 'consumption' AND l.trade_item_key IS NOT NULL
|
|
2049
|
+
GROUP BY l.trade_item_key
|
|
2050
|
+
ON CONFLICT (order_item_id, trade_item_key) DO UPDATE SET afgeboekt = EXCLUDED.afgeboekt;
|
|
2051
|
+
IF EXISTS (SELECT 1 FROM public.voorraad_orderregel_afboeking WHERE order_item_id = p_order_item_id) THEN
|
|
2052
|
+
UPDATE public.voorraad_orderregel_verzending SET afboekregel = v_regel, updated_at = now() WHERE order_item_id = p_order_item_id;
|
|
2053
|
+
END IF;
|
|
2054
|
+
IF EXISTS (SELECT 1 FROM public.stock_mutation_log WHERE order_item_id = p_order_item_id AND mutation_type = 'consumption_done') THEN
|
|
2055
|
+
UPDATE public.voorraad_orderregel_verzending SET verzonden = GREATEST(verzonden, besteld), updated_at = now()
|
|
2056
|
+
WHERE order_item_id = p_order_item_id RETURNING verzonden INTO v_prev;
|
|
2057
|
+
END IF;
|
|
2058
|
+
END IF;
|
|
2059
|
+
|
|
2060
|
+
v_doel := CASE
|
|
2061
|
+
WHEN p_verzonden IS NULL THEN GREATEST(v_besteld, v_prev)
|
|
2062
|
+
WHEN p_modus = 'erbij' THEN LEAST(v_prev + GREATEST(p_verzonden, 0), GREATEST(v_besteld, v_prev))
|
|
2063
|
+
ELSE GREATEST(p_verzonden, v_prev) END;
|
|
2064
|
+
|
|
2065
|
+
IF NOT EXISTS (SELECT 1 FROM public.voorraad_orderregel_afboeking WHERE order_item_id = p_order_item_id) THEN
|
|
2066
|
+
IF v_doel > v_prev THEN
|
|
2067
|
+
INSERT INTO public.stock_mutation_log(order_id, order_item_id, order_source, mutation_type, qty_delta, reason, created_by)
|
|
2068
|
+
VALUES (v_order, p_order_item_id, v_norm, 'consumption_blocked', v_doel - v_prev,
|
|
2069
|
+
'Geen toewijzing voor deze regel; niets afgeboekt — ' || v_reason, auth.uid());
|
|
2070
|
+
END IF;
|
|
2071
|
+
RETURN jsonb_build_object('status', 'geblokkeerd', 'verzonden', v_prev, 'besteld', v_besteld);
|
|
2072
|
+
END IF;
|
|
2073
|
+
|
|
2074
|
+
SELECT array_agg(trade_item_key ORDER BY trade_item_key) INTO v_keys
|
|
2075
|
+
FROM public.voorraad_orderregel_afboeking WHERE order_item_id = p_order_item_id;
|
|
2076
|
+
PERFORM public.voorraad_lock_sleutels(v_keys);
|
|
2077
|
+
|
|
2078
|
+
FOR r IN SELECT * FROM public.voorraad_orderregel_afboeking WHERE order_item_id = p_order_item_id
|
|
2079
|
+
ORDER BY trade_item_key FOR UPDATE LOOP
|
|
2080
|
+
v_doelkey := CASE WHEN v_besteld <= 0 THEN r.besteld ELSE round(r.besteld * v_doel / v_besteld) END;
|
|
2081
|
+
v_delta := v_doelkey - r.afgeboekt;
|
|
2082
|
+
IF v_delta <= 0 THEN CONTINUE; END IF;
|
|
2083
|
+
IF v_norm = 'FO' AND public.voorraad_floriday_leads_key(r.trade_item_key) THEN
|
|
2084
|
+
INSERT INTO public.stock_mutation_log(trade_item_key, order_id, order_item_id, order_source, mutation_type, qty_delta, reason, created_by)
|
|
2085
|
+
VALUES (r.trade_item_key, v_order, p_order_item_id, v_norm, 'consumption_skipped', v_delta,
|
|
2086
|
+
'Niet afgeboekt: Floriday leidt dit artikel en heeft de verkoop al verwerkt — ' || v_reason, auth.uid());
|
|
2087
|
+
ELSE
|
|
2088
|
+
PERFORM public.voorraad_afboeken_kern(r.trade_item_key, v_delta, v_order, p_order_item_id, p_source,
|
|
2089
|
+
v_reason || ' [verzonden ' || v_doel || ' van ' || v_besteld || ']');
|
|
2395
2090
|
n := n + 1;
|
|
2091
|
+
IF v_norm <> 'FO' AND public.voorraad_floriday_leads_key(r.trade_item_key)
|
|
2092
|
+
AND NOT EXISTS (SELECT 1 FROM public.voorraad_floriday_mutaties m WHERE m.order_item_id = p_order_item_id) THEN
|
|
2093
|
+
PERFORM public.voorraad_alert_floriday_not_updated(r.trade_item_key, v_delta, v_order, p_order_item_id);
|
|
2094
|
+
END IF;
|
|
2396
2095
|
END IF;
|
|
2096
|
+
UPDATE public.voorraad_orderregel_afboeking SET afgeboekt = afgeboekt + v_delta, updated_at = now()
|
|
2097
|
+
WHERE order_item_id = r.order_item_id AND trade_item_key = r.trade_item_key;
|
|
2397
2098
|
END LOOP;
|
|
2398
|
-
|
|
2099
|
+
|
|
2100
|
+
UPDATE public.voorraad_orderregel_verzending
|
|
2101
|
+
SET verzonden = v_doel, besteld = v_besteld, meer_dan_besteld = v_doel > v_besteld, updated_at = now()
|
|
2102
|
+
WHERE order_item_id = p_order_item_id;
|
|
2103
|
+
IF v_doel >= v_besteld THEN
|
|
2104
|
+
INSERT INTO public.stock_mutation_log(order_id, order_item_id, order_source, mutation_type, qty_delta, reason, created_by)
|
|
2105
|
+
VALUES (v_order, p_order_item_id, v_norm, 'consumption_done', 0, v_reason, auth.uid())
|
|
2106
|
+
ON CONFLICT (order_item_id) WHERE mutation_type = 'consumption_done' AND order_item_id IS NOT NULL DO NOTHING;
|
|
2107
|
+
END IF;
|
|
2108
|
+
RETURN jsonb_build_object('status', 'ok', 'afgeboekt_regels', n, 'verzonden', v_doel, 'besteld', v_besteld,
|
|
2109
|
+
'meer_dan_besteld', v_doel > v_besteld, 'afboekregel', v_regel);
|
|
2399
2110
|
END $function$
|
|
2400
2111
|
;
|
|
2401
|
-
REVOKE ALL ON FUNCTION
|
|
2402
|
-
REVOKE ALL ON FUNCTION
|
|
2403
|
-
GRANT EXECUTE ON FUNCTION
|
|
2112
|
+
REVOKE ALL ON FUNCTION consume_order_item_v2(uuid,uuid,numeric,text,text,text) FROM PUBLIC;
|
|
2113
|
+
REVOKE ALL ON FUNCTION consume_order_item_v2(uuid,uuid,numeric,text,text,text) FROM anon;
|
|
2114
|
+
GRANT EXECUTE ON FUNCTION consume_order_item_v2(uuid,uuid,numeric,text,text,text) TO authenticated;
|
|
2115
|
+
GRANT EXECUTE ON FUNCTION consume_order_item_v2(uuid,uuid,numeric,text,text,text) TO service_role;
|
|
2404
2116
|
CREATE OR REPLACE FUNCTION public.drain_inventory_recompute_queue()
|
|
2405
2117
|
RETURNS integer
|
|
2406
2118
|
LANGUAGE plpgsql
|
|
@@ -3245,6 +2957,7 @@ BEGIN
|
|
|
3245
2957
|
WHERE t.trade_item_key IN (v_tid, 'product:'||v_pid::text, v_pid::text)
|
|
3246
2958
|
ORDER BY (t.trade_item_key = v_tid) DESC, t.updated_at DESC NULLS LAST LIMIT 1;
|
|
3247
2959
|
v_stock := NULLIF(v_it->>'stock','')::numeric;
|
|
2960
|
+
IF v_stock IS NOT NULL THEN v_stock := public.voorraad_floriday_volg_waarde(v_pid, p_connection_id, v_stock); END IF;
|
|
3248
2961
|
IF v_stock IS NULL THEN v_res := 'Geen Floriday-voorraad gevonden (geen doorlopende voorraad en geen weekaanbod voor deze week)'; END IF;
|
|
3249
2962
|
IF v_stock IS NOT NULL AND v_stock >= 0 AND v_stock IS DISTINCT FROM v_cur_stock THEN
|
|
3250
2963
|
IF v_uid IS NULL THEN RAISE EXCEPTION 'Geen eigenaar bij de voorraadsturing'; END IF;
|
|
@@ -3283,200 +2996,10 @@ CREATE OR REPLACE FUNCTION public.floriday_ingest_sales_orders(p_limit integer D
|
|
|
3283
2996
|
SECURITY DEFINER
|
|
3284
2997
|
SET search_path TO 'public'
|
|
3285
2998
|
AS $function$
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
v_key text;
|
|
3291
|
-
v_user uuid;
|
|
3292
|
-
v_count integer := 0;
|
|
3293
|
-
v_packing jsonb;
|
|
3294
|
-
v_vbn text;
|
|
3295
|
-
v_custom text;
|
|
3296
|
-
v_fust_key text;
|
|
3297
|
-
v_per_package integer;
|
|
3298
|
-
v_packages integer;
|
|
3299
|
-
v_fust_id uuid;
|
|
3300
|
-
v_prev_packages integer;
|
|
3301
|
-
v_fust_delta integer;
|
|
3302
|
-
v_owner uuid;
|
|
3303
|
-
BEGIN
|
|
3304
|
-
PERFORM public.voorraad_vereis('ingelogd', 'floriday_ingest_sales_orders');
|
|
3305
|
-
PERFORM public.voorraad_fust_startmoment_auto();
|
|
3306
|
-
FOR r IN
|
|
3307
|
-
SELECT c.connection_id,
|
|
3308
|
-
c.floriday_id,
|
|
3309
|
-
COALESCE((c.data->>'salesOrderVersion')::bigint, 0) AS version,
|
|
3310
|
-
COALESCE(c.status, c.data->>'status') AS status,
|
|
3311
|
-
c.is_deleted,
|
|
3312
|
-
c.data->>'tradeItemId' AS trade_item_id,
|
|
3313
|
-
COALESCE((c.data->>'numberOfPieces')::int, 0) AS pieces,
|
|
3314
|
-
c.data->'packingConfiguration' AS order_packing,
|
|
3315
|
-
c.data->'delivery'->>'latestDeliveryDateTime' AS lever_at
|
|
3316
|
-
FROM public.floriday_salesorders_cache c
|
|
3317
|
-
WHERE NOT EXISTS (
|
|
3318
|
-
SELECT 1 FROM public.floriday_sales_order_ingest i
|
|
3319
|
-
WHERE i.connection_id = c.connection_id
|
|
3320
|
-
AND i.sales_order_id = c.floriday_id
|
|
3321
|
-
AND i.order_version = COALESCE((c.data->>'salesOrderVersion')::bigint, 0)
|
|
3322
|
-
)
|
|
3323
|
-
ORDER BY c.updated_at ASC
|
|
3324
|
-
LIMIT GREATEST(1, LEAST(p_limit, 1000))
|
|
3325
|
-
LOOP
|
|
3326
|
-
v_pieces := GREATEST(0, COALESCE(r.pieces, 0));
|
|
3327
|
-
v_key := r.trade_item_id;
|
|
3328
|
-
|
|
3329
|
-
-- Reservering: openstaande orders reserveren, geannuleerde geven vrij.
|
|
3330
|
-
IF r.is_deleted OR COALESCE(r.status, '') IN ('CANCELLED', 'REJECTED', 'EXPIRED') THEN
|
|
3331
|
-
v_delta := 0;
|
|
3332
|
-
ELSE
|
|
3333
|
-
v_delta := v_pieces;
|
|
3334
|
-
END IF;
|
|
3335
|
-
|
|
3336
|
-
IF v_key IS NOT NULL AND v_delta > 0 THEN
|
|
3337
|
-
SELECT user_id INTO v_user FROM public.trade_item_stock
|
|
3338
|
-
WHERE connection_id = r.connection_id AND trade_item_key = v_key LIMIT 1;
|
|
3339
|
-
|
|
3340
|
-
IF v_user IS NOT NULL THEN
|
|
3341
|
-
UPDATE public.trade_item_stock
|
|
3342
|
-
SET reserved_stock = GREATEST(0, COALESCE(reserved_stock, 0) + v_delta),
|
|
3343
|
-
change_source = 'FLORIDAY_ORDER',
|
|
3344
|
-
updated_at = now()
|
|
3345
|
-
WHERE connection_id = r.connection_id
|
|
3346
|
-
AND trade_item_key = v_key;
|
|
3347
|
-
END IF;
|
|
3348
|
-
END IF;
|
|
3349
|
-
|
|
3350
|
-
---------------------------------------------------------------
|
|
3351
|
-
-- Fustenafschrijving
|
|
3352
|
-
---------------------------------------------------------------
|
|
3353
|
-
v_fust_key := NULL;
|
|
3354
|
-
v_packages := 0;
|
|
3355
|
-
v_fust_id := NULL;
|
|
3356
|
-
|
|
3357
|
-
-- Belading: eerst die van de order zelf, anders de primaire belading
|
|
3358
|
-
-- van het artikel uit de cache.
|
|
3359
|
-
v_packing := r.order_packing;
|
|
3360
|
-
IF v_packing IS NULL OR v_packing = 'null'::jsonb THEN
|
|
3361
|
-
SELECT p INTO v_packing
|
|
3362
|
-
FROM public.floriday_trade_items_cache tic
|
|
3363
|
-
CROSS JOIN LATERAL jsonb_array_elements(
|
|
3364
|
-
COALESCE(tic.data->'packingConfigurations', '[]'::jsonb)
|
|
3365
|
-
) AS p
|
|
3366
|
-
WHERE tic.connection_id = r.connection_id
|
|
3367
|
-
AND tic.floriday_id = v_key
|
|
3368
|
-
ORDER BY COALESCE((p->>'primary')::boolean, (p->>'isPrimary')::boolean, false) DESC
|
|
3369
|
-
LIMIT 1;
|
|
3370
|
-
END IF;
|
|
3371
|
-
|
|
3372
|
-
IF v_packing IS NOT NULL AND v_packing <> 'null'::jsonb THEN
|
|
3373
|
-
v_vbn := COALESCE(
|
|
3374
|
-
NULLIF(v_packing->'package'->>'vbnPackageCode', ''),
|
|
3375
|
-
NULLIF(v_packing->>'vbnPackageCode', ''),
|
|
3376
|
-
NULLIF(v_packing->>'packagingType', '')
|
|
3377
|
-
);
|
|
3378
|
-
v_custom := COALESCE(
|
|
3379
|
-
NULLIF(v_packing->'package'->>'customPackageId', ''),
|
|
3380
|
-
NULLIF(v_packing->>'packagingMaterialId', '')
|
|
3381
|
-
);
|
|
3382
|
-
IF v_vbn IS NOT NULL THEN
|
|
3383
|
-
v_fust_key := 'vbn:' || v_vbn;
|
|
3384
|
-
ELSIF v_custom IS NOT NULL THEN
|
|
3385
|
-
v_fust_key := 'custom:' || v_custom;
|
|
3386
|
-
END IF;
|
|
3387
|
-
|
|
3388
|
-
v_per_package := GREATEST(1, COALESCE(
|
|
3389
|
-
NULLIF(v_packing->>'piecesPerPackage', '')::int,
|
|
3390
|
-
NULLIF(v_packing->>'unitsPerPackage', '')::int,
|
|
3391
|
-
1
|
|
3392
|
-
));
|
|
3393
|
-
v_packages := CEIL(v_pieces::numeric / v_per_package)::int;
|
|
3394
|
-
END IF;
|
|
3395
|
-
|
|
3396
|
-
IF v_fust_key IS NOT NULL AND v_packages > 0 AND NOT EXISTS (SELECT 1 FROM public.order_fust_bookings b JOIN public.order_items oi ON oi.id = b.order_item_id WHERE oi.source_line_key = r.floriday_id) THEN
|
|
3397
|
-
v_fust_id := public.voorraad_active_fust_id(v_fust_key, NULL);
|
|
3398
|
-
|
|
3399
|
-
IF v_fust_id IS NULL THEN
|
|
3400
|
-
SELECT user_id INTO v_owner FROM public.fust_types LIMIT 1;
|
|
3401
|
-
IF v_owner IS NULL THEN
|
|
3402
|
-
SELECT user_id INTO v_owner FROM public.trade_item_stock
|
|
3403
|
-
WHERE connection_id = r.connection_id LIMIT 1;
|
|
3404
|
-
END IF;
|
|
3405
|
-
IF v_owner IS NOT NULL THEN
|
|
3406
|
-
INSERT INTO public.fust_types (
|
|
3407
|
-
user_id, connection_id, fust_key, name, source, vbn_code,
|
|
3408
|
-
custom_package_id, in_use, used_by_count
|
|
3409
|
-
) VALUES (
|
|
3410
|
-
v_owner, NULL, v_fust_key,
|
|
3411
|
-
CASE WHEN v_vbn IS NOT NULL THEN 'VBN-fust ' || v_vbn
|
|
3412
|
-
ELSE 'Eigen fust ' || left(COALESCE(v_custom, ''), 8) END,
|
|
3413
|
-
CASE WHEN v_vbn IS NOT NULL THEN 'VBN' ELSE 'SUPPLIER' END,
|
|
3414
|
-
CASE WHEN v_vbn ~ '^[0-9]+$' THEN v_vbn::int ELSE NULL END,
|
|
3415
|
-
CASE WHEN v_vbn IS NULL THEN v_custom ELSE NULL END,
|
|
3416
|
-
true, 1
|
|
3417
|
-
)
|
|
3418
|
-
ON CONFLICT (user_id, connection_id, fust_key) DO NOTHING
|
|
3419
|
-
RETURNING id INTO v_fust_id;
|
|
3420
|
-
|
|
3421
|
-
IF v_fust_id IS NULL THEN
|
|
3422
|
-
v_fust_id := public.voorraad_active_fust_id(v_fust_key, NULL);
|
|
3423
|
-
END IF;
|
|
3424
|
-
END IF;
|
|
3425
|
-
END IF;
|
|
3426
|
-
END IF;
|
|
3427
|
-
|
|
3428
|
-
IF v_fust_id IS NOT NULL AND public.voorraad_fust_voor_startmoment(v_fust_id, public.voorraad_lever_datum(r.lever_at)) THEN
|
|
3429
|
-
v_packages := 0; -- leverdatum vóór het fust-startmoment: geen fustboeking
|
|
3430
|
-
ELSIF v_fust_id IS NOT NULL THEN
|
|
3431
|
-
-- Eerder geboekt aantal voor deze order (vorige versie) terugdraaien.
|
|
3432
|
-
SELECT COALESCE(MAX((i.impact->>'fustPackages')::int), 0)
|
|
3433
|
-
INTO v_prev_packages
|
|
3434
|
-
FROM public.floriday_sales_order_ingest i
|
|
3435
|
-
WHERE i.connection_id = r.connection_id
|
|
3436
|
-
AND i.sales_order_id = r.floriday_id
|
|
3437
|
-
AND (i.impact->>'fustTypeId') = v_fust_id::text;
|
|
3438
|
-
|
|
3439
|
-
IF r.is_deleted OR COALESCE(r.status, '') IN ('CANCELLED', 'REJECTED', 'EXPIRED') THEN
|
|
3440
|
-
v_fust_delta := v_prev_packages; -- alles teruggeven
|
|
3441
|
-
v_packages := 0;
|
|
3442
|
-
ELSE
|
|
3443
|
-
v_fust_delta := -(v_packages - COALESCE(v_prev_packages, 0));
|
|
3444
|
-
END IF;
|
|
3445
|
-
|
|
3446
|
-
IF v_fust_delta <> 0 THEN
|
|
3447
|
-
SELECT user_id INTO v_owner FROM public.fust_types WHERE id = v_fust_id;
|
|
3448
|
-
INSERT INTO public.fust_stock_mutations (
|
|
3449
|
-
user_id, fust_type_id, delta, reason, note, trade_item_key
|
|
3450
|
-
) VALUES (
|
|
3451
|
-
v_owner, v_fust_id, v_fust_delta,
|
|
3452
|
-
CASE WHEN v_fust_delta < 0 THEN 'sale' ELSE 'sale_cancelled' END,
|
|
3453
|
-
'Floriday-order ' || r.floriday_id || ' (' || v_pieces || ' stuks)',
|
|
3454
|
-
v_key
|
|
3455
|
-
);
|
|
3456
|
-
END IF;
|
|
3457
|
-
END IF;
|
|
3458
|
-
|
|
3459
|
-
INSERT INTO public.floriday_sales_order_ingest (
|
|
3460
|
-
connection_id, sales_order_id, order_version, order_status, impact
|
|
3461
|
-
) VALUES (
|
|
3462
|
-
r.connection_id, r.floriday_id, r.version, r.status,
|
|
3463
|
-
jsonb_build_object(
|
|
3464
|
-
'tradeItemId', v_key,
|
|
3465
|
-
'reservedDelta', v_delta,
|
|
3466
|
-
'fustTypeId', v_fust_id,
|
|
3467
|
-
'fustKey', v_fust_key,
|
|
3468
|
-
'fustPackages', v_packages,
|
|
3469
|
-
'voorStartmoment', public.voorraad_fust_voor_startmoment(v_fust_id, public.voorraad_lever_datum(r.lever_at))
|
|
3470
|
-
)
|
|
3471
|
-
)
|
|
3472
|
-
ON CONFLICT (connection_id, sales_order_id, order_version) DO NOTHING;
|
|
3473
|
-
|
|
3474
|
-
v_count := v_count + 1;
|
|
3475
|
-
END LOOP;
|
|
3476
|
-
|
|
3477
|
-
RETURN v_count;
|
|
3478
|
-
END;
|
|
3479
|
-
$function$
|
|
2999
|
+
BEGIN
|
|
3000
|
+
PERFORM public.voorraad_vereis('server', 'floriday_ingest_sales_orders');
|
|
3001
|
+
RAISE EXCEPTION 'Deze functie is uitgeschakeld: Floriday-orders worden verwerkt door de minuutronde.' USING ERRCODE = 'P0001';
|
|
3002
|
+
END $function$
|
|
3480
3003
|
;
|
|
3481
3004
|
REVOKE ALL ON FUNCTION floriday_ingest_sales_orders(integer) FROM PUBLIC;
|
|
3482
3005
|
REVOKE ALL ON FUNCTION floriday_ingest_sales_orders(integer) FROM anon;
|
|
@@ -3616,7 +3139,7 @@ BEGIN
|
|
|
3616
3139
|
|
|
3617
3140
|
IF TG_OP = 'UPDATE' THEN
|
|
3618
3141
|
IF NEW.status = 'pending' AND OLD.status IS DISTINCT FROM 'pending'
|
|
3619
|
-
AND (OLD.status IN ('blocked_by_gate','skipped_week_closed') OR NOT COALESCE(v_found,false) OR v_lead IS FALSE) THEN
|
|
3142
|
+
AND (OLD.status IN ('blocked_by_gate','skipped_week_closed') OR NOT COALESCE(v_found,false) OR (v_lead IS FALSE AND NOT COALESCE(NEW.voorraad_mutatie, false))) THEN
|
|
3620
3143
|
NEW.status := OLD.status;
|
|
3621
3144
|
END IF;
|
|
3622
3145
|
RETURN NEW;
|
|
@@ -3627,7 +3150,7 @@ BEGIN
|
|
|
3627
3150
|
IF NEW.target_week IS NOT NULL AND (COALESCE(NEW.target_year, v_cy), NEW.target_week) < (v_cy, v_cw) THEN
|
|
3628
3151
|
v_reason := 'Week ligt in het verleden'; v_status := 'skipped_week_closed';
|
|
3629
3152
|
ELSIF NOT COALESCE(v_found,false) THEN v_reason := 'Geen voorraadsturing voor dit artikel';
|
|
3630
|
-
ELSIF v_lead IS FALSE THEN v_reason := 'Floriday is leidend';
|
|
3153
|
+
ELSIF v_lead IS FALSE AND NOT COALESCE(NEW.voorraad_mutatie, false) THEN v_reason := 'Floriday is leidend';
|
|
3631
3154
|
ELSIF v_lead IS TRUE AND v_forms IS NOT NULL AND (
|
|
3632
3155
|
(NEW.target_week IS NULL AND COALESCE((v_forms->>'continuous')::boolean,false) = false)
|
|
3633
3156
|
OR (NEW.target_week IS NOT NULL AND COALESCE((v_forms->>'weekly')::boolean,false) = false)) THEN
|
|
@@ -5017,24 +4540,294 @@ $function$
|
|
|
5017
4540
|
REVOKE ALL ON FUNCTION product_type(uuid) FROM PUBLIC;
|
|
5018
4541
|
REVOKE ALL ON FUNCTION product_type(uuid) FROM anon;
|
|
5019
4542
|
GRANT EXECUTE ON FUNCTION product_type(uuid) TO service_role;
|
|
5020
|
-
CREATE OR REPLACE FUNCTION public.
|
|
5021
|
-
RETURNS
|
|
4543
|
+
CREATE OR REPLACE FUNCTION public.productie_order_aanmaken(p_product_id uuid, p_aantal numeric, p_opmerking text DEFAULT NULL::text)
|
|
4544
|
+
RETURNS jsonb
|
|
5022
4545
|
LANGUAGE plpgsql
|
|
5023
4546
|
SECURITY DEFINER
|
|
5024
4547
|
SET search_path TO 'public'
|
|
5025
4548
|
AS $function$
|
|
5026
|
-
DECLARE
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
4549
|
+
DECLARE
|
|
4550
|
+
v_id uuid := gen_random_uuid(); v_nr text; v_pkey text; b record; m record; v_need numeric; v_rem numeric;
|
|
4551
|
+
v_key text; v_last_key text; v_last_pid uuid; v_last_name text; v_avail numeric; v_take numeric; v_planned numeric;
|
|
4552
|
+
v_keys text[]; v_tekort jsonb := '[]'::jsonb; d record; v_vrij numeric; v_naam text;
|
|
4553
|
+
BEGIN
|
|
4554
|
+
PERFORM public.voorraad_vereis('ingelogd', 'productie_order_aanmaken');
|
|
4555
|
+
IF NOT public.voorraad_can_write() THEN RAISE EXCEPTION 'Je hebt geen rechten om voorraad te wijzigen.' USING ERRCODE = '42501'; END IF;
|
|
4556
|
+
IF p_product_id IS NULL OR COALESCE(p_aantal, 0) <= 0 THEN RAISE EXCEPTION 'Kies een samenstelling en een aantal groter dan 0.' USING ERRCODE = 'P0001'; END IF;
|
|
4557
|
+
IF NOT EXISTS (SELECT 1 FROM public.product_bom_items x WHERE x.parent_product_id = p_product_id) THEN
|
|
4558
|
+
RAISE EXCEPTION 'Dit artikel heeft geen stuklijst; kies een samenstelling.' USING ERRCODE = 'P0001';
|
|
4559
|
+
END IF;
|
|
4560
|
+
v_pkey := public.ensure_trade_item_stock_row_key(p_product_id::text);
|
|
4561
|
+
IF v_pkey IS NULL THEN RAISE EXCEPTION 'Voor deze samenstelling is geen voorraadregel te maken.' USING ERRCODE = 'P0001'; END IF;
|
|
4562
|
+
v_nr := 'PO-' || lpad(nextval('public.productie_order_nummer_seq')::text, 6, '0');
|
|
4563
|
+
INSERT INTO public.productie_orders(id, nummer, product_id, trade_item_key, aantal, opmerking, aangemaakt_door)
|
|
4564
|
+
VALUES (v_id, v_nr, p_product_id, v_pkey, p_aantal, NULLIF(btrim(COALESCE(p_opmerking, '')), ''), auth.uid());
|
|
4565
|
+
|
|
4566
|
+
-- Stuklijst vastleggen; groepen vertaald zoals de productie dat deed (volgorde groep, beschikbaar), rest op het laatste lid.
|
|
4567
|
+
FOR b IN SELECT bi.*, p.product AS pnaam, g.id AS gid, g.name AS gnaam
|
|
4568
|
+
FROM public.product_bom_items bi
|
|
4569
|
+
LEFT JOIN public.products p ON p.id = bi.component_product_id
|
|
4570
|
+
LEFT JOIN public.product_groups g ON g.is_active = true AND (g.head_product_id = bi.component_product_id
|
|
4571
|
+
OR g.head_trade_item_floriday_id = bi.component_trade_item_floriday_id)
|
|
4572
|
+
WHERE bi.parent_product_id = p_product_id ORDER BY bi.sort_order NULLS LAST, bi.created_at LOOP
|
|
4573
|
+
v_need := COALESCE(b.quantity, 1) * p_aantal;
|
|
4574
|
+
IF b.gid IS NOT NULL THEN
|
|
4575
|
+
v_rem := v_need; v_last_key := NULL;
|
|
4576
|
+
FOR m IN SELECT gi.trade_item_id, p2.id AS pid, p2.product AS naam
|
|
4577
|
+
FROM public.product_group_items gi LEFT JOIN public.products p2 ON p2.id::text = gi.trade_item_id
|
|
4578
|
+
WHERE gi.product_group_id = b.gid ORDER BY gi.sort_order ASC NULLS LAST, gi.created_at ASC NULLS LAST LOOP
|
|
4579
|
+
v_key := public.ensure_trade_item_stock_row_key(COALESCE(m.pid::text, m.trade_item_id));
|
|
4580
|
+
IF v_key IS NULL THEN CONTINUE; END IF;
|
|
4581
|
+
v_last_key := v_key; v_last_pid := m.pid; v_last_name := COALESCE(m.naam, m.trade_item_id);
|
|
4582
|
+
IF v_rem <= 0 THEN CONTINUE; END IF;
|
|
4583
|
+
SELECT COALESCE(SUM(aantal), 0) INTO v_planned FROM public.productie_order_onderdelen WHERE productie_order_id = v_id AND trade_item_key = v_key;
|
|
4584
|
+
SELECT GREATEST(COALESCE(MAX(s.physical_stock), 0) - v_planned, 0) INTO v_avail FROM public.trade_item_stock s WHERE s.trade_item_key = v_key;
|
|
4585
|
+
v_take := LEAST(v_rem, COALESCE(v_avail, 0));
|
|
4586
|
+
IF v_take > 0 THEN
|
|
4587
|
+
INSERT INTO public.productie_order_onderdelen(productie_order_id, product_id, trade_item_key, naam, aantal)
|
|
4588
|
+
VALUES (v_id, m.pid, v_key, COALESCE(m.naam, m.trade_item_id), v_take);
|
|
4589
|
+
v_rem := v_rem - v_take;
|
|
4590
|
+
END IF;
|
|
4591
|
+
END LOOP;
|
|
4592
|
+
IF v_rem > 0 THEN
|
|
4593
|
+
IF v_last_key IS NULL THEN
|
|
4594
|
+
RAISE EXCEPTION 'De groep "%" in de stuklijst heeft geen leden met voorraad; pas de stuklijst aan.', COALESCE(b.gnaam, '?') USING ERRCODE = 'P0001';
|
|
4595
|
+
END IF;
|
|
4596
|
+
INSERT INTO public.productie_order_onderdelen(productie_order_id, product_id, trade_item_key, naam, aantal)
|
|
4597
|
+
VALUES (v_id, v_last_pid, v_last_key, v_last_name, v_rem);
|
|
4598
|
+
END IF;
|
|
4599
|
+
ELSE
|
|
4600
|
+
v_key := public.ensure_trade_item_stock_row_key(COALESCE(b.component_product_id::text, b.component_trade_item_floriday_id));
|
|
4601
|
+
IF v_key IS NULL THEN
|
|
4602
|
+
RAISE EXCEPTION 'Een onderdeel in de stuklijst heeft geen voorraadregel (%); pas de stuklijst aan.', COALESCE(b.pnaam, b.component_trade_item_floriday_id, '?') USING ERRCODE = 'P0001';
|
|
4603
|
+
END IF;
|
|
4604
|
+
INSERT INTO public.productie_order_onderdelen(productie_order_id, product_id, trade_item_key, naam, aantal)
|
|
4605
|
+
VALUES (v_id, b.component_product_id, v_key, COALESCE(b.pnaam, b.component_trade_item_floriday_id), v_need);
|
|
4606
|
+
END IF;
|
|
4607
|
+
END LOOP;
|
|
4608
|
+
|
|
4609
|
+
SELECT array_agg(DISTINCT x ORDER BY x) INTO v_keys FROM (SELECT trade_item_key x FROM public.productie_order_onderdelen WHERE productie_order_id = v_id UNION SELECT v_pkey) s;
|
|
4610
|
+
PERFORM public.voorraad_lock_sleutels(v_keys);
|
|
4611
|
+
|
|
4612
|
+
-- Tekort bepalen vóór de eigen reservering: vrij = fysiek − gereserveerd.
|
|
4613
|
+
FOR d IN SELECT trade_item_key, MAX(naam) AS naam, SUM(aantal) AS aantal FROM public.productie_order_onderdelen
|
|
4614
|
+
WHERE productie_order_id = v_id GROUP BY trade_item_key ORDER BY trade_item_key LOOP
|
|
4615
|
+
SELECT COALESCE(MAX(s.physical_stock), 0) - COALESCE(MAX(s.reserved_stock), 0) INTO v_vrij FROM public.trade_item_stock s WHERE s.trade_item_key = d.trade_item_key;
|
|
4616
|
+
IF d.aantal > GREATEST(COALESCE(v_vrij, 0), 0) THEN
|
|
4617
|
+
v_tekort := v_tekort || jsonb_build_object('trade_item_key', d.trade_item_key, 'naam', d.naam,
|
|
4618
|
+
'tekort', d.aantal - GREATEST(COALESCE(v_vrij, 0), 0),
|
|
4619
|
+
'tekst', 'Tekort: ' || trim(to_char(d.aantal - GREATEST(COALESCE(v_vrij, 0), 0), 'FM999999990.##')) || ' × ' || COALESCE(d.naam, d.trade_item_key));
|
|
4620
|
+
END IF;
|
|
4621
|
+
PERFORM public.voorraad_reservering_verschil(d.trade_item_key, d.aantal);
|
|
4622
|
+
END LOOP;
|
|
4623
|
+
|
|
4624
|
+
PERFORM set_config('stock.change_source', 'PRODUCTION', true);
|
|
4625
|
+
UPDATE public.trade_item_stock SET incoming_stock = COALESCE(incoming_stock, 0) + CEIL(p_aantal)::integer, change_source = 'PRODUCTION', updated_at = now()
|
|
4626
|
+
WHERE trade_item_key = v_pkey;
|
|
4627
|
+
INSERT INTO public.stock_mutation_log(trade_item_key, mutation_type, qty_delta, reason, created_by, production_batch_id)
|
|
4628
|
+
VALUES (v_pkey, 'production', 0, v_nr || ': productieorder aangemaakt, inkomend +' || p_aantal, auth.uid(), v_id);
|
|
4629
|
+
|
|
4630
|
+
RETURN jsonb_build_object('id', v_id, 'nummer', v_nr, 'status', 'open', 'tekorten', v_tekort);
|
|
4631
|
+
END $function$
|
|
4632
|
+
;
|
|
4633
|
+
REVOKE ALL ON FUNCTION productie_order_aanmaken(uuid,numeric,text) FROM PUBLIC;
|
|
4634
|
+
REVOKE ALL ON FUNCTION productie_order_aanmaken(uuid,numeric,text) FROM anon;
|
|
4635
|
+
GRANT EXECUTE ON FUNCTION productie_order_aanmaken(uuid,numeric,text) TO authenticated;
|
|
4636
|
+
GRANT EXECUTE ON FUNCTION productie_order_aanmaken(uuid,numeric,text) TO service_role;
|
|
4637
|
+
CREATE OR REPLACE FUNCTION public.productie_order_annuleren(p_id uuid, p_reden text DEFAULT NULL::text)
|
|
4638
|
+
RETURNS jsonb
|
|
4639
|
+
LANGUAGE plpgsql
|
|
4640
|
+
SECURITY DEFINER
|
|
4641
|
+
SET search_path TO 'public'
|
|
4642
|
+
AS $function$
|
|
4643
|
+
DECLARE po record; d record; v_keys text[];
|
|
4644
|
+
BEGIN
|
|
4645
|
+
PERFORM public.voorraad_vereis('ingelogd', 'productie_order_annuleren');
|
|
4646
|
+
IF NOT public.voorraad_can_write() THEN RAISE EXCEPTION 'Je hebt geen rechten om voorraad te wijzigen.' USING ERRCODE = '42501'; END IF;
|
|
4647
|
+
SELECT * INTO po FROM public.productie_orders WHERE id = p_id FOR UPDATE;
|
|
4648
|
+
IF NOT FOUND THEN RAISE EXCEPTION 'Deze productieorder bestaat niet.' USING ERRCODE = 'P0001'; END IF;
|
|
4649
|
+
IF po.status = 'geannuleerd' THEN RETURN jsonb_build_object('status', 'al_geannuleerd', 'nummer', po.nummer); END IF;
|
|
4650
|
+
IF po.status <> 'open' THEN RAISE EXCEPTION 'Alleen een open productieorder kan worden geannuleerd.' USING ERRCODE = 'P0001'; END IF;
|
|
4651
|
+
SELECT array_agg(DISTINCT x ORDER BY x) INTO v_keys FROM (SELECT trade_item_key x FROM public.productie_order_onderdelen WHERE productie_order_id = p_id UNION SELECT po.trade_item_key) s;
|
|
4652
|
+
PERFORM public.voorraad_lock_sleutels(v_keys);
|
|
4653
|
+
UPDATE public.productie_orders SET status = 'geannuleerd', geannuleerd_door = auth.uid(), geannuleerd_op = now(),
|
|
4654
|
+
reden = NULLIF(btrim(COALESCE(p_reden, '')), '') WHERE id = p_id;
|
|
4655
|
+
FOR d IN SELECT trade_item_key, SUM(aantal) AS aantal FROM public.productie_order_onderdelen WHERE productie_order_id = p_id GROUP BY 1 ORDER BY 1 LOOP
|
|
4656
|
+
PERFORM public.voorraad_reservering_verschil(d.trade_item_key, -d.aantal);
|
|
4657
|
+
END LOOP;
|
|
4658
|
+
PERFORM set_config('stock.change_source', 'PRODUCTION', true);
|
|
4659
|
+
UPDATE public.trade_item_stock SET incoming_stock = GREATEST(COALESCE(incoming_stock, 0) - CEIL(po.aantal)::integer, 0), change_source = 'PRODUCTION', updated_at = now()
|
|
4660
|
+
WHERE trade_item_key = po.trade_item_key;
|
|
4661
|
+
INSERT INTO public.stock_mutation_log(trade_item_key, mutation_type, qty_delta, reason, created_by, production_batch_id)
|
|
4662
|
+
VALUES (po.trade_item_key, 'production', 0, po.nummer || ': geannuleerd, inkomend −' || po.aantal, auth.uid(), p_id);
|
|
4663
|
+
RETURN jsonb_build_object('status', 'geannuleerd', 'nummer', po.nummer);
|
|
4664
|
+
END $function$
|
|
4665
|
+
;
|
|
4666
|
+
REVOKE ALL ON FUNCTION productie_order_annuleren(uuid,text) FROM PUBLIC;
|
|
4667
|
+
REVOKE ALL ON FUNCTION productie_order_annuleren(uuid,text) FROM anon;
|
|
4668
|
+
GRANT EXECUTE ON FUNCTION productie_order_annuleren(uuid,text) TO authenticated;
|
|
4669
|
+
GRANT EXECUTE ON FUNCTION productie_order_annuleren(uuid,text) TO service_role;
|
|
4670
|
+
CREATE OR REPLACE FUNCTION public.productie_order_geprint(p_id uuid)
|
|
4671
|
+
RETURNS jsonb
|
|
4672
|
+
LANGUAGE plpgsql
|
|
4673
|
+
SECURITY DEFINER
|
|
4674
|
+
SET search_path TO 'public'
|
|
4675
|
+
AS $function$
|
|
4676
|
+
DECLARE v_op timestamptz;
|
|
4677
|
+
BEGIN
|
|
4678
|
+
PERFORM public.voorraad_vereis('ingelogd', 'productie_order_geprint');
|
|
4679
|
+
UPDATE public.productie_orders SET geprint_op = now() WHERE id = p_id RETURNING geprint_op INTO v_op;
|
|
4680
|
+
IF v_op IS NULL THEN RAISE EXCEPTION 'Deze productieorder bestaat niet.' USING ERRCODE = 'P0001'; END IF;
|
|
4681
|
+
RETURN jsonb_build_object('geprint_op', v_op);
|
|
4682
|
+
END $function$
|
|
4683
|
+
;
|
|
4684
|
+
REVOKE ALL ON FUNCTION productie_order_geprint(uuid) FROM PUBLIC;
|
|
4685
|
+
REVOKE ALL ON FUNCTION productie_order_geprint(uuid) FROM anon;
|
|
4686
|
+
GRANT EXECUTE ON FUNCTION productie_order_geprint(uuid) TO authenticated;
|
|
4687
|
+
GRANT EXECUTE ON FUNCTION productie_order_geprint(uuid) TO service_role;
|
|
4688
|
+
CREATE OR REPLACE FUNCTION public.productie_order_terugdraaien(p_id uuid, p_reden text)
|
|
4689
|
+
RETURNS jsonb
|
|
4690
|
+
LANGUAGE plpgsql
|
|
4691
|
+
SECURITY DEFINER
|
|
4692
|
+
SET search_path TO 'public'
|
|
4693
|
+
AS $function$
|
|
4694
|
+
DECLARE po record; d record; v_keys text[]; v_before numeric; v_after numeric; v_conn uuid;
|
|
4695
|
+
BEGIN
|
|
4696
|
+
PERFORM public.voorraad_vereis('ingelogd', 'productie_order_terugdraaien');
|
|
4697
|
+
IF NOT public.voorraad_is_beheerder() THEN
|
|
4698
|
+
RAISE EXCEPTION 'Alleen een beheerder kan een verwerkte productieorder terugdraaien.' USING ERRCODE = '42501';
|
|
4699
|
+
END IF;
|
|
4700
|
+
IF NULLIF(btrim(COALESCE(p_reden, '')), '') IS NULL THEN RAISE EXCEPTION 'Geef een reden op.' USING ERRCODE = 'P0001'; END IF;
|
|
4701
|
+
SELECT * INTO po FROM public.productie_orders WHERE id = p_id FOR UPDATE;
|
|
4702
|
+
IF NOT FOUND THEN RAISE EXCEPTION 'Deze productieorder bestaat niet.' USING ERRCODE = 'P0001'; END IF;
|
|
4703
|
+
IF po.status = 'teruggedraaid' THEN RETURN jsonb_build_object('status', 'al_teruggedraaid', 'nummer', po.nummer); END IF;
|
|
4704
|
+
IF po.status <> 'verwerkt' THEN RAISE EXCEPTION 'Alleen een verwerkte productieorder kan worden teruggedraaid.' USING ERRCODE = 'P0001'; END IF;
|
|
4705
|
+
SELECT array_agg(DISTINCT x ORDER BY x) INTO v_keys FROM (SELECT trade_item_key x FROM public.productie_order_onderdelen WHERE productie_order_id = p_id UNION SELECT po.trade_item_key) s;
|
|
4706
|
+
PERFORM public.voorraad_lock_sleutels(v_keys);
|
|
4707
|
+
PERFORM set_config('stock.change_source', 'PRODUCTION', true);
|
|
4708
|
+
FOR d IN SELECT trade_item_key, SUM(aantal) AS aantal FROM public.productie_order_onderdelen WHERE productie_order_id = p_id GROUP BY 1 ORDER BY 1 LOOP
|
|
4709
|
+
SELECT physical_stock, connection_id INTO v_before, v_conn FROM public.trade_item_stock WHERE trade_item_key = d.trade_item_key ORDER BY updated_at DESC NULLS LAST LIMIT 1 FOR UPDATE;
|
|
4710
|
+
v_before := COALESCE(v_before, 0); v_after := v_before + d.aantal;
|
|
4711
|
+
UPDATE public.trade_item_stock SET physical_stock = v_after::integer, change_source = 'PRODUCTION', updated_at = now() WHERE trade_item_key = d.trade_item_key;
|
|
4712
|
+
INSERT INTO public.stock_mutation_log(trade_item_key, connection_id, mutation_type, qty_delta, physical_before, physical_after, reason, created_by, production_batch_id)
|
|
4713
|
+
VALUES (d.trade_item_key, v_conn, 'production_reverse', d.aantal, v_before, v_after, po.nummer || ': terugdraaien onderdeel, reden ' || p_reden, auth.uid(), p_id);
|
|
4714
|
+
END LOOP;
|
|
4715
|
+
SELECT physical_stock, connection_id INTO v_before, v_conn FROM public.trade_item_stock WHERE trade_item_key = po.trade_item_key ORDER BY updated_at DESC NULLS LAST LIMIT 1 FOR UPDATE;
|
|
4716
|
+
v_before := COALESCE(v_before, 0); v_after := v_before - po.aantal;
|
|
4717
|
+
UPDATE public.trade_item_stock SET physical_stock = v_after::integer, change_source = 'PRODUCTION', updated_at = now() WHERE trade_item_key = po.trade_item_key;
|
|
4718
|
+
INSERT INTO public.stock_mutation_log(trade_item_key, connection_id, mutation_type, qty_delta, physical_before, physical_after, reason, created_by, production_batch_id)
|
|
4719
|
+
VALUES (po.trade_item_key, v_conn, 'production_reverse', -po.aantal, v_before, v_after, po.nummer || ': terugdraaien samenstelling, reden ' || p_reden, auth.uid(), p_id);
|
|
4720
|
+
UPDATE public.productie_orders SET status = 'teruggedraaid', teruggedraaid_door = auth.uid(), teruggedraaid_op = now(), reden = p_reden WHERE id = p_id;
|
|
4721
|
+
RETURN jsonb_build_object('status', 'teruggedraaid', 'nummer', po.nummer);
|
|
4722
|
+
END $function$
|
|
4723
|
+
;
|
|
4724
|
+
REVOKE ALL ON FUNCTION productie_order_terugdraaien(uuid,text) FROM PUBLIC;
|
|
4725
|
+
REVOKE ALL ON FUNCTION productie_order_terugdraaien(uuid,text) FROM anon;
|
|
4726
|
+
GRANT EXECUTE ON FUNCTION productie_order_terugdraaien(uuid,text) TO authenticated;
|
|
4727
|
+
GRANT EXECUTE ON FUNCTION productie_order_terugdraaien(uuid,text) TO service_role;
|
|
4728
|
+
CREATE OR REPLACE FUNCTION public.productie_order_verwerken(p_id uuid)
|
|
4729
|
+
RETURNS jsonb
|
|
4730
|
+
LANGUAGE plpgsql
|
|
4731
|
+
SECURITY DEFINER
|
|
4732
|
+
SET search_path TO 'public'
|
|
4733
|
+
AS $function$
|
|
4734
|
+
DECLARE po record; d record; v_keys text[]; v_before numeric; v_after numeric; v_conn uuid; v_warn jsonb := '[]'::jsonb;
|
|
4735
|
+
BEGIN
|
|
4736
|
+
PERFORM public.voorraad_vereis('ingelogd', 'productie_order_verwerken');
|
|
4737
|
+
IF NOT public.voorraad_can_write() THEN RAISE EXCEPTION 'Je hebt geen rechten om voorraad te wijzigen.' USING ERRCODE = '42501'; END IF;
|
|
4738
|
+
SELECT * INTO po FROM public.productie_orders WHERE id = p_id FOR UPDATE;
|
|
4739
|
+
IF NOT FOUND THEN RAISE EXCEPTION 'Deze productieorder bestaat niet.' USING ERRCODE = 'P0001'; END IF;
|
|
4740
|
+
IF po.status = 'verwerkt' THEN RETURN jsonb_build_object('status', 'al_verwerkt', 'nummer', po.nummer, 'waarschuwingen', po.waarschuwingen); END IF;
|
|
4741
|
+
IF po.status <> 'open' THEN RAISE EXCEPTION 'Deze productieorder is % en kan niet meer worden verwerkt.', po.status USING ERRCODE = 'P0001'; END IF;
|
|
4742
|
+
SELECT array_agg(DISTINCT x ORDER BY x) INTO v_keys FROM (SELECT trade_item_key x FROM public.productie_order_onderdelen WHERE productie_order_id = p_id UNION SELECT po.trade_item_key) s;
|
|
4743
|
+
PERFORM public.voorraad_lock_sleutels(v_keys);
|
|
4744
|
+
PERFORM set_config('stock.change_source', 'PRODUCTION', true);
|
|
4745
|
+
|
|
4746
|
+
FOR d IN SELECT trade_item_key, MAX(naam) AS naam, SUM(aantal) AS aantal FROM public.productie_order_onderdelen
|
|
4747
|
+
WHERE productie_order_id = p_id GROUP BY trade_item_key ORDER BY trade_item_key LOOP
|
|
4748
|
+
SELECT physical_stock, connection_id INTO v_before, v_conn FROM public.trade_item_stock WHERE trade_item_key = d.trade_item_key ORDER BY updated_at DESC NULLS LAST LIMIT 1 FOR UPDATE;
|
|
4749
|
+
v_before := COALESCE(v_before, 0); v_after := v_before - d.aantal;
|
|
4750
|
+
UPDATE public.trade_item_stock
|
|
4751
|
+
SET physical_stock = v_after::integer, reserved_stock = GREATEST(COALESCE(reserved_stock, 0) - CEIL(d.aantal)::integer, 0),
|
|
4752
|
+
change_source = 'PRODUCTION', updated_at = now()
|
|
4753
|
+
WHERE trade_item_key = d.trade_item_key;
|
|
4754
|
+
INSERT INTO public.stock_mutation_log(trade_item_key, connection_id, mutation_type, qty_delta, physical_before, physical_after, reason, created_by, production_batch_id)
|
|
4755
|
+
VALUES (d.trade_item_key, v_conn, 'production_consume', -d.aantal, v_before, v_after, po.nummer || ': verbruik voor productie', auth.uid(), p_id);
|
|
4756
|
+
IF v_after < 0 THEN
|
|
4757
|
+
v_warn := v_warn || jsonb_build_object('trade_item_key', d.trade_item_key, 'naam', d.naam, 'stand', v_after,
|
|
4758
|
+
'tekst', COALESCE(d.naam, d.trade_item_key) || ' staat nu op ' || trim(to_char(v_after, 'FM999999990.##')) || '; controleer de voorraad');
|
|
4759
|
+
END IF;
|
|
4760
|
+
END LOOP;
|
|
4761
|
+
|
|
4762
|
+
SELECT physical_stock, connection_id INTO v_before, v_conn FROM public.trade_item_stock WHERE trade_item_key = po.trade_item_key ORDER BY updated_at DESC NULLS LAST LIMIT 1 FOR UPDATE;
|
|
4763
|
+
v_before := COALESCE(v_before, 0); v_after := v_before + po.aantal;
|
|
4764
|
+
UPDATE public.trade_item_stock
|
|
4765
|
+
SET physical_stock = v_after::integer, incoming_stock = GREATEST(COALESCE(incoming_stock, 0) - CEIL(po.aantal)::integer, 0),
|
|
4766
|
+
change_source = 'PRODUCTION', updated_at = now()
|
|
4767
|
+
WHERE trade_item_key = po.trade_item_key;
|
|
4768
|
+
INSERT INTO public.stock_mutation_log(trade_item_key, connection_id, mutation_type, qty_delta, physical_before, physical_after, reason, created_by, production_batch_id)
|
|
4769
|
+
VALUES (po.trade_item_key, v_conn, 'production_output', po.aantal, v_before, v_after, po.nummer || ': geproduceerd', auth.uid(), p_id);
|
|
4770
|
+
|
|
4771
|
+
UPDATE public.productie_orders SET status = 'verwerkt', verwerkt_door = auth.uid(), verwerkt_op = now(), waarschuwingen = v_warn WHERE id = p_id;
|
|
4772
|
+
RETURN jsonb_build_object('status', 'verwerkt', 'nummer', po.nummer, 'waarschuwingen', v_warn);
|
|
4773
|
+
END $function$
|
|
4774
|
+
;
|
|
4775
|
+
REVOKE ALL ON FUNCTION productie_order_verwerken(uuid) FROM PUBLIC;
|
|
4776
|
+
REVOKE ALL ON FUNCTION productie_order_verwerken(uuid) FROM anon;
|
|
4777
|
+
GRANT EXECUTE ON FUNCTION productie_order_verwerken(uuid) TO authenticated;
|
|
4778
|
+
GRANT EXECUTE ON FUNCTION productie_order_verwerken(uuid) TO service_role;
|
|
4779
|
+
CREATE OR REPLACE FUNCTION public.productie_orders_lijst(p_status text DEFAULT NULL::text, p_van timestamp with time zone DEFAULT NULL::timestamp with time zone, p_tot timestamp with time zone DEFAULT NULL::timestamp with time zone, p_zoek text DEFAULT NULL::text, p_limit integer DEFAULT 25, p_offset integer DEFAULT 0)
|
|
4780
|
+
RETURNS jsonb
|
|
4781
|
+
LANGUAGE plpgsql
|
|
4782
|
+
STABLE SECURITY DEFINER
|
|
4783
|
+
SET search_path TO 'public'
|
|
4784
|
+
AS $function$
|
|
4785
|
+
DECLARE v_rows jsonb; v_total bigint; v_z text := NULLIF(lower(btrim(COALESCE(p_zoek, ''))), '');
|
|
4786
|
+
v_st text[] := CASE WHEN p_status IS NULL OR p_status = '' THEN NULL
|
|
4787
|
+
WHEN p_status = 'geannuleerd' THEN ARRAY['geannuleerd','teruggedraaid'] ELSE ARRAY[p_status] END;
|
|
4788
|
+
BEGIN
|
|
4789
|
+
PERFORM public.voorraad_vereis('ingelogd', 'productie_orders_lijst');
|
|
4790
|
+
SELECT count(*) INTO v_total FROM public.productie_orders po LEFT JOIN public.products p ON p.id = po.product_id
|
|
4791
|
+
WHERE (v_st IS NULL OR po.status = ANY(v_st)) AND (p_van IS NULL OR po.aangemaakt_op >= p_van) AND (p_tot IS NULL OR po.aangemaakt_op < p_tot)
|
|
4792
|
+
AND (v_z IS NULL OR lower(po.nummer) LIKE '%' || v_z || '%' OR lower(COALESCE(p.product, '')) LIKE '%' || v_z || '%' OR lower(COALESCE(p.article_number, '')) LIKE '%' || v_z || '%');
|
|
4793
|
+
SELECT COALESCE(jsonb_agg(r ORDER BY (r->>'aangemaakt_op') DESC), '[]'::jsonb) INTO v_rows FROM (
|
|
4794
|
+
SELECT jsonb_build_object('id', po.id, 'nummer', po.nummer, 'product_id', po.product_id, 'naam', p.product, 'artikelcode', p.article_number,
|
|
4795
|
+
'aantal', po.aantal, 'status', po.status, 'opmerking', po.opmerking, 'aangemaakt_op', po.aangemaakt_op, 'aangemaakt_door', po.aangemaakt_door,
|
|
4796
|
+
'verwerkt_op', po.verwerkt_op, 'verwerkt_door', po.verwerkt_door, 'geannuleerd_op', po.geannuleerd_op,
|
|
4797
|
+
'teruggedraaid_op', po.teruggedraaid_op, 'teruggedraaid_door', po.teruggedraaid_door, 'reden', po.reden,
|
|
4798
|
+
'geprint_op', po.geprint_op, 'waarschuwingen', po.waarschuwingen,
|
|
4799
|
+
'onderdelen', (SELECT COALESCE(jsonb_agg(jsonb_build_object('product_id', d.product_id, 'naam', d.naam, 'aantal', d.aantal) ORDER BY d.naam), '[]'::jsonb)
|
|
4800
|
+
FROM public.productie_order_onderdelen d WHERE d.productie_order_id = po.id)) AS r
|
|
4801
|
+
FROM public.productie_orders po LEFT JOIN public.products p ON p.id = po.product_id
|
|
4802
|
+
WHERE (v_st IS NULL OR po.status = ANY(v_st)) AND (p_van IS NULL OR po.aangemaakt_op >= p_van) AND (p_tot IS NULL OR po.aangemaakt_op < p_tot)
|
|
4803
|
+
AND (v_z IS NULL OR lower(po.nummer) LIKE '%' || v_z || '%' OR lower(COALESCE(p.product, '')) LIKE '%' || v_z || '%' OR lower(COALESCE(p.article_number, '')) LIKE '%' || v_z || '%')
|
|
4804
|
+
ORDER BY po.aangemaakt_op DESC
|
|
4805
|
+
LIMIT LEAST(GREATEST(COALESCE(p_limit, 25), 1), 500) OFFSET GREATEST(COALESCE(p_offset, 0), 0)) s;
|
|
4806
|
+
RETURN jsonb_build_object('rijen', v_rows, 'totaal', v_total);
|
|
4807
|
+
END $function$
|
|
4808
|
+
;
|
|
4809
|
+
REVOKE ALL ON FUNCTION productie_orders_lijst(text,timestamp with time zone,timestamp with time zone,text,integer,integer) FROM PUBLIC;
|
|
4810
|
+
REVOKE ALL ON FUNCTION productie_orders_lijst(text,timestamp with time zone,timestamp with time zone,text,integer,integer) FROM anon;
|
|
4811
|
+
GRANT EXECUTE ON FUNCTION productie_orders_lijst(text,timestamp with time zone,timestamp with time zone,text,integer,integer) TO authenticated;
|
|
4812
|
+
GRANT EXECUTE ON FUNCTION productie_orders_lijst(text,timestamp with time zone,timestamp with time zone,text,integer,integer) TO service_role;
|
|
4813
|
+
CREATE OR REPLACE FUNCTION public.promote_trade_item_key(p_old text, p_new text)
|
|
4814
|
+
RETURNS void
|
|
4815
|
+
LANGUAGE plpgsql
|
|
4816
|
+
SECURITY DEFINER
|
|
4817
|
+
SET search_path TO 'public'
|
|
4818
|
+
AS $function$
|
|
4819
|
+
DECLARE r RECORD; v_existing_id uuid;
|
|
4820
|
+
BEGIN
|
|
4821
|
+
PERFORM public.voorraad_vereis('ingelogd', 'promote_trade_item_key');
|
|
4822
|
+
IF p_old IS NULL OR p_new IS NULL OR p_old = p_new THEN RETURN; END IF;
|
|
4823
|
+
FOR r IN SELECT * FROM public.trade_item_stock WHERE trade_item_key = p_old FOR UPDATE LOOP
|
|
4824
|
+
SELECT id INTO v_existing_id FROM public.trade_item_stock
|
|
4825
|
+
WHERE connection_id = r.connection_id AND trade_item_key = p_new;
|
|
4826
|
+
IF v_existing_id IS NULL THEN
|
|
4827
|
+
UPDATE public.trade_item_stock SET trade_item_key = p_new, updated_at = now() WHERE id = r.id;
|
|
4828
|
+
ELSE
|
|
4829
|
+
-- Physical/min/incoming represent the same inventory; take the greater value.
|
|
4830
|
+
-- Reservations from different sources are additive.
|
|
5038
4831
|
UPDATE public.trade_item_stock
|
|
5039
4832
|
SET physical_stock = GREATEST(physical_stock, r.physical_stock),
|
|
5040
4833
|
minimum_stock = GREATEST(minimum_stock, r.minimum_stock),
|
|
@@ -5069,6 +4862,7 @@ BEGIN
|
|
|
5069
4862
|
BEGIN PERFORM public.voorraad_ensure_defaults(); EXCEPTION WHEN others THEN NULL; END;
|
|
5070
4863
|
IF current_setting('app.recomputing_reserved', true) = 'on' THEN RETURN; END IF;
|
|
5071
4864
|
PERFORM set_config('app.recomputing_reserved', 'on', true);
|
|
4865
|
+
PERFORM pg_advisory_xact_lock(hashtext('voorraad_res:*')); -- één volledige herberekening tegelijk
|
|
5072
4866
|
|
|
5073
4867
|
DROP TABLE IF EXISTS _reserved_keys;
|
|
5074
4868
|
DROP TABLE IF EXISTS _reserved_demand;
|
|
@@ -5227,7 +5021,7 @@ BEGIN
|
|
|
5227
5021
|
FROM public.trade_item_stock s2
|
|
5228
5022
|
LEFT JOIN _reserved_demand d ON d.trade_item_key = s2.trade_item_key
|
|
5229
5023
|
WHERE s2.id = s.id
|
|
5230
|
-
AND s.reserved_stock IS DISTINCT FROM CEIL(COALESCE(d.qty, 0))::integer;
|
|
5024
|
+
AND s.reserved_stock IS DISTINCT FROM CEIL(COALESCE(d.qty, 0))::integer + public.voorraad_reservering_extra(s.trade_item_key);
|
|
5231
5025
|
|
|
5232
5026
|
IF jsonb_array_length(v_skipped) > 0 THEN
|
|
5233
5027
|
PERFORM public.logistics_trace(jsonb_build_object(
|
|
@@ -5322,16 +5116,17 @@ CREATE OR REPLACE FUNCTION public.recompute_reserved_for_order(p_order_id uuid)
|
|
|
5322
5116
|
SECURITY DEFINER
|
|
5323
5117
|
SET search_path TO 'public'
|
|
5324
5118
|
AS $function$
|
|
5325
|
-
DECLARE k text;
|
|
5119
|
+
DECLARE k text; v_keys text[];
|
|
5326
5120
|
BEGIN
|
|
5327
5121
|
PERFORM public.voorraad_vereis('ingelogd', 'recompute_reserved_for_order');
|
|
5328
|
-
|
|
5329
|
-
SELECT
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5122
|
+
SELECT array_agg(DISTINCT x ORDER BY x) INTO v_keys FROM (
|
|
5123
|
+
SELECT public.voorraad_orderregel_sleutel(oi.product_id::text) AS x
|
|
5124
|
+
FROM logistics_active.order_items oi WHERE oi.order_id = p_order_id AND oi.product_id IS NOT NULL
|
|
5125
|
+
UNION SELECT a.trade_item_key FROM public.voorraad_orderregel_afboeking a WHERE a.order_id = p_order_id
|
|
5126
|
+
) s WHERE x IS NOT NULL;
|
|
5127
|
+
IF v_keys IS NULL THEN RETURN; END IF;
|
|
5128
|
+
PERFORM public.voorraad_lock_sleutels(v_keys);
|
|
5129
|
+
FOREACH k IN ARRAY v_keys LOOP PERFORM public.recompute_reserved_stock(k); END LOOP;
|
|
5335
5130
|
END $function$
|
|
5336
5131
|
;
|
|
5337
5132
|
REVOKE ALL ON FUNCTION recompute_reserved_for_order(uuid) FROM PUBLIC;
|
|
@@ -5357,7 +5152,8 @@ BEGIN
|
|
|
5357
5152
|
IF current_setting('app.recomputing_reserved', true) = 'on' THEN RETURN; END IF;
|
|
5358
5153
|
|
|
5359
5154
|
v_key := public.logistics_reserved_key(p_trade_item_key);
|
|
5360
|
-
|
|
5155
|
+
PERFORM public.voorraad_lock_sleutels(ARRAY[v_key]); -- SUM en UPDATE onder een lock per sleutel
|
|
5156
|
+
IF public.logistics_reserved_fast_skip(p_trade_item_key, v_key) AND public.voorraad_reservering_extra(v_key) = 0 THEN RETURN; END IF;
|
|
5361
5157
|
|
|
5362
5158
|
SELECT array_agg(p.id) INTO v_products
|
|
5363
5159
|
FROM public.products p
|
|
@@ -5435,7 +5231,7 @@ BEGIN
|
|
|
5435
5231
|
change_source = 'RESERVATION_RECOMPUTE',
|
|
5436
5232
|
updated_at = now()
|
|
5437
5233
|
WHERE trade_item_key = v_key
|
|
5438
|
-
AND reserved_stock IS DISTINCT FROM v_sum;
|
|
5234
|
+
AND reserved_stock IS DISTINCT FROM v_sum + public.voorraad_reservering_extra(v_key);
|
|
5439
5235
|
END
|
|
5440
5236
|
$function$
|
|
5441
5237
|
;
|
|
@@ -5654,128 +5450,11 @@ CREATE OR REPLACE FUNCTION public.reverse_production(p_parent_key text, p_quanti
|
|
|
5654
5450
|
LANGUAGE plpgsql
|
|
5655
5451
|
SECURITY DEFINER
|
|
5656
5452
|
SET search_path TO 'public'
|
|
5657
|
-
AS $function$
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
v_scale numeric;
|
|
5663
|
-
v_output_remaining numeric;
|
|
5664
|
-
v_reverse_amount numeric;
|
|
5665
|
-
v_before numeric;
|
|
5666
|
-
v_after numeric;
|
|
5667
|
-
v_connection_id uuid := p_connection_id;
|
|
5668
|
-
v_uid uuid := COALESCE(p_user_id, auth.uid());
|
|
5669
|
-
v_reversed jsonb := '[]'::jsonb;
|
|
5670
|
-
v_batches_processed int := 0;
|
|
5671
|
-
BEGIN
|
|
5672
|
-
PERFORM public.voorraad_vereis('ingelogd', 'reverse_production');
|
|
5673
|
-
IF v_remaining <= 0 OR p_parent_key IS NULL THEN
|
|
5674
|
-
RETURN jsonb_build_object('ok', true, 'reversed', v_reversed);
|
|
5675
|
-
END IF;
|
|
5676
|
-
|
|
5677
|
-
-- Walk production batches most-recent first
|
|
5678
|
-
FOR v_batch IN
|
|
5679
|
-
SELECT
|
|
5680
|
-
out_row.production_batch_id AS batch_id,
|
|
5681
|
-
out_row.qty_delta AS produced_qty,
|
|
5682
|
-
out_row.connection_id AS conn_id,
|
|
5683
|
-
out_row.created_at AS produced_at,
|
|
5684
|
-
COALESCE((
|
|
5685
|
-
SELECT SUM(-rev.qty_delta)
|
|
5686
|
-
FROM stock_mutation_log rev
|
|
5687
|
-
WHERE rev.production_batch_id = out_row.production_batch_id
|
|
5688
|
-
AND rev.parent_trade_item_key = p_parent_key
|
|
5689
|
-
AND rev.mutation_type = 'production_reverse'
|
|
5690
|
-
), 0) AS already_reversed
|
|
5691
|
-
FROM stock_mutation_log out_row
|
|
5692
|
-
WHERE out_row.mutation_type = 'production_output'
|
|
5693
|
-
AND out_row.parent_trade_item_key = p_parent_key
|
|
5694
|
-
AND out_row.production_batch_id IS NOT NULL
|
|
5695
|
-
ORDER BY out_row.created_at DESC
|
|
5696
|
-
LOOP
|
|
5697
|
-
v_output_remaining := v_batch.produced_qty - v_batch.already_reversed;
|
|
5698
|
-
IF v_output_remaining <= 0 THEN CONTINUE; END IF;
|
|
5699
|
-
|
|
5700
|
-
v_reverse_amount := LEAST(v_remaining, v_output_remaining);
|
|
5701
|
-
v_scale := v_reverse_amount / v_batch.produced_qty;
|
|
5702
|
-
v_connection_id := COALESCE(v_connection_id, v_batch.conn_id);
|
|
5703
|
-
|
|
5704
|
-
-- Restore each consumed component pro-rata
|
|
5705
|
-
FOR v_consume IN
|
|
5706
|
-
SELECT trade_item_key, connection_id, -qty_delta AS consumed_qty
|
|
5707
|
-
FROM stock_mutation_log
|
|
5708
|
-
WHERE production_batch_id = v_batch.batch_id
|
|
5709
|
-
AND mutation_type = 'production_consume'
|
|
5710
|
-
AND parent_trade_item_key = p_parent_key
|
|
5711
|
-
LOOP
|
|
5712
|
-
DECLARE
|
|
5713
|
-
v_restore numeric := v_consume.consumed_qty * v_scale;
|
|
5714
|
-
v_prod_id uuid;
|
|
5715
|
-
BEGIN
|
|
5716
|
-
SELECT COALESCE(ts.physical_stock, 0) INTO v_before
|
|
5717
|
-
FROM trade_item_stock ts WHERE ts.trade_item_key = v_consume.trade_item_key;
|
|
5718
|
-
v_before := COALESCE(v_before, 0);
|
|
5719
|
-
v_after := v_before + v_restore;
|
|
5720
|
-
|
|
5721
|
-
PERFORM set_config('app.bom_consume_in_progress', 'on', true);
|
|
5722
|
-
INSERT INTO trade_item_stock (connection_id, trade_item_key, physical_stock, user_id)
|
|
5723
|
-
VALUES (COALESCE(v_consume.connection_id, v_connection_id), v_consume.trade_item_key, v_after::int, v_uid)
|
|
5724
|
-
ON CONFLICT (connection_id, trade_item_key) DO UPDATE
|
|
5725
|
-
SET physical_stock = EXCLUDED.physical_stock,
|
|
5726
|
-
connection_id = COALESCE(trade_item_stock.connection_id, EXCLUDED.connection_id),
|
|
5727
|
-
user_id = COALESCE(trade_item_stock.user_id, EXCLUDED.user_id),
|
|
5728
|
-
updated_at = now();
|
|
5729
|
-
PERFORM set_config('app.bom_consume_in_progress', 'off', true);
|
|
5730
|
-
|
|
5731
|
-
IF v_consume.trade_item_key LIKE 'product:%' THEN
|
|
5732
|
-
BEGIN v_prod_id := substring(v_consume.trade_item_key from 9)::uuid;
|
|
5733
|
-
EXCEPTION WHEN others THEN v_prod_id := NULL; END;
|
|
5734
|
-
ELSE
|
|
5735
|
-
SELECT id INTO v_prod_id FROM products WHERE trade_item_key = v_consume.trade_item_key LIMIT 1;
|
|
5736
|
-
END IF;
|
|
5737
|
-
IF v_prod_id IS NOT NULL THEN
|
|
5738
|
-
UPDATE products SET quantity = v_after::int, updated_at = now() WHERE id = v_prod_id;
|
|
5739
|
-
END IF;
|
|
5740
|
-
|
|
5741
|
-
INSERT INTO stock_mutation_log (
|
|
5742
|
-
connection_id, trade_item_key, mutation_type, qty_delta,
|
|
5743
|
-
physical_before, physical_after, reason, created_by,
|
|
5744
|
-
production_batch_id, parent_trade_item_key
|
|
5745
|
-
) VALUES (
|
|
5746
|
-
COALESCE(v_consume.connection_id, v_connection_id), v_consume.trade_item_key,
|
|
5747
|
-
'production_reverse', v_restore, v_before, v_after,
|
|
5748
|
-
COALESCE(p_reason, 'Terugboeking productie ' || p_parent_key || ' (x' || v_reverse_amount || ')'),
|
|
5749
|
-
v_uid, v_batch.batch_id, p_parent_key
|
|
5750
|
-
);
|
|
5751
|
-
|
|
5752
|
-
v_reversed := v_reversed || jsonb_build_object(
|
|
5753
|
-
'trade_item_key', v_consume.trade_item_key, 'restored', v_restore, 'new_stock', v_after,
|
|
5754
|
-
'batch_id', v_batch.batch_id);
|
|
5755
|
-
END;
|
|
5756
|
-
END LOOP;
|
|
5757
|
-
|
|
5758
|
-
-- Log a reverse entry against the parent output as well, for audit
|
|
5759
|
-
INSERT INTO stock_mutation_log (
|
|
5760
|
-
connection_id, trade_item_key, mutation_type, qty_delta,
|
|
5761
|
-
physical_before, physical_after, reason, created_by,
|
|
5762
|
-
production_batch_id, parent_trade_item_key
|
|
5763
|
-
) VALUES (
|
|
5764
|
-
v_connection_id, p_parent_key, 'production_reverse', -v_reverse_amount,
|
|
5765
|
-
NULL, NULL,
|
|
5766
|
-
COALESCE(p_reason, 'Terugdraaien productie (' || v_reverse_amount || ' stuks)'),
|
|
5767
|
-
v_uid, v_batch.batch_id, p_parent_key
|
|
5768
|
-
);
|
|
5769
|
-
|
|
5770
|
-
v_remaining := v_remaining - v_reverse_amount;
|
|
5771
|
-
v_batches_processed := v_batches_processed + 1;
|
|
5772
|
-
EXIT WHEN v_remaining <= 0;
|
|
5773
|
-
END LOOP;
|
|
5774
|
-
|
|
5775
|
-
RETURN jsonb_build_object('ok', true, 'reversed', v_reversed,
|
|
5776
|
-
'batches_reversed', v_batches_processed, 'unreversed_qty', v_remaining);
|
|
5777
|
-
END;
|
|
5778
|
-
$function$
|
|
5453
|
+
AS $function$
|
|
5454
|
+
BEGIN
|
|
5455
|
+
PERFORM public.voorraad_vereis('ingelogd', 'reverse_production');
|
|
5456
|
+
RAISE EXCEPTION 'Gebruik Productieorder maken (of terugdraaien bij de productieorder).' USING ERRCODE = 'P0001';
|
|
5457
|
+
END $function$
|
|
5779
5458
|
;
|
|
5780
5459
|
REVOKE ALL ON FUNCTION reverse_production(text,numeric,uuid,uuid,text) FROM PUBLIC;
|
|
5781
5460
|
REVOKE ALL ON FUNCTION reverse_production(text,numeric,uuid,uuid,text) FROM anon;
|
|
@@ -6922,17 +6601,8 @@ CREATE OR REPLACE FUNCTION public.trg_orders_cancel_release_fn()
|
|
|
6922
6601
|
SECURITY DEFINER
|
|
6923
6602
|
SET search_path TO 'public'
|
|
6924
6603
|
AS $function$
|
|
6925
|
-
DECLARE
|
|
6926
|
-
oi RECORD;
|
|
6927
|
-
v_key text;
|
|
6928
6604
|
BEGIN
|
|
6929
|
-
|
|
6930
|
-
AND OLD.status IS DISTINCT FROM NEW.status THEN
|
|
6931
|
-
FOR oi IN SELECT id, product_id, quantity FROM logistics_active.order_items WHERE order_id = NEW.id LOOP
|
|
6932
|
-
SELECT trade_item_key INTO v_key FROM public.products WHERE id = oi.product_id;
|
|
6933
|
-
PERFORM public.apply_stock_reservation(v_key, -COALESCE(oi.quantity,0), NEW.id, oi.id, COALESCE(NEW.order_source,'manual'), 'order cancelled');
|
|
6934
|
-
END LOOP;
|
|
6935
|
-
END IF;
|
|
6605
|
+
-- Bewust leeg: vrijgeven gebeurt alleen door herberekenen (trg_orders_recompute_reserved), nooit door aftrekken.
|
|
6936
6606
|
RETURN NEW;
|
|
6937
6607
|
END $function$
|
|
6938
6608
|
;
|
|
@@ -7059,7 +6729,8 @@ CREATE OR REPLACE FUNCTION public.trg_orders_recompute_reserved_fn()
|
|
|
7059
6729
|
SET search_path TO 'public'
|
|
7060
6730
|
AS $function$
|
|
7061
6731
|
BEGIN
|
|
7062
|
-
IF TG_OP = 'UPDATE' AND NEW.status IS DISTINCT FROM OLD.status
|
|
6732
|
+
IF TG_OP = 'UPDATE' AND (NEW.status IS DISTINCT FROM OLD.status OR NEW.deleted_at IS DISTINCT FROM OLD.deleted_at
|
|
6733
|
+
OR NEW.cancelled_at IS DISTINCT FROM OLD.cancelled_at) THEN
|
|
7063
6734
|
PERFORM public.recompute_reserved_for_order(NEW.id);
|
|
7064
6735
|
ELSIF TG_OP = 'DELETE' THEN
|
|
7065
6736
|
PERFORM public.recompute_reserved_for_order(OLD.id);
|
|
@@ -7925,6 +7596,67 @@ REVOKE ALL ON FUNCTION voorraad_afboeken(uuid,text,numeric,text,text) FROM PUBLI
|
|
|
7925
7596
|
REVOKE ALL ON FUNCTION voorraad_afboeken(uuid,text,numeric,text,text) FROM anon;
|
|
7926
7597
|
GRANT EXECUTE ON FUNCTION voorraad_afboeken(uuid,text,numeric,text,text) TO authenticated;
|
|
7927
7598
|
GRANT EXECUTE ON FUNCTION voorraad_afboeken(uuid,text,numeric,text,text) TO service_role;
|
|
7599
|
+
CREATE OR REPLACE FUNCTION public.voorraad_afboeken_kern(p_trade_item_key text, p_qty numeric, p_order_id uuid, p_order_item_id uuid, p_source text, p_reason text)
|
|
7600
|
+
RETURNS void
|
|
7601
|
+
LANGUAGE plpgsql
|
|
7602
|
+
SECURITY DEFINER
|
|
7603
|
+
SET search_path TO 'public'
|
|
7604
|
+
AS $function$
|
|
7605
|
+
DECLARE
|
|
7606
|
+
v_norm text := public.normalize_order_source(p_source);
|
|
7607
|
+
v_src text := CASE WHEN v_norm = 'FO' THEN 'FLORIDAY_ORDER' ELSE 'ORDER_DELIVERY' END;
|
|
7608
|
+
v_ctx record; v_key text; r public.trade_item_stock%ROWTYPE; v_after numeric; v_res_after numeric;
|
|
7609
|
+
BEGIN
|
|
7610
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_afboeken_kern');
|
|
7611
|
+
IF p_trade_item_key IS NULL OR COALESCE(p_qty,0) <= 0 THEN RETURN; END IF;
|
|
7612
|
+
SELECT * INTO v_ctx FROM public.get_stock_context(true);
|
|
7613
|
+
v_key := public.ensure_trade_item_stock_row_key(p_trade_item_key);
|
|
7614
|
+
IF v_ctx.connection_id IS NULL OR v_key IS NULL THEN
|
|
7615
|
+
INSERT INTO public.stock_mutation_log(trade_item_key, order_id, order_item_id, order_source, mutation_type, qty_delta, reason, created_by)
|
|
7616
|
+
VALUES (p_trade_item_key, p_order_id, p_order_item_id, v_norm, 'consumption_skipped', p_qty,
|
|
7617
|
+
CASE WHEN v_ctx.connection_id IS NULL THEN 'geen actieve koppeling' ELSE 'geen voorraadrij' END || ' — ' || COALESCE(p_reason,''), auth.uid());
|
|
7618
|
+
RETURN;
|
|
7619
|
+
END IF;
|
|
7620
|
+
SELECT * INTO r FROM public.trade_item_stock WHERE connection_id = v_ctx.connection_id AND trade_item_key = v_key FOR UPDATE;
|
|
7621
|
+
IF r.id IS NULL THEN
|
|
7622
|
+
INSERT INTO public.stock_mutation_log(trade_item_key, order_id, order_item_id, order_source, mutation_type, qty_delta, reason, created_by)
|
|
7623
|
+
VALUES (v_key, p_order_id, p_order_item_id, v_norm, 'consumption_skipped', p_qty, 'geen voorraadrij op de actieve koppeling — ' || COALESCE(p_reason,''), auth.uid());
|
|
7624
|
+
RETURN;
|
|
7625
|
+
END IF;
|
|
7626
|
+
v_after := COALESCE(r.physical_stock,0) - p_qty;
|
|
7627
|
+
v_res_after := GREATEST(COALESCE(r.reserved_stock,0) - p_qty, 0);
|
|
7628
|
+
|
|
7629
|
+
PERFORM set_config('stock.change_source', v_src, true);
|
|
7630
|
+
PERFORM set_config('stock.log_handled',
|
|
7631
|
+
COALESCE(NULLIF(current_setting('stock.log_handled', true),''), ';') || r.connection_id || '|' || v_key || '|' || v_after || '|' || v_res_after || ';', true);
|
|
7632
|
+
|
|
7633
|
+
UPDATE public.trade_item_stock
|
|
7634
|
+
SET physical_stock = v_after, reserved_stock = v_res_after, change_source = v_src, updated_at = now()
|
|
7635
|
+
WHERE id = r.id;
|
|
7636
|
+
|
|
7637
|
+
INSERT INTO public.stock_mutation_log(trade_item_key, connection_id, order_id, order_item_id, order_source,
|
|
7638
|
+
mutation_type, qty_delta, physical_before, physical_after, reserved_before, reserved_after, reason, created_by)
|
|
7639
|
+
VALUES (v_key, r.connection_id, p_order_id, p_order_item_id, v_norm, 'consumption', -p_qty,
|
|
7640
|
+
COALESCE(r.physical_stock,0), v_after, COALESCE(r.reserved_stock,0), v_res_after,
|
|
7641
|
+
COALESCE(p_reason,'afgeboekt') || ' (' || v_src || ')', auth.uid());
|
|
7642
|
+
|
|
7643
|
+
IF v_after < 0 THEN
|
|
7644
|
+
BEGIN
|
|
7645
|
+
INSERT INTO public.stock_integrity_alerts(tx_id, alert_kind, item_count, items)
|
|
7646
|
+
VALUES (-txid_current(), 'NEGATIVE_STOCK', 1, jsonb_build_array(jsonb_build_object(
|
|
7647
|
+
'trade_item_key', v_key, 'connection_id', r.connection_id, 'physical_before', r.physical_stock,
|
|
7648
|
+
'physical_after', v_after, 'order_id', p_order_id, 'order_item_id', p_order_item_id, 'change_source', v_src)))
|
|
7649
|
+
ON CONFLICT (tx_id) DO UPDATE SET item_count = public.stock_integrity_alerts.item_count + 1,
|
|
7650
|
+
items = public.stock_integrity_alerts.items || EXCLUDED.items, updated_at = now();
|
|
7651
|
+
EXCEPTION WHEN others THEN RAISE WARNING '[negative-stock-alert] %', SQLERRM;
|
|
7652
|
+
END;
|
|
7653
|
+
END IF;
|
|
7654
|
+
END $function$
|
|
7655
|
+
;
|
|
7656
|
+
REVOKE ALL ON FUNCTION voorraad_afboeken_kern(text,numeric,uuid,uuid,text,text) FROM PUBLIC;
|
|
7657
|
+
REVOKE ALL ON FUNCTION voorraad_afboeken_kern(text,numeric,uuid,uuid,text,text) FROM anon;
|
|
7658
|
+
GRANT EXECUTE ON FUNCTION voorraad_afboeken_kern(text,numeric,uuid,uuid,text,text) TO authenticated;
|
|
7659
|
+
GRANT EXECUTE ON FUNCTION voorraad_afboeken_kern(text,numeric,uuid,uuid,text,text) TO service_role;
|
|
7928
7660
|
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)
|
|
7929
7661
|
RETURNS void
|
|
7930
7662
|
LANGUAGE plpgsql
|
|
@@ -9395,7 +9127,7 @@ CREATE OR REPLACE FUNCTION public.voorraad_defaults_versie()
|
|
|
9395
9127
|
LANGUAGE sql
|
|
9396
9128
|
IMMUTABLE
|
|
9397
9129
|
SET search_path TO 'public'
|
|
9398
|
-
AS $function$ SELECT
|
|
9130
|
+
AS $function$ SELECT 5 $function$
|
|
9399
9131
|
;
|
|
9400
9132
|
REVOKE ALL ON FUNCTION voorraad_defaults_versie() FROM PUBLIC;
|
|
9401
9133
|
REVOKE ALL ON FUNCTION voorraad_defaults_versie() FROM anon;
|
|
@@ -9469,6 +9201,36 @@ REVOKE ALL ON FUNCTION voorraad_eigen_velden_opslaan(uuid,jsonb,jsonb) FROM PUBL
|
|
|
9469
9201
|
REVOKE ALL ON FUNCTION voorraad_eigen_velden_opslaan(uuid,jsonb,jsonb) FROM anon;
|
|
9470
9202
|
GRANT EXECUTE ON FUNCTION voorraad_eigen_velden_opslaan(uuid,jsonb,jsonb) TO authenticated;
|
|
9471
9203
|
GRANT EXECUTE ON FUNCTION voorraad_eigen_velden_opslaan(uuid,jsonb,jsonb) TO service_role;
|
|
9204
|
+
CREATE OR REPLACE FUNCTION public.voorraad_eigen_verkoop_mutatie(p_product_id uuid, p_aantal_verkocht numeric, p_referentie text)
|
|
9205
|
+
RETURNS jsonb
|
|
9206
|
+
LANGUAGE plpgsql
|
|
9207
|
+
SECURITY DEFINER
|
|
9208
|
+
SET search_path TO 'public'
|
|
9209
|
+
AS $function$
|
|
9210
|
+
DECLARE v_pid uuid; v_key text; v_delta integer;
|
|
9211
|
+
BEGIN
|
|
9212
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_eigen_verkoop_mutatie');
|
|
9213
|
+
IF p_product_id IS NULL OR NULLIF(btrim(COALESCE(p_referentie, '')), '') IS NULL THEN
|
|
9214
|
+
RAISE EXCEPTION 'Geef een artikel en een referentie op.' USING ERRCODE = 'P0001';
|
|
9215
|
+
END IF;
|
|
9216
|
+
IF EXISTS (SELECT 1 FROM public.orders o WHERE o.order_number::text = btrim(p_referentie)) THEN
|
|
9217
|
+
RETURN jsonb_build_object('status', 'via_order', 'tekst', 'Deze verkoop loopt via de ERP-order ' || btrim(p_referentie) || '.');
|
|
9218
|
+
END IF;
|
|
9219
|
+
BEGIN SELECT c.product_id, c.trade_item_key INTO v_pid, v_key FROM public.voorraad_canoniek_artikel(p_product_id::text) c LIMIT 1;
|
|
9220
|
+
EXCEPTION WHEN others THEN v_pid := NULL; END;
|
|
9221
|
+
v_pid := COALESCE(v_pid, p_product_id);
|
|
9222
|
+
IF NOT public.voorraad_floriday_leads_key(COALESCE(v_key, v_pid::text)) THEN
|
|
9223
|
+
RETURN jsonb_build_object('status', 'niet_floriday_leidend');
|
|
9224
|
+
END IF;
|
|
9225
|
+
v_delta := public.voorraad_floriday_mutatie_naar(v_pid, -CEIL(GREATEST(COALESCE(p_aantal_verkocht, 0), 0))::integer, NULL, NULL, btrim(p_referentie), 'verkoop zonder order');
|
|
9226
|
+
IF v_delta <> 0 THEN PERFORM public.voorraad_floriday_mutaties_klaarzetten(v_pid); END IF;
|
|
9227
|
+
RETURN jsonb_build_object('status', CASE WHEN v_delta = 0 THEN 'ongewijzigd' ELSE 'vastgelegd' END, 'verschil', v_delta);
|
|
9228
|
+
END $function$
|
|
9229
|
+
;
|
|
9230
|
+
REVOKE ALL ON FUNCTION voorraad_eigen_verkoop_mutatie(uuid,numeric,text) FROM PUBLIC;
|
|
9231
|
+
REVOKE ALL ON FUNCTION voorraad_eigen_verkoop_mutatie(uuid,numeric,text) FROM anon;
|
|
9232
|
+
GRANT EXECUTE ON FUNCTION voorraad_eigen_verkoop_mutatie(uuid,numeric,text) TO authenticated;
|
|
9233
|
+
GRANT EXECUTE ON FUNCTION voorraad_eigen_verkoop_mutatie(uuid,numeric,text) TO service_role;
|
|
9472
9234
|
CREATE OR REPLACE FUNCTION public.voorraad_ensure_defaults()
|
|
9473
9235
|
RETURNS jsonb
|
|
9474
9236
|
LANGUAGE plpgsql
|
|
@@ -9494,7 +9256,7 @@ BEGIN
|
|
|
9494
9256
|
AND EXISTS (SELECT 1 FROM public.voorraad_load_carrier_types)
|
|
9495
9257
|
AND EXISTS (SELECT 1 FROM public.voorraad_instellingen WHERE id)
|
|
9496
9258
|
AND NOT EXISTS (SELECT 1 FROM public.fust_types WHERE saldo_bijhouden IS NULL)
|
|
9497
|
-
AND (SELECT count(*) FROM public.module_runtime_config WHERE key LIKE 'voorraad_hook_enabled.%') >=
|
|
9259
|
+
AND (SELECT count(*) FROM public.module_runtime_config WHERE key LIKE 'voorraad_hook_enabled.%') >= 8
|
|
9498
9260
|
AND v_job_ok THEN
|
|
9499
9261
|
RETURN jsonb_build_object('ok', true, 'versie', v_versie, 'overgeslagen', true);
|
|
9500
9262
|
END IF;
|
|
@@ -9536,7 +9298,7 @@ BEGIN
|
|
|
9536
9298
|
('voorraad_hook_enabled.logistics_tasks', 'standaard'),
|
|
9537
9299
|
('voorraad_hook_enabled.stock_reconcile', 'false'),
|
|
9538
9300
|
('voorraad_hook_enabled.continuous_stock', 'false'),
|
|
9539
|
-
('voorraad_hook_enabled.continuous_stock_pull', 'false')
|
|
9301
|
+
('voorraad_hook_enabled.floriday_mutaties', 'true'), ('voorraad_hook_enabled.continuous_stock_pull', 'false')
|
|
9540
9302
|
ON CONFLICT (key) DO NOTHING;
|
|
9541
9303
|
GET DIAGNOSTICS n_sch = ROW_COUNT;
|
|
9542
9304
|
PERFORM set_config('voorraad.schakelaar_defaults', '', true);
|
|
@@ -9857,6 +9619,48 @@ REVOKE ALL ON FUNCTION voorraad_floriday_dubbele_ids() FROM PUBLIC;
|
|
|
9857
9619
|
REVOKE ALL ON FUNCTION voorraad_floriday_dubbele_ids() FROM anon;
|
|
9858
9620
|
GRANT EXECUTE ON FUNCTION voorraad_floriday_dubbele_ids() TO authenticated;
|
|
9859
9621
|
GRANT EXECUTE ON FUNCTION voorraad_floriday_dubbele_ids() TO service_role;
|
|
9622
|
+
CREATE OR REPLACE FUNCTION public.voorraad_floriday_inhalen_kandidaten()
|
|
9623
|
+
RETURNS TABLE(order_id uuid, order_nummer text, order_item_id uuid, product_id uuid, aantal integer, aangemaakt timestamp with time zone)
|
|
9624
|
+
LANGUAGE plpgsql
|
|
9625
|
+
STABLE SECURITY DEFINER
|
|
9626
|
+
SET search_path TO 'public'
|
|
9627
|
+
AS $function$
|
|
9628
|
+
BEGIN
|
|
9629
|
+
PERFORM public.voorraad_vereis('server', 'voorraad_floriday_inhalen_kandidaten');
|
|
9630
|
+
IF NOT EXISTS (SELECT 1 FROM public.floriday_inventory_settings WHERE erp_leading = false) THEN RETURN; END IF;
|
|
9631
|
+
RETURN QUERY
|
|
9632
|
+
SELECT o.id, COALESCE(o.order_number::text, o.id::text), oi.id, oi.product_id, CEIL(oi.quantity)::integer, o.created_at
|
|
9633
|
+
FROM public.orders o JOIN public.order_items oi ON oi.order_id = o.id
|
|
9634
|
+
WHERE public.normalize_order_source(o.order_source) <> 'FO'
|
|
9635
|
+
AND oi.quarantined_at IS NULL
|
|
9636
|
+
AND NOT public.voorraad_order_geannuleerd(o.status, o.cancelled_at, o.deleted_at)
|
|
9637
|
+
AND lower(COALESCE(o.status, '')) NOT IN ('verzonden','shipped','geleverd','delivered','afgehandeld','completed')
|
|
9638
|
+
AND NOT EXISTS (SELECT 1 FROM public.voorraad_order_terugdraaiing t WHERE t.order_id = o.id)
|
|
9639
|
+
AND COALESCE(oi.quantity, 0) > 0 AND oi.product_id IS NOT NULL
|
|
9640
|
+
AND NOT EXISTS (SELECT 1 FROM public.stock_mutation_log l WHERE l.order_item_id = oi.id AND l.mutation_type = 'consumption_done')
|
|
9641
|
+
AND NOT EXISTS (SELECT 1 FROM public.voorraad_floriday_mutaties m WHERE m.order_item_id = oi.id)
|
|
9642
|
+
AND public.voorraad_floriday_leads_key(oi.product_id::text);
|
|
9643
|
+
END $function$
|
|
9644
|
+
;
|
|
9645
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_inhalen_kandidaten() FROM PUBLIC;
|
|
9646
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_inhalen_kandidaten() FROM anon;
|
|
9647
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_inhalen_kandidaten() TO service_role;
|
|
9648
|
+
CREATE OR REPLACE FUNCTION public.voorraad_floriday_inhalen_open()
|
|
9649
|
+
RETURNS integer
|
|
9650
|
+
LANGUAGE plpgsql
|
|
9651
|
+
STABLE SECURITY DEFINER
|
|
9652
|
+
SET search_path TO 'public'
|
|
9653
|
+
AS $function$
|
|
9654
|
+
DECLARE n integer;
|
|
9655
|
+
BEGIN
|
|
9656
|
+
PERFORM public.voorraad_vereis('server', 'voorraad_floriday_inhalen_open');
|
|
9657
|
+
SELECT count(*) INTO n FROM public.voorraad_floriday_inhalen_kandidaten() k WHERE k.aangemaakt < now() - interval '5 minutes';
|
|
9658
|
+
RETURN n;
|
|
9659
|
+
END $function$
|
|
9660
|
+
;
|
|
9661
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_inhalen_open() FROM PUBLIC;
|
|
9662
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_inhalen_open() FROM anon;
|
|
9663
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_inhalen_open() TO service_role;
|
|
9860
9664
|
CREATE OR REPLACE FUNCTION public.voorraad_floriday_klaarzetten_toegestaan()
|
|
9861
9665
|
RETURNS boolean
|
|
9862
9666
|
LANGUAGE plpgsql
|
|
@@ -9896,6 +9700,324 @@ $function$
|
|
|
9896
9700
|
REVOKE ALL ON FUNCTION voorraad_floriday_leads_key(text) FROM PUBLIC;
|
|
9897
9701
|
REVOKE ALL ON FUNCTION voorraad_floriday_leads_key(text) FROM anon;
|
|
9898
9702
|
GRANT EXECUTE ON FUNCTION voorraad_floriday_leads_key(text) TO service_role;
|
|
9703
|
+
CREATE OR REPLACE FUNCTION public.voorraad_floriday_mutatie_doel(p_product_id uuid)
|
|
9704
|
+
RETURNS integer
|
|
9705
|
+
LANGUAGE plpgsql
|
|
9706
|
+
STABLE SECURITY DEFINER
|
|
9707
|
+
SET search_path TO 'public'
|
|
9708
|
+
AS $function$
|
|
9709
|
+
DECLARE v_f numeric; v_t timestamptz; v_u numeric;
|
|
9710
|
+
BEGIN
|
|
9711
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_floriday_mutatie_doel');
|
|
9712
|
+
SELECT st.number_of_pieces, st.opgehaald_at INTO v_f, v_t
|
|
9713
|
+
FROM public.voorraad_floriday_stand st
|
|
9714
|
+
JOIN public.floriday_inventory_settings s ON s.connection_id = st.connection_id AND s.floriday_trade_item_id::text = st.trade_item_id::text
|
|
9715
|
+
WHERE s.product_id = p_product_id AND s.erp_leading = false AND st.opgehaald_at >= now() - interval '2 minutes'
|
|
9716
|
+
ORDER BY st.opgehaald_at DESC LIMIT 1;
|
|
9717
|
+
IF v_t IS NULL OR NOT public.voorraad_floriday_orders_vers() THEN RETURN NULL; END IF;
|
|
9718
|
+
SELECT COALESCE(SUM(m.delta), 0) INTO v_u FROM public.voorraad_floriday_mutaties m
|
|
9719
|
+
WHERE m.product_id = p_product_id
|
|
9720
|
+
AND (m.status IN ('open','in_wachtrij','mislukt') OR (m.status = 'verzonden' AND m.verzonden_at >= v_t));
|
|
9721
|
+
RETURN GREATEST(v_f + v_u, 0)::integer;
|
|
9722
|
+
END $function$
|
|
9723
|
+
;
|
|
9724
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_mutatie_doel(uuid) FROM PUBLIC;
|
|
9725
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_mutatie_doel(uuid) FROM anon;
|
|
9726
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_mutatie_doel(uuid) TO authenticated;
|
|
9727
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_mutatie_doel(uuid) TO service_role;
|
|
9728
|
+
CREATE OR REPLACE FUNCTION public.voorraad_floriday_mutatie_naar(p_product_id uuid, p_doel integer, p_order_id uuid, p_order_item_id uuid, p_referentie text, p_bron text)
|
|
9729
|
+
RETURNS integer
|
|
9730
|
+
LANGUAGE plpgsql
|
|
9731
|
+
SECURITY DEFINER
|
|
9732
|
+
SET search_path TO 'public'
|
|
9733
|
+
AS $function$
|
|
9734
|
+
DECLARE v_huidig integer; s record;
|
|
9735
|
+
BEGIN
|
|
9736
|
+
PERFORM public.voorraad_vereis('server', 'voorraad_floriday_mutatie_naar');
|
|
9737
|
+
PERFORM pg_advisory_xact_lock(hashtext('voorraad_fm:' || p_product_id::text));
|
|
9738
|
+
SELECT COALESCE(SUM(delta), 0) INTO v_huidig FROM public.voorraad_floriday_mutaties
|
|
9739
|
+
WHERE product_id = p_product_id
|
|
9740
|
+
AND ((p_order_item_id IS NOT NULL AND order_item_id = p_order_item_id)
|
|
9741
|
+
OR (p_order_item_id IS NULL AND order_item_id IS NULL AND referentie = p_referentie));
|
|
9742
|
+
IF v_huidig = p_doel THEN RETURN 0; END IF;
|
|
9743
|
+
SELECT fis.connection_id, fis.floriday_trade_item_id INTO s FROM public.floriday_inventory_settings fis
|
|
9744
|
+
WHERE fis.product_id = p_product_id AND fis.erp_leading = false LIMIT 1;
|
|
9745
|
+
INSERT INTO public.voorraad_floriday_mutaties(connection_id, product_id, trade_item_id, order_id, order_item_id, referentie, delta, bron)
|
|
9746
|
+
VALUES (s.connection_id, p_product_id, NULLIF(s.floriday_trade_item_id::text, '')::uuid, p_order_id, p_order_item_id, p_referentie, p_doel - v_huidig, p_bron);
|
|
9747
|
+
RETURN p_doel - v_huidig;
|
|
9748
|
+
END $function$
|
|
9749
|
+
;
|
|
9750
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_mutatie_naar(uuid,integer,uuid,uuid,text,text) FROM PUBLIC;
|
|
9751
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_mutatie_naar(uuid,integer,uuid,uuid,text,text) FROM anon;
|
|
9752
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_mutatie_naar(uuid,integer,uuid,uuid,text,text) TO authenticated;
|
|
9753
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_mutatie_naar(uuid,integer,uuid,uuid,text,text) TO service_role;
|
|
9754
|
+
CREATE OR REPLACE FUNCTION public.voorraad_floriday_mutaties_inhalen(p_uitvoeren boolean DEFAULT false)
|
|
9755
|
+
RETURNS jsonb
|
|
9756
|
+
LANGUAGE plpgsql
|
|
9757
|
+
SECURITY DEFINER
|
|
9758
|
+
SET search_path TO 'public'
|
|
9759
|
+
AS $function$
|
|
9760
|
+
DECLARE v_orders jsonb; v_art jsonb; r record; n_orders integer := 0; n_mut integer := 0; v_fouten jsonb := '[]'::jsonb;
|
|
9761
|
+
BEGIN
|
|
9762
|
+
PERFORM public.voorraad_vereis('server', 'voorraad_floriday_mutaties_inhalen');
|
|
9763
|
+
SELECT COALESCE(jsonb_agg(jsonb_build_object('order', x.order_nummer, 'order_id', x.order_id, 'regels', x.regels) ORDER BY x.order_nummer), '[]'::jsonb)
|
|
9764
|
+
INTO v_orders FROM (
|
|
9765
|
+
SELECT k.order_id, k.order_nummer, jsonb_agg(jsonb_build_object('order_item_id', k.order_item_id, 'product_id', k.product_id, 'aantal', k.aantal)) regels
|
|
9766
|
+
FROM public.voorraad_floriday_inhalen_kandidaten() k GROUP BY 1, 2) x;
|
|
9767
|
+
SELECT COALESCE(jsonb_agg(jsonb_build_object('product_id', y.product_id, 'artikel', p.product, 'artikelcode', p.article_number,
|
|
9768
|
+
'verschil', -y.som, 'orders', y.n) ORDER BY p.article_number), '[]'::jsonb)
|
|
9769
|
+
INTO v_art FROM (SELECT k.product_id, SUM(k.aantal) som, COUNT(DISTINCT k.order_id) n FROM public.voorraad_floriday_inhalen_kandidaten() k GROUP BY 1) y
|
|
9770
|
+
LEFT JOIN public.products p ON p.id = y.product_id;
|
|
9771
|
+
IF NOT p_uitvoeren THEN
|
|
9772
|
+
RETURN jsonb_build_object('uitgevoerd', false, 'orders', v_orders, 'per_artikel', v_art, 'aantal_orders', jsonb_array_length(v_orders));
|
|
9773
|
+
END IF;
|
|
9774
|
+
FOR r IN SELECT DISTINCT k.order_id FROM public.voorraad_floriday_inhalen_kandidaten() k ORDER BY 1 LOOP
|
|
9775
|
+
BEGIN
|
|
9776
|
+
n_mut := n_mut + public.voorraad_floriday_mutaties_order(r.order_id);
|
|
9777
|
+
n_orders := n_orders + 1;
|
|
9778
|
+
EXCEPTION WHEN others THEN
|
|
9779
|
+
RAISE WARNING 'voorraad_floriday_mutaties_inhalen: order % mislukt: %', r.order_id, SQLERRM;
|
|
9780
|
+
v_fouten := v_fouten || jsonb_build_object('order_id', r.order_id, 'fout', left(SQLERRM, 300));
|
|
9781
|
+
END;
|
|
9782
|
+
END LOOP;
|
|
9783
|
+
IF n_orders > 0 OR jsonb_array_length(v_fouten) > 0 THEN
|
|
9784
|
+
INSERT INTO public.voorraad_correcties(correctie, uitgevoerd_door, proef, aantallen, hash_ok)
|
|
9785
|
+
VALUES ('floriday_mutaties_inhalen', 'minuutronde', false,
|
|
9786
|
+
jsonb_build_object('orders', n_orders, 'mutaties', n_mut, 'per_artikel', v_art, 'fouten', v_fouten), true);
|
|
9787
|
+
END IF;
|
|
9788
|
+
RETURN jsonb_build_object('uitgevoerd', true, 'orders', n_orders, 'mutaties', n_mut, 'per_artikel', v_art, 'fouten', v_fouten);
|
|
9789
|
+
END $function$
|
|
9790
|
+
;
|
|
9791
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_mutaties_inhalen(boolean) FROM PUBLIC;
|
|
9792
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_mutaties_inhalen(boolean) FROM anon;
|
|
9793
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_mutaties_inhalen(boolean) TO service_role;
|
|
9794
|
+
CREATE OR REPLACE FUNCTION public.voorraad_floriday_mutaties_klaarzetten(p_product_id uuid)
|
|
9795
|
+
RETURNS jsonb
|
|
9796
|
+
LANGUAGE plpgsql
|
|
9797
|
+
SECURITY DEFINER
|
|
9798
|
+
SET search_path TO 'public'
|
|
9799
|
+
AS $function$
|
|
9800
|
+
DECLARE s record; v_doel integer; v_q uuid; v_fout text;
|
|
9801
|
+
BEGIN
|
|
9802
|
+
PERFORM public.voorraad_vereis('server', 'voorraad_floriday_mutaties_klaarzetten');
|
|
9803
|
+
PERFORM pg_advisory_xact_lock(hashtext('voorraad_fm:' || p_product_id::text));
|
|
9804
|
+
IF NOT EXISTS (SELECT 1 FROM public.voorraad_floriday_mutaties m WHERE m.product_id = p_product_id
|
|
9805
|
+
AND m.status IN ('open','mislukt') AND m.volgende_poging_at <= now() AND m.pogingen < 10) THEN
|
|
9806
|
+
RETURN jsonb_build_object('status', 'niets');
|
|
9807
|
+
END IF;
|
|
9808
|
+
SELECT fis.* INTO s FROM public.floriday_inventory_settings fis
|
|
9809
|
+
WHERE fis.product_id = p_product_id AND fis.erp_leading = false
|
|
9810
|
+
AND fis.connection_id = COALESCE((SELECT c.connection_id FROM public.get_active_floriday_context() c), fis.connection_id)
|
|
9811
|
+
LIMIT 1;
|
|
9812
|
+
IF NOT FOUND THEN
|
|
9813
|
+
UPDATE public.voorraad_floriday_mutaties SET status = 'bevestigd', bevestigd_at = now(),
|
|
9814
|
+
laatste_fout = 'Floriday is niet meer leidend; het ERP stuurt nu de hele voorraad'
|
|
9815
|
+
WHERE product_id = p_product_id AND status IN ('open','mislukt','in_wachtrij');
|
|
9816
|
+
RETURN jsonb_build_object('status', 'niet_meer_floriday_leidend');
|
|
9817
|
+
END IF;
|
|
9818
|
+
IF NOT public.voorraad_floriday_klaarzetten_toegestaan() THEN RETURN jsonb_build_object('status', 'schrijfstop'); END IF;
|
|
9819
|
+
v_doel := public.voorraad_floriday_mutatie_doel(p_product_id);
|
|
9820
|
+
IF v_doel IS NULL THEN RETURN jsonb_build_object('status', 'wacht_op_ophaalronde'); END IF;
|
|
9821
|
+
BEGIN
|
|
9822
|
+
INSERT INTO public.floriday_continuous_stock_queue(user_id, connection_id, trade_item_id, product_id, number_of_pieces,
|
|
9823
|
+
desired_available, status, next_attempt_at, voorraad_mutatie)
|
|
9824
|
+
VALUES (s.user_id, s.connection_id, s.floriday_trade_item_id::uuid, p_product_id, v_doel, v_doel > 0, 'pending', now(), true)
|
|
9825
|
+
RETURNING id INTO v_q;
|
|
9826
|
+
EXCEPTION WHEN others THEN v_fout := SQLERRM;
|
|
9827
|
+
END;
|
|
9828
|
+
IF v_q IS NULL THEN
|
|
9829
|
+
UPDATE public.voorraad_floriday_mutaties
|
|
9830
|
+
SET status = 'mislukt', pogingen = pogingen + 1, laatste_fout = left(COALESCE(v_fout, 'Niet klaargezet door de wachtrijbewaking'), 300),
|
|
9831
|
+
volgende_poging_at = now() + make_interval(mins => LEAST(power(2, pogingen)::int, 60))
|
|
9832
|
+
WHERE product_id = p_product_id AND status IN ('open','mislukt');
|
|
9833
|
+
RETURN jsonb_build_object('status', 'mislukt', 'fout', v_fout);
|
|
9834
|
+
END IF;
|
|
9835
|
+
UPDATE public.voorraad_floriday_mutaties SET status = 'in_wachtrij', queue_id = v_q, laatste_fout = NULL
|
|
9836
|
+
WHERE product_id = p_product_id AND status IN ('open','mislukt','in_wachtrij');
|
|
9837
|
+
RETURN jsonb_build_object('status', 'klaargezet', 'queue_id', v_q, 'aantal', v_doel);
|
|
9838
|
+
END $function$
|
|
9839
|
+
;
|
|
9840
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_mutaties_klaarzetten(uuid) FROM PUBLIC;
|
|
9841
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_mutaties_klaarzetten(uuid) FROM anon;
|
|
9842
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_mutaties_klaarzetten(uuid) TO authenticated;
|
|
9843
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_mutaties_klaarzetten(uuid) TO service_role;
|
|
9844
|
+
CREATE OR REPLACE FUNCTION public.voorraad_floriday_mutaties_klaarzetten_alle()
|
|
9845
|
+
RETURNS jsonb
|
|
9846
|
+
LANGUAGE plpgsql
|
|
9847
|
+
SECURITY DEFINER
|
|
9848
|
+
SET search_path TO 'public'
|
|
9849
|
+
AS $function$
|
|
9850
|
+
DECLARE r record; v jsonb; n integer := 0; w integer := 0;
|
|
9851
|
+
BEGIN
|
|
9852
|
+
PERFORM public.voorraad_vereis('server', 'voorraad_floriday_mutaties_klaarzetten_alle');
|
|
9853
|
+
FOR r IN SELECT DISTINCT product_id FROM public.voorraad_floriday_mutaties
|
|
9854
|
+
WHERE status IN ('open','mislukt') AND volgende_poging_at <= now() AND pogingen < 10 ORDER BY 1 LOOP
|
|
9855
|
+
v := public.voorraad_floriday_mutaties_klaarzetten(r.product_id);
|
|
9856
|
+
IF v->>'status' = 'klaargezet' THEN n := n + 1; ELSIF v->>'status' = 'wacht_op_ophaalronde' THEN w := w + 1; END IF;
|
|
9857
|
+
END LOOP;
|
|
9858
|
+
RETURN jsonb_build_object('klaargezet', n, 'wacht', w);
|
|
9859
|
+
END $function$
|
|
9860
|
+
;
|
|
9861
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_mutaties_klaarzetten_alle() FROM PUBLIC;
|
|
9862
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_mutaties_klaarzetten_alle() FROM anon;
|
|
9863
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_mutaties_klaarzetten_alle() TO authenticated;
|
|
9864
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_mutaties_klaarzetten_alle() TO service_role;
|
|
9865
|
+
CREATE OR REPLACE FUNCTION public.voorraad_floriday_mutaties_order(p_order_id uuid)
|
|
9866
|
+
RETURNS integer
|
|
9867
|
+
LANGUAGE plpgsql
|
|
9868
|
+
SECURITY DEFINER
|
|
9869
|
+
SET search_path TO 'public'
|
|
9870
|
+
AS $function$
|
|
9871
|
+
DECLARE o record; v_actief boolean; l record; v_pid uuid; v_key text; v_doel integer; n integer := 0; v_ref text;
|
|
9872
|
+
BEGIN
|
|
9873
|
+
PERFORM public.voorraad_vereis('server', 'voorraad_floriday_mutaties_order');
|
|
9874
|
+
IF p_order_id IS NULL OR NOT EXISTS (SELECT 1 FROM public.floriday_inventory_settings WHERE erp_leading = false) THEN RETURN 0; END IF;
|
|
9875
|
+
SELECT * INTO o FROM public.orders WHERE id = p_order_id;
|
|
9876
|
+
IF FOUND AND public.normalize_order_source(o.order_source) = 'FO' THEN RETURN 0; END IF; -- Floriday kent deze verkoop al
|
|
9877
|
+
v_actief := FOUND AND o.deleted_at IS NULL AND o.cancelled_at IS NULL
|
|
9878
|
+
AND lower(COALESCE(o.status, '')) NOT IN ('geannuleerd','cancelled','canceled','annulering')
|
|
9879
|
+
AND NOT EXISTS (SELECT 1 FROM public.voorraad_order_terugdraaiing t WHERE t.order_id = p_order_id);
|
|
9880
|
+
v_ref := COALESCE(o.order_number::text, p_order_id::text);
|
|
9881
|
+
FOR l IN
|
|
9882
|
+
SELECT oi.id, oi.product_id, oi.quantity, (oi.quarantined_at IS NULL) AS ok FROM public.order_items oi WHERE oi.order_id = p_order_id
|
|
9883
|
+
UNION ALL
|
|
9884
|
+
SELECT DISTINCT ON (m.order_item_id) m.order_item_id, m.product_id, 0, false FROM public.voorraad_floriday_mutaties m
|
|
9885
|
+
WHERE m.order_id = p_order_id AND m.order_item_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM public.order_items x WHERE x.id = m.order_item_id)
|
|
9886
|
+
LOOP
|
|
9887
|
+
IF l.product_id IS NULL THEN CONTINUE; END IF;
|
|
9888
|
+
v_pid := NULL;
|
|
9889
|
+
BEGIN SELECT c.product_id, c.trade_item_key INTO v_pid, v_key FROM public.voorraad_canoniek_artikel(l.product_id::text) c LIMIT 1;
|
|
9890
|
+
EXCEPTION WHEN others THEN v_pid := NULL; END;
|
|
9891
|
+
v_pid := COALESCE(v_pid, l.product_id);
|
|
9892
|
+
IF NOT public.voorraad_floriday_leads_key(COALESCE(v_key, v_pid::text))
|
|
9893
|
+
AND NOT EXISTS (SELECT 1 FROM public.voorraad_floriday_mutaties m WHERE m.order_item_id = l.id) THEN CONTINUE; END IF;
|
|
9894
|
+
IF NOT public.voorraad_floriday_leads_key(COALESCE(v_key, v_pid::text)) THEN CONTINUE; END IF; -- niet meer leidend: ERP stuurt alles
|
|
9895
|
+
v_doel := CASE WHEN v_actief AND l.ok THEN -CEIL(COALESCE(l.quantity, 0))::integer ELSE 0 END;
|
|
9896
|
+
IF public.voorraad_floriday_mutatie_naar(v_pid, v_doel, p_order_id, l.id, v_ref, 'order') <> 0 THEN n := n + 1; END IF;
|
|
9897
|
+
END LOOP;
|
|
9898
|
+
IF n > 0 THEN
|
|
9899
|
+
PERFORM public.voorraad_floriday_mutaties_klaarzetten(m.product_id)
|
|
9900
|
+
FROM (SELECT DISTINCT product_id FROM public.voorraad_floriday_mutaties WHERE order_id = p_order_id AND status = 'open') m;
|
|
9901
|
+
END IF;
|
|
9902
|
+
RETURN n;
|
|
9903
|
+
END $function$
|
|
9904
|
+
;
|
|
9905
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_mutaties_order(uuid) FROM PUBLIC;
|
|
9906
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_mutaties_order(uuid) FROM anon;
|
|
9907
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_mutaties_order(uuid) TO authenticated;
|
|
9908
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_mutaties_order(uuid) TO service_role;
|
|
9909
|
+
CREATE OR REPLACE FUNCTION public.voorraad_floriday_mutaties_ronde()
|
|
9910
|
+
RETURNS jsonb
|
|
9911
|
+
LANGUAGE plpgsql
|
|
9912
|
+
SECURITY DEFINER
|
|
9913
|
+
SET search_path TO 'public'
|
|
9914
|
+
AS $function$
|
|
9915
|
+
DECLARE n_verz integer; n_bev integer; n_mis integer; v_lijst jsonb; v_conn uuid; v_inh jsonb;
|
|
9916
|
+
BEGIN
|
|
9917
|
+
PERFORM public.voorraad_vereis('server', 'voorraad_floriday_mutaties_ronde');
|
|
9918
|
+
BEGIN
|
|
9919
|
+
v_inh := public.voorraad_floriday_mutaties_inhalen(true);
|
|
9920
|
+
EXCEPTION WHEN others THEN
|
|
9921
|
+
RAISE WARNING 'voorraad_floriday_mutaties_ronde: inhalen mislukt: %', SQLERRM;
|
|
9922
|
+
v_inh := jsonb_build_object('fout', left(SQLERRM, 300));
|
|
9923
|
+
END;
|
|
9924
|
+
UPDATE public.voorraad_floriday_mutaties m SET queue_id = q.superseded_by
|
|
9925
|
+
FROM public.floriday_continuous_stock_queue q
|
|
9926
|
+
WHERE m.status = 'in_wachtrij' AND m.queue_id = q.id AND q.superseded_by IS NOT NULL;
|
|
9927
|
+
UPDATE public.voorraad_floriday_mutaties m SET status = 'verzonden', verzonden_at = q.quantity_sent_at
|
|
9928
|
+
FROM public.floriday_continuous_stock_queue q
|
|
9929
|
+
WHERE m.status = 'in_wachtrij' AND m.queue_id = q.id AND q.status = 'sent' AND q.quantity_sent_at IS NOT NULL
|
|
9930
|
+
AND m.created_at <= COALESCE(q.locked_at, q.quantity_sent_at);
|
|
9931
|
+
GET DIAGNOSTICS n_verz = ROW_COUNT;
|
|
9932
|
+
UPDATE public.voorraad_floriday_mutaties m SET status = 'open'
|
|
9933
|
+
FROM public.floriday_continuous_stock_queue q
|
|
9934
|
+
WHERE m.status = 'in_wachtrij' AND m.queue_id = q.id AND q.status = 'sent';
|
|
9935
|
+
UPDATE public.voorraad_floriday_mutaties m
|
|
9936
|
+
SET status = 'mislukt', pogingen = m.pogingen + 1,
|
|
9937
|
+
laatste_fout = left(COALESCE(q.last_error, q.result_label, q.skip_reason, q.status), 300),
|
|
9938
|
+
volgende_poging_at = now() + make_interval(mins => LEAST(power(2, m.pogingen)::int, 60))
|
|
9939
|
+
FROM public.floriday_continuous_stock_queue q
|
|
9940
|
+
WHERE m.status = 'in_wachtrij' AND m.queue_id = q.id AND q.status NOT IN ('pending','processing','sent');
|
|
9941
|
+
GET DIAGNOSTICS n_mis = ROW_COUNT;
|
|
9942
|
+
UPDATE public.voorraad_floriday_mutaties m SET status = 'bevestigd', bevestigd_at = st.opgehaald_at
|
|
9943
|
+
FROM public.voorraad_floriday_stand st
|
|
9944
|
+
WHERE m.status = 'verzonden' AND st.connection_id = m.connection_id AND st.trade_item_id = m.trade_item_id
|
|
9945
|
+
AND st.opgehaald_at > m.verzonden_at;
|
|
9946
|
+
GET DIAGNOSTICS n_bev = ROW_COUNT;
|
|
9947
|
+
|
|
9948
|
+
SELECT c.connection_id INTO v_conn FROM public.get_active_floriday_context() c;
|
|
9949
|
+
SELECT COALESCE(jsonb_agg(DISTINCT jsonb_build_object('product_id', z.product_id, 'trade_item_id', z.trade_item_id)), '[]'::jsonb) INTO v_lijst
|
|
9950
|
+
FROM (
|
|
9951
|
+
SELECT m.product_id, m.trade_item_id FROM public.voorraad_floriday_mutaties m
|
|
9952
|
+
WHERE m.trade_item_id IS NOT NULL AND (m.status = 'verzonden'
|
|
9953
|
+
OR (m.status IN ('open','mislukt') AND m.volgende_poging_at <= now() AND m.pogingen < 10))
|
|
9954
|
+
UNION
|
|
9955
|
+
-- Floriday verkocht zelf: nieuwe FO-regel sinds de laatste stand → stand lezen zodat de eigen voorraad meteen volgt
|
|
9956
|
+
SELECT s.product_id, NULLIF(s.floriday_trade_item_id::text, '')::uuid
|
|
9957
|
+
FROM public.order_items oi JOIN public.orders o ON o.id = oi.order_id
|
|
9958
|
+
JOIN public.floriday_inventory_settings s ON s.product_id = oi.product_id AND s.erp_leading = false
|
|
9959
|
+
AND s.connection_id = COALESCE(v_conn, s.connection_id)
|
|
9960
|
+
LEFT JOIN public.voorraad_floriday_stand st ON st.connection_id = s.connection_id AND st.trade_item_id::text = s.floriday_trade_item_id::text
|
|
9961
|
+
WHERE public.normalize_order_source(o.order_source) = 'FO' AND o.deleted_at IS NULL
|
|
9962
|
+
AND GREATEST(o.updated_at, o.created_at) >= now() - interval '2 days'
|
|
9963
|
+
AND GREATEST(o.updated_at, o.created_at) > COALESCE(st.opgehaald_at, '-infinity'::timestamptz)
|
|
9964
|
+
AND s.floriday_trade_item_id IS NOT NULL AND s.floriday_trade_item_id::text ~* '^[0-9a-f-]{36}$'
|
|
9965
|
+
) z;
|
|
9966
|
+
RETURN jsonb_build_object('connection_id', v_conn, 'verzonden', n_verz, 'bevestigd', n_bev, 'mislukt', n_mis, 'te_lezen', v_lijst, 'ingehaald', v_inh);
|
|
9967
|
+
END $function$
|
|
9968
|
+
;
|
|
9969
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_mutaties_ronde() FROM PUBLIC;
|
|
9970
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_mutaties_ronde() FROM anon;
|
|
9971
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_mutaties_ronde() TO authenticated;
|
|
9972
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_mutaties_ronde() TO service_role;
|
|
9973
|
+
CREATE OR REPLACE FUNCTION public.voorraad_floriday_mutaties_trg()
|
|
9974
|
+
RETURNS trigger
|
|
9975
|
+
LANGUAGE plpgsql
|
|
9976
|
+
SECURITY DEFINER
|
|
9977
|
+
SET search_path TO 'public'
|
|
9978
|
+
AS $function$
|
|
9979
|
+
DECLARE v_order uuid;
|
|
9980
|
+
BEGIN
|
|
9981
|
+
-- Alleen geneste IF's: een orders-rij heeft geen order_id, en een gecombineerde expressie faalt daarop.
|
|
9982
|
+
IF TG_TABLE_NAME = 'orders' THEN
|
|
9983
|
+
IF TG_OP = 'DELETE' THEN v_order := OLD.id; ELSE v_order := NEW.id; END IF;
|
|
9984
|
+
PERFORM public.voorraad_floriday_mutaties_order(v_order);
|
|
9985
|
+
ELSE
|
|
9986
|
+
IF TG_OP = 'DELETE' THEN v_order := OLD.order_id; ELSE v_order := NEW.order_id; END IF;
|
|
9987
|
+
PERFORM public.voorraad_floriday_mutaties_order(v_order);
|
|
9988
|
+
IF TG_OP = 'UPDATE' THEN
|
|
9989
|
+
IF OLD.order_id IS DISTINCT FROM NEW.order_id THEN
|
|
9990
|
+
PERFORM public.voorraad_floriday_mutaties_order(OLD.order_id);
|
|
9991
|
+
END IF;
|
|
9992
|
+
END IF;
|
|
9993
|
+
END IF;
|
|
9994
|
+
RETURN NULL;
|
|
9995
|
+
EXCEPTION WHEN others THEN
|
|
9996
|
+
-- Nooit de orderwijziging blokkeren; de integriteitscontrole meldt een ontbrekende mutatie.
|
|
9997
|
+
RAISE WARNING '[voorraad-floriday-mutatie] order %: %', v_order, SQLERRM;
|
|
9998
|
+
RETURN NULL;
|
|
9999
|
+
END $function$
|
|
10000
|
+
;
|
|
10001
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_mutaties_trg() FROM PUBLIC;
|
|
10002
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_mutaties_trg() FROM anon;
|
|
10003
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_mutaties_trg() TO service_role;
|
|
10004
|
+
CREATE OR REPLACE FUNCTION public.voorraad_floriday_orders_vers()
|
|
10005
|
+
RETURNS boolean
|
|
10006
|
+
LANGUAGE plpgsql
|
|
10007
|
+
STABLE SECURITY DEFINER
|
|
10008
|
+
SET search_path TO 'public'
|
|
10009
|
+
AS $function$
|
|
10010
|
+
BEGIN
|
|
10011
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_floriday_orders_vers');
|
|
10012
|
+
RETURN EXISTS (SELECT 1 FROM public.floriday_sync_state s
|
|
10013
|
+
WHERE s.entity_type = 'sales-orders' AND s.last_success_at >= now() - interval '2 minutes'
|
|
10014
|
+
AND s.connection_id = COALESCE((SELECT c.connection_id FROM public.get_active_floriday_context() c), s.connection_id));
|
|
10015
|
+
END $function$
|
|
10016
|
+
;
|
|
10017
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_orders_vers() FROM PUBLIC;
|
|
10018
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_orders_vers() FROM anon;
|
|
10019
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_orders_vers() TO authenticated;
|
|
10020
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_orders_vers() TO service_role;
|
|
9899
10021
|
CREATE OR REPLACE FUNCTION public.voorraad_floriday_product_van(p_floriday_id text)
|
|
9900
10022
|
RETURNS uuid
|
|
9901
10023
|
LANGUAGE plpgsql
|
|
@@ -9922,6 +10044,42 @@ REVOKE ALL ON FUNCTION voorraad_floriday_product_van(text) FROM PUBLIC;
|
|
|
9922
10044
|
REVOKE ALL ON FUNCTION voorraad_floriday_product_van(text) FROM anon;
|
|
9923
10045
|
GRANT EXECUTE ON FUNCTION voorraad_floriday_product_van(text) TO authenticated;
|
|
9924
10046
|
GRANT EXECUTE ON FUNCTION voorraad_floriday_product_van(text) TO service_role;
|
|
10047
|
+
CREATE OR REPLACE FUNCTION public.voorraad_floriday_stand_vastleggen(p_connection_id uuid, p_jaar integer, p_week integer, p_rows jsonb)
|
|
10048
|
+
RETURNS integer
|
|
10049
|
+
LANGUAGE plpgsql
|
|
10050
|
+
SECURITY DEFINER
|
|
10051
|
+
SET search_path TO 'public'
|
|
10052
|
+
AS $function$
|
|
10053
|
+
DECLARE n integer; v_items jsonb; v_res jsonb;
|
|
10054
|
+
BEGIN
|
|
10055
|
+
PERFORM public.voorraad_vereis('server', 'voorraad_floriday_stand_vastleggen');
|
|
10056
|
+
INSERT INTO public.voorraad_floriday_stand(connection_id, trade_item_id, number_of_pieces, jaar, week, opgehaald_at)
|
|
10057
|
+
SELECT p_connection_id, (e->>'trade_item_id')::uuid, GREATEST(COALESCE((e->>'number_of_pieces')::numeric, 0), 0)::integer, p_jaar, p_week, now()
|
|
10058
|
+
FROM jsonb_array_elements(COALESCE(p_rows, '[]'::jsonb)) e
|
|
10059
|
+
WHERE e->>'trade_item_id' ~* '^[0-9a-f-]{36}$'
|
|
10060
|
+
ON CONFLICT (connection_id, trade_item_id) DO UPDATE
|
|
10061
|
+
SET number_of_pieces = EXCLUDED.number_of_pieces, jaar = EXCLUDED.jaar, week = EXCLUDED.week, opgehaald_at = EXCLUDED.opgehaald_at;
|
|
10062
|
+
GET DIAGNOSTICS n = ROW_COUNT;
|
|
10063
|
+
SELECT COALESCE(jsonb_agg(jsonb_build_object('trade_item_id', e->>'trade_item_id',
|
|
10064
|
+
'stock', GREATEST(COALESCE((e->>'number_of_pieces')::numeric, 0), 0))), '[]'::jsonb)
|
|
10065
|
+
INTO v_items FROM jsonb_array_elements(COALESCE(p_rows, '[]'::jsonb)) e WHERE e->>'trade_item_id' ~* '^[0-9a-f-]{36}$';
|
|
10066
|
+
IF jsonb_array_length(v_items) > 0 THEN
|
|
10067
|
+
BEGIN
|
|
10068
|
+
v_res := public.floriday_follow_apply(p_connection_id, v_items);
|
|
10069
|
+
IF COALESCE((v_res->>'failed')::int, 0) > 0 THEN
|
|
10070
|
+
RAISE WARNING 'voorraad_floriday_stand_vastleggen: % artikelen niet bijgewerkt (zie follow_floriday_result)', v_res->>'failed';
|
|
10071
|
+
END IF;
|
|
10072
|
+
EXCEPTION WHEN others THEN
|
|
10073
|
+
RAISE WARNING 'voorraad_floriday_stand_vastleggen: volgen mislukt: %', SQLERRM;
|
|
10074
|
+
END;
|
|
10075
|
+
END IF;
|
|
10076
|
+
RETURN n;
|
|
10077
|
+
END $function$
|
|
10078
|
+
;
|
|
10079
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_stand_vastleggen(uuid,integer,integer,jsonb) FROM PUBLIC;
|
|
10080
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_stand_vastleggen(uuid,integer,integer,jsonb) FROM anon;
|
|
10081
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_stand_vastleggen(uuid,integer,integer,jsonb) TO authenticated;
|
|
10082
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_stand_vastleggen(uuid,integer,integer,jsonb) TO service_role;
|
|
9925
10083
|
CREATE OR REPLACE FUNCTION public.voorraad_floriday_versieronde_geslaagd(p_connection_id uuid)
|
|
9926
10084
|
RETURNS boolean
|
|
9927
10085
|
LANGUAGE plpgsql
|
|
@@ -10230,6 +10388,38 @@ REVOKE ALL ON FUNCTION voorraad_floriday_vervallen_verwerken(boolean) FROM PUBLI
|
|
|
10230
10388
|
REVOKE ALL ON FUNCTION voorraad_floriday_vervallen_verwerken(boolean) FROM anon;
|
|
10231
10389
|
GRANT EXECUTE ON FUNCTION voorraad_floriday_vervallen_verwerken(boolean) TO authenticated;
|
|
10232
10390
|
GRANT EXECUTE ON FUNCTION voorraad_floriday_vervallen_verwerken(boolean) TO service_role;
|
|
10391
|
+
CREATE OR REPLACE FUNCTION public.voorraad_floriday_volg_waarde(p_product_id uuid, p_connection_id uuid, p_floriday numeric)
|
|
10392
|
+
RETURNS numeric
|
|
10393
|
+
LANGUAGE plpgsql
|
|
10394
|
+
STABLE SECURITY DEFINER
|
|
10395
|
+
SET search_path TO 'public'
|
|
10396
|
+
AS $function$
|
|
10397
|
+
DECLARE v_f numeric := p_floriday; v_t timestamptz; v_u numeric; v_r numeric;
|
|
10398
|
+
BEGIN
|
|
10399
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_floriday_volg_waarde');
|
|
10400
|
+
SELECT st.number_of_pieces, st.opgehaald_at INTO v_f, v_t
|
|
10401
|
+
FROM public.voorraad_floriday_stand st JOIN public.products p ON lower(p.floriday_trade_item_id) = lower(st.trade_item_id::text)
|
|
10402
|
+
WHERE p.id = p_product_id AND st.connection_id = p_connection_id AND st.opgehaald_at >= now() - interval '65 minutes'
|
|
10403
|
+
ORDER BY st.opgehaald_at DESC LIMIT 1;
|
|
10404
|
+
IF v_t IS NULL THEN v_f := p_floriday; END IF;
|
|
10405
|
+
SELECT COALESCE(SUM(m.delta), 0) INTO v_u FROM public.voorraad_floriday_mutaties m
|
|
10406
|
+
WHERE m.product_id = p_product_id
|
|
10407
|
+
AND (m.status IN ('open','in_wachtrij','mislukt') OR (m.status = 'verzonden' AND (v_t IS NULL OR m.verzonden_at >= v_t)));
|
|
10408
|
+
SELECT COALESCE(SUM(-x.som * x.rest), 0) INTO v_r FROM (
|
|
10409
|
+
SELECT SUM(m.delta) AS som,
|
|
10410
|
+
CASE WHEN EXISTS (SELECT 1 FROM public.stock_mutation_log l WHERE l.order_item_id = m.order_item_id AND l.mutation_type = 'consumption_done') THEN 0
|
|
10411
|
+
ELSE COALESCE((SELECT GREATEST(v.besteld - v.verzonden, 0) / NULLIF(v.besteld, 0) FROM public.voorraad_orderregel_verzending v
|
|
10412
|
+
WHERE v.order_item_id = m.order_item_id), 1) END AS rest
|
|
10413
|
+
FROM public.voorraad_floriday_mutaties m
|
|
10414
|
+
WHERE m.product_id = p_product_id AND m.order_item_id IS NOT NULL
|
|
10415
|
+
GROUP BY m.order_item_id) x;
|
|
10416
|
+
RETURN v_f + v_u + v_r;
|
|
10417
|
+
END $function$
|
|
10418
|
+
;
|
|
10419
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_volg_waarde(uuid,uuid,numeric) FROM PUBLIC;
|
|
10420
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_volg_waarde(uuid,uuid,numeric) FROM anon;
|
|
10421
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_volg_waarde(uuid,uuid,numeric) TO authenticated;
|
|
10422
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_volg_waarde(uuid,uuid,numeric) TO service_role;
|
|
10233
10423
|
CREATE OR REPLACE FUNCTION public.voorraad_floriday_volgt(p_product_id uuid)
|
|
10234
10424
|
RETURNS boolean
|
|
10235
10425
|
LANGUAGE plpgsql
|
|
@@ -10675,7 +10865,7 @@ BEGIN
|
|
|
10675
10865
|
-- Zelfde regel als src/server-hooks/guard.ts (hookEnabled).
|
|
10676
10866
|
SELECT lower(trim(value)) INTO v FROM public.module_runtime_config WHERE key = 'voorraad_hook_enabled.' || p_name;
|
|
10677
10867
|
IF v IS NOT NULL AND v <> 'standaard' THEN RETURN v = 'true'; END IF;
|
|
10678
|
-
IF p_name IN ('follow_floriday', 'floriday_versies') THEN RETURN true; END IF;
|
|
10868
|
+
IF p_name IN ('follow_floriday', 'floriday_versies', 'floriday_mutaties') THEN RETURN true; END IF;
|
|
10679
10869
|
IF p_name IN ('floriday_base_supply', 'logistics_tasks') THEN
|
|
10680
10870
|
RETURN EXISTS (SELECT 1 FROM public.floriday_inventory_settings WHERE erp_leading = true)
|
|
10681
10871
|
OR EXISTS (SELECT 1 FROM public.floriday_inventory_settings WHERE erp_leading IS NULL AND stock_mode <> 'DISABLED');
|
|
@@ -10750,7 +10940,7 @@ CREATE OR REPLACE FUNCTION public.voorraad_install_check()
|
|
|
10750
10940
|
STABLE SECURITY DEFINER
|
|
10751
10941
|
SET search_path TO 'public'
|
|
10752
10942
|
AS $function$
|
|
10753
|
-
DECLARE v_f text[] := ARRAY['voorraad_foto_info','voorraad_lijst_v2','voorraad_lijst_v2_rijen','voorraad_kpi','voorraad_validatie_pagina','voorraad_groep_volgorde_opslaan','voorraad_floriday_versieronde_geslaagd','voorraad_is_beheerder','voorraad_floriday_versieronde_volgende','voorraad_floriday_versieronde_portie','run_floriday_versieronde','voorraad_floriday_versieronde_inplannen','voorraad_floriday_versieronde_melding','voorraad_floriday_versieronde_status','voorraad_floriday_product_van','voorraad_floriday_vervallen_verwerken','voorraad_floriday_versies_vastleggen','voorraad_fust_historisch_vervallen','voorraad_correctie_1148','voorraad_instellingen_lezen','voorraad_twijfel_nieuw_artikel','voorraad_eigen_velden_opslaan','voorraad_traysticker_opslaan','voorraad_floriday_volgt','voorraad_artikel_archiveren','voorraad_orders_gearchiveerd','voorraad_twijfel_kiezen','voorraad_twijfel_lijst','voorraad_voorraad_instellingen_opslaan','voorraad_artikel_detail','voorraad_artikel_opslaan','voorraad_voorraad_corrigeren','voorraad_lijst','voorraad_floriday_artikelen_aanmaken','voorraad_floriday_artikelen_vangnet','voorraad_orderregel_trade_item','voorraad_orderregel_trade_item_bron','voorraad_correctie_1144','voorraad_telmoment_lijst','voorraad_telmoment_opslaan','voorraad_order_vertrokken_voor','voorraad_fust_startmoment_opslaan','voorraad_fust_startmoment_auto','voorraad_fust_instellingen_opslaan','voorraad_koppeling_check','voorraad_instellingen_opslaan','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'];
|
|
10943
|
+
DECLARE v_f text[] := ARRAY['voorraad_floriday_mutaties_inhalen','voorraad_floriday_inhalen_kandidaten','voorraad_floriday_inhalen_open','voorraad_floriday_stand_vastleggen','voorraad_integriteit_check','voorraad_integriteit_status','voorraad_push_wacht_status','voorraad_order_terugdraaien','consume_order_item_v2','voorraad_lock_sleutels','voorraad_reservering_extra','voorraad_floriday_mutaties_order','voorraad_floriday_mutaties_ronde','voorraad_floriday_mutaties_klaarzetten','voorraad_eigen_verkoop_mutatie','voorraad_floriday_volg_waarde','voorraad_floriday_mutatie_doel','voorraad_floriday_orders_vers','productie_order_aanmaken','productie_order_verwerken','productie_order_annuleren','productie_order_terugdraaien','productie_orders_lijst','voorraad_foto_info','voorraad_lijst_v2','voorraad_lijst_v2_rijen','voorraad_kpi','voorraad_validatie_pagina','voorraad_groep_volgorde_opslaan','voorraad_floriday_versieronde_geslaagd','voorraad_is_beheerder','voorraad_floriday_versieronde_volgende','voorraad_floriday_versieronde_portie','run_floriday_versieronde','voorraad_floriday_versieronde_inplannen','voorraad_floriday_versieronde_melding','voorraad_floriday_versieronde_status','voorraad_floriday_product_van','voorraad_floriday_vervallen_verwerken','voorraad_floriday_versies_vastleggen','voorraad_fust_historisch_vervallen','voorraad_correctie_1148','voorraad_instellingen_lezen','voorraad_twijfel_nieuw_artikel','voorraad_eigen_velden_opslaan','voorraad_traysticker_opslaan','voorraad_floriday_volgt','voorraad_artikel_archiveren','voorraad_orders_gearchiveerd','voorraad_twijfel_kiezen','voorraad_twijfel_lijst','voorraad_voorraad_instellingen_opslaan','voorraad_artikel_detail','voorraad_artikel_opslaan','voorraad_voorraad_corrigeren','voorraad_lijst','voorraad_floriday_artikelen_aanmaken','voorraad_floriday_artikelen_vangnet','voorraad_orderregel_trade_item','voorraad_orderregel_trade_item_bron','voorraad_correctie_1144','voorraad_telmoment_lijst','voorraad_telmoment_opslaan','voorraad_order_vertrokken_voor','voorraad_fust_startmoment_opslaan','voorraad_fust_startmoment_auto','voorraad_fust_instellingen_opslaan','voorraad_koppeling_check','voorraad_instellingen_opslaan','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'];
|
|
10754
10944
|
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'];
|
|
10755
10945
|
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'];
|
|
10756
10946
|
v_open text[] := ARRAY['voorraad_is_server','voorraad_vereis'];
|
|
@@ -10787,7 +10977,7 @@ BEGIN
|
|
|
10787
10977
|
'policies_ontbrekend', (SELECT count(*) FROM jsonb_array_elements(v_pol) e WHERE NOT (e->>'aanwezig')::boolean),
|
|
10788
10978
|
'nog_zonder_controle_volgende_ronde', (SELECT COALESCE(jsonb_agg(e->>'functie' ORDER BY e->>'functie'), '[]'::jsonb) FROM jsonb_array_elements(v_func) e WHERE e->>'soort' = 'sql' AND NOT COALESCE((e->>'interne_controle')::boolean, false) AND NOT (e->>'functie' = ANY(v_open))),
|
|
10789
10979
|
'bewust_open', 'geen pickscherm/scanner-functies zonder inlog in Voorraad'),
|
|
10790
|
-
'correctie_1098', public.voorraad_correctie_status('1098'), 'voorraad_context', public.voorraad_stock_context_status(),
|
|
10980
|
+
'integriteit', public.voorraad_integriteit_status(), 'floriday_mutaties_inhalen_open', public.voorraad_floriday_inhalen_open(), 'correctie_1098', public.voorraad_correctie_status('1098'), 'voorraad_context', public.voorraad_stock_context_status(),
|
|
10791
10981
|
'functies', v_func, 'triggers', v_trig, 'policies', v_pol);
|
|
10792
10982
|
END $function$
|
|
10793
10983
|
;
|
|
@@ -10832,6 +11022,127 @@ REVOKE ALL ON FUNCTION voorraad_instellingen_opslaan(text) FROM PUBLIC;
|
|
|
10832
11022
|
REVOKE ALL ON FUNCTION voorraad_instellingen_opslaan(text) FROM anon;
|
|
10833
11023
|
GRANT EXECUTE ON FUNCTION voorraad_instellingen_opslaan(text) TO authenticated;
|
|
10834
11024
|
GRANT EXECUTE ON FUNCTION voorraad_instellingen_opslaan(text) TO service_role;
|
|
11025
|
+
CREATE OR REPLACE FUNCTION public.voorraad_integriteit_check()
|
|
11026
|
+
RETURNS jsonb
|
|
11027
|
+
LANGUAGE plpgsql
|
|
11028
|
+
SECURITY DEFINER
|
|
11029
|
+
SET search_path TO 'public'
|
|
11030
|
+
AS $function$
|
|
11031
|
+
DECLARE
|
|
11032
|
+
v_voor jsonb; v_res jsonb := '[]'::jsonb; v_fout text; v_neg jsonb; v_zonder jsonb; v_dubbel jsonb; v_meer jsonb;
|
|
11033
|
+
v_prod jsonb; v_mut jsonb; v_ontbr jsonb; v_push jsonb; v_samen jsonb; v_uit jsonb; v_id uuid;
|
|
11034
|
+
BEGIN
|
|
11035
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_integriteit_check');
|
|
11036
|
+
-- 1. Reservering: herberekenen in een subtransactie die altijd wordt teruggedraaid (verandert niets).
|
|
11037
|
+
SELECT jsonb_object_agg(s.id::text, COALESCE(s.reserved_stock, 0)) INTO v_voor FROM public.trade_item_stock s WHERE s.archived_at IS NULL;
|
|
11038
|
+
BEGIN
|
|
11039
|
+
PERFORM public.recompute_all_reserved_stock();
|
|
11040
|
+
SELECT COALESCE(jsonb_agg(jsonb_build_object('trade_item_key', s.trade_item_key, 'artikel', p.product, 'artikelcode', p.article_number,
|
|
11041
|
+
'opgeslagen', (v_voor->>s.id::text)::int, 'berekend', COALESCE(s.reserved_stock, 0),
|
|
11042
|
+
'voorstel', 'Gereserveerd van ' || (v_voor->>s.id::text) || ' naar ' || COALESCE(s.reserved_stock, 0) || ' (reservering herberekenen)')
|
|
11043
|
+
ORDER BY s.trade_item_key), '[]'::jsonb) INTO v_res
|
|
11044
|
+
FROM public.trade_item_stock s
|
|
11045
|
+
LEFT JOIN LATERAL (SELECT c.product_id FROM public.voorraad_canoniek_artikel(s.trade_item_key) c LIMIT 1) ca ON true
|
|
11046
|
+
LEFT JOIN public.products p ON p.id = ca.product_id
|
|
11047
|
+
WHERE s.archived_at IS NULL AND v_voor ? s.id::text AND COALESCE(s.reserved_stock, 0) IS DISTINCT FROM (v_voor->>s.id::text)::int;
|
|
11048
|
+
RAISE EXCEPTION 'voorraad_integriteit_terugdraaien';
|
|
11049
|
+
EXCEPTION WHEN others THEN
|
|
11050
|
+
IF SQLERRM <> 'voorraad_integriteit_terugdraaien' THEN v_fout := SQLERRM; v_res := '[]'::jsonb; END IF;
|
|
11051
|
+
END;
|
|
11052
|
+
-- 2. Negatieve voorraad
|
|
11053
|
+
SELECT COALESCE(jsonb_agg(jsonb_build_object('trade_item_key', s.trade_item_key, 'fysiek', s.physical_stock,
|
|
11054
|
+
'voorstel', 'Tel de voorraad; staat nu op ' || s.physical_stock) ORDER BY s.physical_stock), '[]'::jsonb) INTO v_neg
|
|
11055
|
+
FROM public.trade_item_stock s WHERE s.archived_at IS NULL AND s.physical_stock < 0;
|
|
11056
|
+
-- 3. Verzonden zonder afboeking (laatste 90 dagen)
|
|
11057
|
+
SELECT COALESCE(jsonb_agg(x ORDER BY x->>'order'), '[]'::jsonb) INTO v_zonder FROM (
|
|
11058
|
+
SELECT jsonb_build_object('order', o.order_number, 'order_id', o.id, 'regel', oi.id, 'aantal', oi.quantity, 'status', o.status,
|
|
11059
|
+
'voorstel', 'Controleer of deze regel echt vertrokken is; boek dan af via de order') AS x
|
|
11060
|
+
FROM public.orders o JOIN logistics_active.order_items oi ON oi.order_id = o.id
|
|
11061
|
+
WHERE lower(COALESCE(o.status, '')) IN ('verzonden','shipped','geleverd','delivered','afgehandeld','completed')
|
|
11062
|
+
AND o.updated_at >= now() - interval '90 days' AND o.deleted_at IS NULL AND COALESCE(oi.quantity, 0) > 0
|
|
11063
|
+
AND NOT EXISTS (SELECT 1 FROM public.stock_mutation_log l WHERE l.order_item_id = oi.id
|
|
11064
|
+
AND l.mutation_type IN ('consumption','consumption_done','consumption_skipped','consumption_blocked'))
|
|
11065
|
+
-- oudere afboekroute logde per order zonder regel
|
|
11066
|
+
AND NOT EXISTS (SELECT 1 FROM public.stock_mutation_log l WHERE l.order_id = o.id AND l.order_item_id IS NULL
|
|
11067
|
+
AND l.mutation_type IN ('consumption','consumption_done','consumption_skipped','consumption_blocked'))
|
|
11068
|
+
-- Floriday leidend: FO-regels worden bewust niet afgeboekt (Floriday trok ze al af)
|
|
11069
|
+
AND NOT (public.normalize_order_source(o.order_source) = 'FO' AND oi.product_id IS NOT NULL
|
|
11070
|
+
AND public.voorraad_floriday_leads_key(oi.product_id::text))
|
|
11071
|
+
LIMIT 200) z;
|
|
11072
|
+
-- 4. Dubbel afgeboekt: dezelfde regel en hetzelfde artikel via zending én via een andere route (van vóór deze versie)
|
|
11073
|
+
SELECT COALESCE(jsonb_agg(x), '[]'::jsonb) INTO v_dubbel FROM (
|
|
11074
|
+
SELECT jsonb_build_object('regel', l.order_item_id, 'order_id', max(l.order_id::text), 'trade_item_key', l.trade_item_key,
|
|
11075
|
+
'afgeboekt', -sum(l.qty_delta), 'besteld', max(oi.quantity),
|
|
11076
|
+
'voorstel', 'Mogelijk ' || (-sum(l.qty_delta) - COALESCE(max(oi.quantity), 0)) || ' te veel afgeboekt; na controle terugboeken via een voorraadcorrectie') AS x
|
|
11077
|
+
FROM public.stock_mutation_log l LEFT JOIN public.order_items oi ON oi.id = l.order_item_id
|
|
11078
|
+
WHERE l.mutation_type = 'consumption' AND l.order_item_id IS NOT NULL
|
|
11079
|
+
GROUP BY l.order_item_id, l.trade_item_key
|
|
11080
|
+
HAVING bool_or(l.reason LIKE 'shipment %') AND bool_or(l.reason NOT LIKE 'shipment %')
|
|
11081
|
+
LIMIT 200) z;
|
|
11082
|
+
SELECT COALESCE(jsonb_agg(jsonb_build_object('regel', v.order_item_id, 'order_id', v.order_id, 'besteld', v.besteld, 'verzonden', v.verzonden,
|
|
11083
|
+
'voorstel', 'Meer verzonden dan besteld; controleer de order')), '[]'::jsonb) INTO v_meer
|
|
11084
|
+
FROM public.voorraad_orderregel_verzending v WHERE v.meer_dan_besteld;
|
|
11085
|
+
-- 5. Productie: onderdelen onder 0
|
|
11086
|
+
SELECT COALESCE(jsonb_agg(jsonb_build_object('nummer', po.nummer, 'waarschuwingen', po.waarschuwingen) ORDER BY po.verwerkt_op DESC), '[]'::jsonb) INTO v_prod
|
|
11087
|
+
FROM public.productie_orders po WHERE po.status = 'verwerkt' AND jsonb_array_length(po.waarschuwingen) > 0 AND po.verwerkt_op >= now() - interval '90 days';
|
|
11088
|
+
-- 6. Floriday-mutaties
|
|
11089
|
+
SELECT COALESCE(jsonb_agg(jsonb_build_object('product_id', m.product_id, 'referentie', m.referentie, 'verschil', m.delta, 'status', m.status,
|
|
11090
|
+
'pogingen', m.pogingen, 'fout', m.laatste_fout)), '[]'::jsonb) INTO v_mut
|
|
11091
|
+
FROM public.voorraad_floriday_mutaties m
|
|
11092
|
+
WHERE m.status = 'mislukt' OR (m.status IN ('open','in_wachtrij') AND m.created_at < now() - interval '30 minutes');
|
|
11093
|
+
SELECT COALESCE(jsonb_agg(x), '[]'::jsonb) INTO v_ontbr FROM (
|
|
11094
|
+
SELECT jsonb_build_object('order', o.order_number, 'regel', oi.id, 'aantal', oi.quantity,
|
|
11095
|
+
'voorstel', 'Eigen verkoop op een Floriday-leidend artikel zonder mutatie naar Floriday') AS x
|
|
11096
|
+
FROM public.orders o JOIN logistics_active.order_items oi ON oi.order_id = o.id
|
|
11097
|
+
WHERE public.normalize_order_source(o.order_source) <> 'FO' AND o.deleted_at IS NULL AND o.cancelled_at IS NULL
|
|
11098
|
+
AND o.created_at >= now() - interval '30 days' AND COALESCE(oi.quantity, 0) > 0
|
|
11099
|
+
AND oi.product_id IS NOT NULL AND public.voorraad_floriday_leads_key(oi.product_id::text)
|
|
11100
|
+
AND NOT EXISTS (SELECT 1 FROM public.voorraad_floriday_mutaties m WHERE m.order_item_id = oi.id)
|
|
11101
|
+
LIMIT 200) z;
|
|
11102
|
+
v_push := public.voorraad_push_wacht_status();
|
|
11103
|
+
|
|
11104
|
+
v_samen := jsonb_build_object(
|
|
11105
|
+
'reservering_afwijkend', jsonb_array_length(v_res), 'negatief', jsonb_array_length(v_neg),
|
|
11106
|
+
'verzonden_zonder_afboeking', jsonb_array_length(v_zonder), 'dubbel_afgeboekt', jsonb_array_length(v_dubbel),
|
|
11107
|
+
'meer_dan_besteld', jsonb_array_length(v_meer), 'productie_onder_nul', jsonb_array_length(v_prod),
|
|
11108
|
+
'floriday_mutaties_mislukt', jsonb_array_length(v_mut), 'floriday_mutatie_ontbreekt', jsonb_array_length(v_ontbr),
|
|
11109
|
+
'push_staat_stil', COALESCE((v_push->>'wacht')::boolean, false), 'herberekenen_mislukt', v_fout);
|
|
11110
|
+
v_samen := v_samen || jsonb_build_object('ok',
|
|
11111
|
+
v_fout IS NULL AND jsonb_array_length(v_res) + jsonb_array_length(v_neg) + jsonb_array_length(v_zonder) + jsonb_array_length(v_dubbel)
|
|
11112
|
+
+ jsonb_array_length(v_meer) + jsonb_array_length(v_prod) + jsonb_array_length(v_mut) + jsonb_array_length(v_ontbr) = 0
|
|
11113
|
+
AND NOT COALESCE((v_push->>'wacht')::boolean, false));
|
|
11114
|
+
v_uit := jsonb_build_object('reservering', v_res, 'negatief', v_neg, 'verzonden_zonder_afboeking', v_zonder, 'dubbel_afgeboekt', v_dubbel,
|
|
11115
|
+
'meer_dan_besteld', v_meer, 'productie_onder_nul', v_prod, 'floriday_mutaties', v_mut, 'floriday_mutatie_ontbreekt', v_ontbr, 'push', v_push);
|
|
11116
|
+
INSERT INTO public.voorraad_integriteit_runs(samenvatting, uitkomst) VALUES (v_samen, v_uit) RETURNING id INTO v_id;
|
|
11117
|
+
DELETE FROM public.voorraad_integriteit_runs WHERE uitgevoerd_op < now() - interval '30 days'; -- bewaartermijn
|
|
11118
|
+
RETURN jsonb_build_object('id', v_id, 'samenvatting', v_samen, 'uitkomst', v_uit);
|
|
11119
|
+
END $function$
|
|
11120
|
+
;
|
|
11121
|
+
REVOKE ALL ON FUNCTION voorraad_integriteit_check() FROM PUBLIC;
|
|
11122
|
+
REVOKE ALL ON FUNCTION voorraad_integriteit_check() FROM anon;
|
|
11123
|
+
GRANT EXECUTE ON FUNCTION voorraad_integriteit_check() TO authenticated;
|
|
11124
|
+
GRANT EXECUTE ON FUNCTION voorraad_integriteit_check() TO service_role;
|
|
11125
|
+
CREATE OR REPLACE FUNCTION public.voorraad_integriteit_status()
|
|
11126
|
+
RETURNS jsonb
|
|
11127
|
+
LANGUAGE plpgsql
|
|
11128
|
+
STABLE SECURITY DEFINER
|
|
11129
|
+
SET search_path TO 'public'
|
|
11130
|
+
AS $function$
|
|
11131
|
+
DECLARE r record;
|
|
11132
|
+
BEGIN
|
|
11133
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_integriteit_status');
|
|
11134
|
+
SELECT * INTO r FROM public.voorraad_integriteit_runs ORDER BY uitgevoerd_op DESC LIMIT 1;
|
|
11135
|
+
RETURN jsonb_build_object('laatste_controle', r.uitgevoerd_op, 'samenvatting', COALESCE(r.samenvatting, '{}'::jsonb),
|
|
11136
|
+
'push', public.voorraad_push_wacht_status(),
|
|
11137
|
+
'tekst', CASE WHEN r.id IS NULL THEN 'De voorraadcontrole heeft nog niet gedraaid.'
|
|
11138
|
+
WHEN COALESCE((r.samenvatting->>'ok')::boolean, false) THEN 'De voorraad klopt.'
|
|
11139
|
+
ELSE 'De voorraadcontrole vond afwijkingen; bekijk de uitkomst per artikel.' END);
|
|
11140
|
+
END $function$
|
|
11141
|
+
;
|
|
11142
|
+
REVOKE ALL ON FUNCTION voorraad_integriteit_status() FROM PUBLIC;
|
|
11143
|
+
REVOKE ALL ON FUNCTION voorraad_integriteit_status() FROM anon;
|
|
11144
|
+
GRANT EXECUTE ON FUNCTION voorraad_integriteit_status() TO authenticated;
|
|
11145
|
+
GRANT EXECUTE ON FUNCTION voorraad_integriteit_status() TO service_role;
|
|
10835
11146
|
CREATE OR REPLACE FUNCTION public.voorraad_is_beheerder()
|
|
10836
11147
|
RETURNS boolean
|
|
10837
11148
|
LANGUAGE plpgsql
|
|
@@ -11289,6 +11600,25 @@ REVOKE ALL ON FUNCTION voorraad_load_carriers() FROM PUBLIC;
|
|
|
11289
11600
|
REVOKE ALL ON FUNCTION voorraad_load_carriers() FROM anon;
|
|
11290
11601
|
GRANT EXECUTE ON FUNCTION voorraad_load_carriers() TO authenticated;
|
|
11291
11602
|
GRANT EXECUTE ON FUNCTION voorraad_load_carriers() TO service_role;
|
|
11603
|
+
CREATE OR REPLACE FUNCTION public.voorraad_lock_sleutels(p_keys text[])
|
|
11604
|
+
RETURNS void
|
|
11605
|
+
LANGUAGE plpgsql
|
|
11606
|
+
SECURITY DEFINER
|
|
11607
|
+
SET search_path TO 'public'
|
|
11608
|
+
AS $function$
|
|
11609
|
+
DECLARE k text;
|
|
11610
|
+
BEGIN
|
|
11611
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_lock_sleutels');
|
|
11612
|
+
FOR k IN SELECT DISTINCT btrim(x) FROM unnest(COALESCE(p_keys, '{}'::text[])) x
|
|
11613
|
+
WHERE x IS NOT NULL AND btrim(x) <> '' ORDER BY 1 LOOP
|
|
11614
|
+
PERFORM pg_advisory_xact_lock(hashtext('voorraad_res:' || k));
|
|
11615
|
+
END LOOP;
|
|
11616
|
+
END $function$
|
|
11617
|
+
;
|
|
11618
|
+
REVOKE ALL ON FUNCTION voorraad_lock_sleutels(text[]) FROM PUBLIC;
|
|
11619
|
+
REVOKE ALL ON FUNCTION voorraad_lock_sleutels(text[]) FROM anon;
|
|
11620
|
+
GRANT EXECUTE ON FUNCTION voorraad_lock_sleutels(text[]) TO authenticated;
|
|
11621
|
+
GRANT EXECUTE ON FUNCTION voorraad_lock_sleutels(text[]) TO service_role;
|
|
11292
11622
|
CREATE OR REPLACE FUNCTION public.voorraad_mark_floriday_sold_before_switch(p_product_id uuid)
|
|
11293
11623
|
RETURNS integer
|
|
11294
11624
|
LANGUAGE plpgsql
|
|
@@ -11337,6 +11667,51 @@ GRANT EXECUTE ON FUNCTION voorraad_order_geannuleerd(text,timestamp with time zo
|
|
|
11337
11667
|
REVOKE EXECUTE ON FUNCTION voorraad_order_geannuleerd(text,timestamp with time zone,timestamp with time zone) FROM anon;
|
|
11338
11668
|
GRANT EXECUTE ON FUNCTION voorraad_order_geannuleerd(text,timestamp with time zone,timestamp with time zone) TO authenticated;
|
|
11339
11669
|
GRANT EXECUTE ON FUNCTION voorraad_order_geannuleerd(text,timestamp with time zone,timestamp with time zone) TO service_role;
|
|
11670
|
+
CREATE OR REPLACE FUNCTION public.voorraad_order_terugdraaien(p_order_id uuid, p_reden text)
|
|
11671
|
+
RETURNS jsonb
|
|
11672
|
+
LANGUAGE plpgsql
|
|
11673
|
+
SECURITY DEFINER
|
|
11674
|
+
SET search_path TO 'public'
|
|
11675
|
+
AS $function$
|
|
11676
|
+
DECLARE v_nr text; v_keys text[]; k text; v_bestaat boolean;
|
|
11677
|
+
BEGIN
|
|
11678
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_order_terugdraaien');
|
|
11679
|
+
IF p_order_id IS NULL THEN RAISE EXCEPTION 'Geen order opgegeven.' USING ERRCODE = 'P0001'; END IF;
|
|
11680
|
+
SELECT o.order_number::text, true INTO v_nr, v_bestaat FROM public.orders o WHERE o.id = p_order_id FOR UPDATE;
|
|
11681
|
+
PERFORM 1 FROM public.order_items oi WHERE oi.order_id = p_order_id ORDER BY oi.id FOR UPDATE;
|
|
11682
|
+
IF EXISTS (SELECT 1 FROM public.voorraad_order_terugdraaiing t WHERE t.order_id = p_order_id) THEN
|
|
11683
|
+
RETURN jsonb_build_object('status', 'al_gedaan');
|
|
11684
|
+
END IF;
|
|
11685
|
+
IF NOT COALESCE(v_bestaat, false) THEN RAISE EXCEPTION 'Deze order bestaat niet (meer).' USING ERRCODE = 'P0001'; END IF;
|
|
11686
|
+
IF EXISTS (SELECT 1 FROM public.stock_mutation_log l JOIN public.order_items oi ON oi.id = l.order_item_id
|
|
11687
|
+
WHERE oi.order_id = p_order_id AND l.mutation_type = 'consumption')
|
|
11688
|
+
OR EXISTS (SELECT 1 FROM public.voorraad_orderregel_afboeking a WHERE a.order_id = p_order_id AND a.afgeboekt > 0) THEN
|
|
11689
|
+
RAISE EXCEPTION 'Deze order is al (deels) verzonden; corrigeer de voorraad via een voorraadcorrectie.' USING ERRCODE = 'P0001';
|
|
11690
|
+
END IF;
|
|
11691
|
+
SELECT array_agg(DISTINCT x ORDER BY x) INTO v_keys FROM (
|
|
11692
|
+
SELECT public.voorraad_orderregel_sleutel(oi.product_id::text) AS x FROM public.order_items oi
|
|
11693
|
+
WHERE oi.order_id = p_order_id AND oi.product_id IS NOT NULL) s WHERE x IS NOT NULL;
|
|
11694
|
+
INSERT INTO public.voorraad_order_terugdraaiing(order_id, order_number, reden, sleutels, door)
|
|
11695
|
+
VALUES (p_order_id, v_nr, NULLIF(btrim(COALESCE(p_reden, '')), ''), COALESCE(v_keys, '{}'), auth.uid())
|
|
11696
|
+
ON CONFLICT (order_id) DO NOTHING;
|
|
11697
|
+
IF v_keys IS NOT NULL THEN
|
|
11698
|
+
PERFORM public.voorraad_lock_sleutels(v_keys);
|
|
11699
|
+
FOREACH k IN ARRAY v_keys LOOP
|
|
11700
|
+
PERFORM public.recompute_reserved_stock(k);
|
|
11701
|
+
INSERT INTO public.stock_mutation_log(trade_item_key, order_id, mutation_type, qty_delta, reason, created_by)
|
|
11702
|
+
VALUES (k, p_order_id, 'reservation_recompute', 0,
|
|
11703
|
+
'order ' || COALESCE(v_nr, p_order_id::text) || ': terugdraaien, reden ' || COALESCE(NULLIF(btrim(p_reden), ''), 'niet opgegeven'), auth.uid());
|
|
11704
|
+
END LOOP;
|
|
11705
|
+
END IF;
|
|
11706
|
+
BEGIN PERFORM public.voorraad_floriday_mutaties_order(p_order_id);
|
|
11707
|
+
EXCEPTION WHEN others THEN RAISE WARNING '[voorraad-floriday-mutatie] terugdraaien %: %', p_order_id, SQLERRM; END;
|
|
11708
|
+
RETURN jsonb_build_object('status', 'teruggedraaid', 'order_number', v_nr, 'sleutels', COALESCE(to_jsonb(v_keys), '[]'::jsonb));
|
|
11709
|
+
END $function$
|
|
11710
|
+
;
|
|
11711
|
+
REVOKE ALL ON FUNCTION voorraad_order_terugdraaien(uuid,text) FROM PUBLIC;
|
|
11712
|
+
REVOKE ALL ON FUNCTION voorraad_order_terugdraaien(uuid,text) FROM anon;
|
|
11713
|
+
GRANT EXECUTE ON FUNCTION voorraad_order_terugdraaien(uuid,text) TO authenticated;
|
|
11714
|
+
GRANT EXECUTE ON FUNCTION voorraad_order_terugdraaien(uuid,text) TO service_role;
|
|
11340
11715
|
CREATE OR REPLACE FUNCTION public.voorraad_order_vertrokken_voor(p_order_id uuid, p_moment timestamp with time zone)
|
|
11341
11716
|
RETURNS boolean
|
|
11342
11717
|
LANGUAGE plpgsql
|
|
@@ -11627,6 +12002,98 @@ GRANT EXECUTE ON FUNCTION voorraad_production_enabled() TO service_role;
|
|
|
11627
12002
|
REVOKE EXECUTE ON FUNCTION voorraad_production_enabled() FROM anon;
|
|
11628
12003
|
GRANT EXECUTE ON FUNCTION voorraad_production_enabled() TO authenticated;
|
|
11629
12004
|
GRANT EXECUTE ON FUNCTION voorraad_production_enabled() TO service_role;
|
|
12005
|
+
CREATE OR REPLACE FUNCTION public.voorraad_push_wacht_status()
|
|
12006
|
+
RETURNS jsonb
|
|
12007
|
+
LANGUAGE plpgsql
|
|
12008
|
+
STABLE SECURITY DEFINER
|
|
12009
|
+
SET search_path TO 'public'
|
|
12010
|
+
AS $function$
|
|
12011
|
+
DECLARE v_sinds timestamptz; v_min integer; v_mis integer;
|
|
12012
|
+
BEGIN
|
|
12013
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_push_wacht_status');
|
|
12014
|
+
SELECT min(q.created_at) INTO v_sinds FROM public.floriday_continuous_stock_queue q
|
|
12015
|
+
WHERE q.status = 'pending' AND q.result_label LIKE 'Wacht op een verse ophaalronde%';
|
|
12016
|
+
SELECT count(*) INTO v_mis FROM public.voorraad_floriday_mutaties WHERE status = 'mislukt';
|
|
12017
|
+
v_min := CASE WHEN v_sinds IS NULL THEN 0 ELSE floor(extract(epoch FROM now() - v_sinds) / 60)::int END;
|
|
12018
|
+
RETURN jsonb_build_object(
|
|
12019
|
+
'wacht', v_min > 30, 'sinds', v_sinds, 'minuten', v_min, 'mislukte_mutaties', v_mis,
|
|
12020
|
+
'tekst', CASE WHEN v_min > 30 THEN 'De voorraad gaat al ' || v_min || ' minuten niet naar Floriday, omdat de nieuwste gegevens uit Floriday niet zijn opgehaald. Neem contact op met de beheerder als dit zo blijft.' END,
|
|
12021
|
+
'tekst_mutaties', CASE WHEN v_mis > 0 THEN v_mis || ' eigen verkoop' || CASE WHEN v_mis = 1 THEN '' ELSE 'en' END || ' kon' || CASE WHEN v_mis = 1 THEN '' ELSE 'den' END || ' nog niet naar Floriday; dit wordt automatisch opnieuw geprobeerd.' END);
|
|
12022
|
+
END $function$
|
|
12023
|
+
;
|
|
12024
|
+
REVOKE ALL ON FUNCTION voorraad_push_wacht_status() FROM PUBLIC;
|
|
12025
|
+
REVOKE ALL ON FUNCTION voorraad_push_wacht_status() FROM anon;
|
|
12026
|
+
GRANT EXECUTE ON FUNCTION voorraad_push_wacht_status() TO authenticated;
|
|
12027
|
+
GRANT EXECUTE ON FUNCTION voorraad_push_wacht_status() TO service_role;
|
|
12028
|
+
CREATE OR REPLACE FUNCTION public.voorraad_reservering_extra(p_key text)
|
|
12029
|
+
RETURNS integer
|
|
12030
|
+
LANGUAGE plpgsql
|
|
12031
|
+
STABLE SECURITY DEFINER
|
|
12032
|
+
SET search_path TO 'public'
|
|
12033
|
+
AS $function$
|
|
12034
|
+
DECLARE v_rest numeric := 0; v_prod numeric := 0;
|
|
12035
|
+
BEGIN
|
|
12036
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_reservering_extra');
|
|
12037
|
+
IF p_key IS NULL OR btrim(p_key) = '' THEN RETURN 0; END IF;
|
|
12038
|
+
SELECT COALESCE(SUM(GREATEST(a.besteld - a.afgeboekt, 0)), 0) INTO v_rest
|
|
12039
|
+
FROM public.voorraad_orderregel_afboeking a
|
|
12040
|
+
JOIN logistics_active.order_items oi ON oi.id = a.order_item_id
|
|
12041
|
+
JOIN public.orders o ON o.id = oi.order_id
|
|
12042
|
+
WHERE a.trade_item_key = p_key AND a.afgeboekt > 0 AND a.afgeboekt < a.besteld
|
|
12043
|
+
AND o.deleted_at IS NULL AND o.cancelled_at IS NULL
|
|
12044
|
+
AND lower(COALESCE(o.status, '')) NOT IN ('geannuleerd','cancelled','canceled','annulering','verzonden','shipped','geleverd','delivered','afgehandeld','completed','done')
|
|
12045
|
+
AND NOT EXISTS (SELECT 1 FROM public.voorraad_order_terugdraaiing t WHERE t.order_id = o.id)
|
|
12046
|
+
AND NOT (public.normalize_order_source(o.order_source) = 'FO' AND public.voorraad_floriday_leads_key(p_key));
|
|
12047
|
+
SELECT COALESCE(SUM(d.aantal), 0) INTO v_prod
|
|
12048
|
+
FROM public.productie_order_onderdelen d JOIN public.productie_orders p ON p.id = d.productie_order_id
|
|
12049
|
+
WHERE p.status = 'open' AND d.trade_item_key = p_key;
|
|
12050
|
+
RETURN CEIL(v_rest + v_prod)::integer;
|
|
12051
|
+
END $function$
|
|
12052
|
+
;
|
|
12053
|
+
REVOKE ALL ON FUNCTION voorraad_reservering_extra(text) FROM PUBLIC;
|
|
12054
|
+
REVOKE ALL ON FUNCTION voorraad_reservering_extra(text) FROM anon;
|
|
12055
|
+
GRANT EXECUTE ON FUNCTION voorraad_reservering_extra(text) TO authenticated;
|
|
12056
|
+
GRANT EXECUTE ON FUNCTION voorraad_reservering_extra(text) TO service_role;
|
|
12057
|
+
CREATE OR REPLACE FUNCTION public.voorraad_reservering_extra_trg()
|
|
12058
|
+
RETURNS trigger
|
|
12059
|
+
LANGUAGE plpgsql
|
|
12060
|
+
SECURITY DEFINER
|
|
12061
|
+
SET search_path TO 'public'
|
|
12062
|
+
AS $function$
|
|
12063
|
+
BEGIN
|
|
12064
|
+
IF NEW.change_source = 'RESERVATION_RECOMPUTE'
|
|
12065
|
+
AND COALESCE(current_setting('stock.change_source', true), '') = 'RESERVATION_RECOMPUTE' THEN
|
|
12066
|
+
NEW.reserved_stock := COALESCE(NEW.reserved_stock, 0) + public.voorraad_reservering_extra(NEW.trade_item_key);
|
|
12067
|
+
END IF;
|
|
12068
|
+
RETURN NEW;
|
|
12069
|
+
EXCEPTION WHEN others THEN
|
|
12070
|
+
RAISE WARNING '[voorraad-reservering-extra] % (sleutel %)', SQLERRM, NEW.trade_item_key;
|
|
12071
|
+
RETURN NEW;
|
|
12072
|
+
END $function$
|
|
12073
|
+
;
|
|
12074
|
+
REVOKE ALL ON FUNCTION voorraad_reservering_extra_trg() FROM PUBLIC;
|
|
12075
|
+
REVOKE ALL ON FUNCTION voorraad_reservering_extra_trg() FROM anon;
|
|
12076
|
+
GRANT EXECUTE ON FUNCTION voorraad_reservering_extra_trg() TO authenticated;
|
|
12077
|
+
GRANT EXECUTE ON FUNCTION voorraad_reservering_extra_trg() TO service_role;
|
|
12078
|
+
CREATE OR REPLACE FUNCTION public.voorraad_reservering_verschil(p_key text, p_delta numeric)
|
|
12079
|
+
RETURNS void
|
|
12080
|
+
LANGUAGE plpgsql
|
|
12081
|
+
SECURITY DEFINER
|
|
12082
|
+
SET search_path TO 'public'
|
|
12083
|
+
AS $function$
|
|
12084
|
+
BEGIN
|
|
12085
|
+
PERFORM public.voorraad_vereis('server', 'voorraad_reservering_verschil');
|
|
12086
|
+
IF p_key IS NULL OR COALESCE(p_delta, 0) = 0 THEN RETURN; END IF;
|
|
12087
|
+
PERFORM set_config('stock.change_source', 'PRODUCTION', true);
|
|
12088
|
+
UPDATE public.trade_item_stock
|
|
12089
|
+
SET reserved_stock = GREATEST(COALESCE(reserved_stock, 0) + CEIL(p_delta)::integer, 0), change_source = 'PRODUCTION', updated_at = now()
|
|
12090
|
+
WHERE trade_item_key = p_key;
|
|
12091
|
+
END $function$
|
|
12092
|
+
;
|
|
12093
|
+
REVOKE ALL ON FUNCTION voorraad_reservering_verschil(text,numeric) FROM PUBLIC;
|
|
12094
|
+
REVOKE ALL ON FUNCTION voorraad_reservering_verschil(text,numeric) FROM anon;
|
|
12095
|
+
GRANT EXECUTE ON FUNCTION voorraad_reservering_verschil(text,numeric) TO authenticated;
|
|
12096
|
+
GRANT EXECUTE ON FUNCTION voorraad_reservering_verschil(text,numeric) TO service_role;
|
|
11630
12097
|
CREATE OR REPLACE FUNCTION public.voorraad_reverse_order_mutations(p_order_id uuid, p_reason text)
|
|
11631
12098
|
RETURNS jsonb
|
|
11632
12099
|
LANGUAGE plpgsql
|
|
@@ -12411,6 +12878,8 @@ DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'order_f
|
|
|
12411
12878
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'product_merge_log_pkey' AND conrelid = 'public.product_merge_log'::regclass) THEN ALTER TABLE public.product_merge_log ADD CONSTRAINT product_merge_log_pkey PRIMARY KEY (id); END IF; END $c$;
|
|
12412
12879
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'product_packings_pkey' AND conrelid = 'public.product_packings'::regclass) THEN ALTER TABLE public.product_packings ADD CONSTRAINT product_packings_pkey PRIMARY KEY (id); END IF; END $c$;
|
|
12413
12880
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'product_tray_stickers_pkey' AND conrelid = 'public.product_tray_stickers'::regclass) THEN ALTER TABLE public.product_tray_stickers ADD CONSTRAINT product_tray_stickers_pkey PRIMARY KEY (product_id); END IF; END $c$;
|
|
12881
|
+
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'productie_order_onderdelen_pkey' AND conrelid = 'public.productie_order_onderdelen'::regclass) THEN ALTER TABLE public.productie_order_onderdelen ADD CONSTRAINT productie_order_onderdelen_pkey PRIMARY KEY (id); END IF; END $c$;
|
|
12882
|
+
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'productie_orders_pkey' AND conrelid = 'public.productie_orders'::regclass) THEN ALTER TABLE public.productie_orders ADD CONSTRAINT productie_orders_pkey PRIMARY KEY (id); END IF; END $c$;
|
|
12414
12883
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'stock_import_chunks_pkey' AND conrelid = 'public.stock_import_chunks'::regclass) THEN ALTER TABLE public.stock_import_chunks ADD CONSTRAINT stock_import_chunks_pkey PRIMARY KEY (run_id, chunk_no); END IF; END $c$;
|
|
12415
12884
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'stock_import_rows_pkey' AND conrelid = 'public.stock_import_rows'::regclass) THEN ALTER TABLE public.stock_import_rows ADD CONSTRAINT stock_import_rows_pkey PRIMARY KEY (id); END IF; END $c$;
|
|
12416
12885
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'stock_import_runs_pkey' AND conrelid = 'public.stock_import_runs'::regclass) THEN ALTER TABLE public.stock_import_runs ADD CONSTRAINT stock_import_runs_pkey PRIMARY KEY (id); END IF; END $c$;
|
|
@@ -12428,18 +12897,24 @@ DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraa
|
|
|
12428
12897
|
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$;
|
|
12429
12898
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_floriday_alias_pkey' AND conrelid = 'public.voorraad_floriday_alias'::regclass) THEN ALTER TABLE public.voorraad_floriday_alias ADD CONSTRAINT voorraad_floriday_alias_pkey PRIMARY KEY (floriday_id); END IF; END $c$;
|
|
12430
12899
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_floriday_artikel_wachtrij_pkey' AND conrelid = 'public.voorraad_floriday_artikel_wachtrij'::regclass) THEN ALTER TABLE public.voorraad_floriday_artikel_wachtrij ADD CONSTRAINT voorraad_floriday_artikel_wachtrij_pkey PRIMARY KEY (floriday_id); END IF; END $c$;
|
|
12900
|
+
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_floriday_mutaties_pkey' AND conrelid = 'public.voorraad_floriday_mutaties'::regclass) THEN ALTER TABLE public.voorraad_floriday_mutaties ADD CONSTRAINT voorraad_floriday_mutaties_pkey PRIMARY KEY (id); END IF; END $c$;
|
|
12901
|
+
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_floriday_stand_pkey' AND conrelid = 'public.voorraad_floriday_stand'::regclass) THEN ALTER TABLE public.voorraad_floriday_stand ADD CONSTRAINT voorraad_floriday_stand_pkey PRIMARY KEY (connection_id, trade_item_id); END IF; END $c$;
|
|
12431
12902
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_floriday_versie_fouten_pkey' AND conrelid = 'public.voorraad_floriday_versie_fouten'::regclass) THEN ALTER TABLE public.voorraad_floriday_versie_fouten ADD CONSTRAINT voorraad_floriday_versie_fouten_pkey PRIMARY KEY (connection_id, floriday_id); END IF; END $c$;
|
|
12432
12903
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_floriday_versie_rondes_pkey' AND conrelid = 'public.voorraad_floriday_versie_rondes'::regclass) THEN ALTER TABLE public.voorraad_floriday_versie_rondes ADD CONSTRAINT voorraad_floriday_versie_rondes_pkey PRIMARY KEY (id); END IF; END $c$;
|
|
12433
12904
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_floriday_versieronde_stand_pkey' AND conrelid = 'public.voorraad_floriday_versieronde_stand'::regclass) THEN ALTER TABLE public.voorraad_floriday_versieronde_stand ADD CONSTRAINT voorraad_floriday_versieronde_stand_pkey PRIMARY KEY (connection_id); END IF; END $c$;
|
|
12434
12905
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_floriday_versieronde_uitkomst_pkey' AND conrelid = 'public.voorraad_floriday_versieronde_uitkomst'::regclass) THEN ALTER TABLE public.voorraad_floriday_versieronde_uitkomst ADD CONSTRAINT voorraad_floriday_versieronde_uitkomst_pkey PRIMARY KEY (ronde_id, floriday_id); END IF; END $c$;
|
|
12435
12906
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_floriday_vervallen_pkey' AND conrelid = 'public.voorraad_floriday_vervallen'::regclass) THEN ALTER TABLE public.voorraad_floriday_vervallen ADD CONSTRAINT voorraad_floriday_vervallen_pkey PRIMARY KEY (floriday_id); END IF; END $c$;
|
|
12436
12907
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_instellingen_pkey' AND conrelid = 'public.voorraad_instellingen'::regclass) THEN ALTER TABLE public.voorraad_instellingen ADD CONSTRAINT voorraad_instellingen_pkey PRIMARY KEY (id); END IF; END $c$;
|
|
12908
|
+
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_integriteit_runs_pkey' AND conrelid = 'public.voorraad_integriteit_runs'::regclass) THEN ALTER TABLE public.voorraad_integriteit_runs ADD CONSTRAINT voorraad_integriteit_runs_pkey PRIMARY KEY (id); END IF; END $c$;
|
|
12437
12909
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_koppel_log_pkey' AND conrelid = 'public.voorraad_koppel_log'::regclass) THEN ALTER TABLE public.voorraad_koppel_log ADD CONSTRAINT voorraad_koppel_log_pkey PRIMARY KEY (id); END IF; END $c$;
|
|
12438
12910
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_koppel_twijfel_pkey' AND conrelid = 'public.voorraad_koppel_twijfel'::regclass) THEN ALTER TABLE public.voorraad_koppel_twijfel ADD CONSTRAINT voorraad_koppel_twijfel_pkey PRIMARY KEY (floriday_id); END IF; END $c$;
|
|
12439
12911
|
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$;
|
|
12440
12912
|
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$;
|
|
12441
12913
|
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$;
|
|
12442
12914
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_media_upload_failures_pkey' AND conrelid = 'public.voorraad_media_upload_failures'::regclass) THEN ALTER TABLE public.voorraad_media_upload_failures ADD CONSTRAINT voorraad_media_upload_failures_pkey PRIMARY KEY (id); END IF; END $c$;
|
|
12915
|
+
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_order_terugdraaiing_pkey' AND conrelid = 'public.voorraad_order_terugdraaiing'::regclass) THEN ALTER TABLE public.voorraad_order_terugdraaiing ADD CONSTRAINT voorraad_order_terugdraaiing_pkey PRIMARY KEY (order_id); END IF; END $c$;
|
|
12916
|
+
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_orderregel_afboeking_pkey' AND conrelid = 'public.voorraad_orderregel_afboeking'::regclass) THEN ALTER TABLE public.voorraad_orderregel_afboeking ADD CONSTRAINT voorraad_orderregel_afboeking_pkey PRIMARY KEY (order_item_id, trade_item_key); END IF; END $c$;
|
|
12917
|
+
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_orderregel_verzending_pkey' AND conrelid = 'public.voorraad_orderregel_verzending'::regclass) THEN ALTER TABLE public.voorraad_orderregel_verzending ADD CONSTRAINT voorraad_orderregel_verzending_pkey PRIMARY KEY (order_item_id); END IF; END $c$;
|
|
12443
12918
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_placeholder_codes_pkey' AND conrelid = 'public.voorraad_placeholder_codes'::regclass) THEN ALTER TABLE public.voorraad_placeholder_codes ADD CONSTRAINT voorraad_placeholder_codes_pkey PRIMARY KEY (code); END IF; END $c$;
|
|
12444
12919
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_publish_attempts_pkey' AND conrelid = 'public.voorraad_publish_attempts'::regclass) THEN ALTER TABLE public.voorraad_publish_attempts ADD CONSTRAINT voorraad_publish_attempts_pkey PRIMARY KEY (id); END IF; END $c$;
|
|
12445
12920
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'voorraad_publish_jobs_pkey' AND conrelid = 'public.voorraad_publish_jobs'::regclass) THEN ALTER TABLE public.voorraad_publish_jobs ADD CONSTRAINT voorraad_publish_jobs_pkey PRIMARY KEY (id); END IF; END $c$;
|
|
@@ -12453,6 +12928,7 @@ DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'florida
|
|
|
12453
12928
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fust_types_user_id_connection_id_fust_key_key' AND conrelid = 'public.fust_types'::regclass) THEN ALTER TABLE public.fust_types ADD CONSTRAINT fust_types_user_id_connection_id_fust_key_key UNIQUE (user_id, connection_id, fust_key); END IF; END $c$;
|
|
12454
12929
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'inventory_stock_snapshots_unique' AND conrelid = 'public.inventory_stock_snapshots'::regclass) THEN ALTER TABLE public.inventory_stock_snapshots ADD CONSTRAINT inventory_stock_snapshots_unique UNIQUE (connection_id, snapshot_at, granularity); END IF; END $c$;
|
|
12455
12930
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'order_fust_bookings_order_item_id_fust_type_id_key' AND conrelid = 'public.order_fust_bookings'::regclass) THEN ALTER TABLE public.order_fust_bookings ADD CONSTRAINT order_fust_bookings_order_item_id_fust_type_id_key UNIQUE (order_item_id, fust_type_id); END IF; END $c$;
|
|
12931
|
+
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'productie_orders_nummer_key' AND conrelid = 'public.productie_orders'::regclass) THEN ALTER TABLE public.productie_orders ADD CONSTRAINT productie_orders_nummer_key UNIQUE (nummer); END IF; END $c$;
|
|
12456
12932
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'stock_import_rows_run_id_row_no_key' AND conrelid = 'public.stock_import_rows'::regclass) THEN ALTER TABLE public.stock_import_rows ADD CONSTRAINT stock_import_rows_run_id_row_no_key UNIQUE (run_id, row_no); END IF; END $c$;
|
|
12457
12933
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'stock_integrity_alerts_tx_id_key' AND conrelid = 'public.stock_integrity_alerts'::regclass) THEN ALTER TABLE public.stock_integrity_alerts ADD CONSTRAINT stock_integrity_alerts_tx_id_key UNIQUE (tx_id); END IF; END $c$;
|
|
12458
12934
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'trade_item_stock_connection_id_trade_item_key_key' AND conrelid = 'public.trade_item_stock'::regclass) THEN ALTER TABLE public.trade_item_stock ADD CONSTRAINT trade_item_stock_connection_id_trade_item_key_key UNIQUE (connection_id, trade_item_key); END IF; END $c$;
|
|
@@ -12492,6 +12968,12 @@ ALTER TABLE public.product_packings DROP CONSTRAINT IF EXISTS product_packings_p
|
|
|
12492
12968
|
ALTER TABLE public.product_packings ADD CONSTRAINT product_packings_positive_check CHECK ((((pieces_per_package IS NULL) OR (pieces_per_package > 0)) AND ((packages_per_layer IS NULL) OR (packages_per_layer > 0)) AND ((layers_per_load_carrier IS NULL) OR (layers_per_load_carrier > 0))));
|
|
12493
12969
|
ALTER TABLE public.product_packings DROP CONSTRAINT IF EXISTS product_packings_source_check;
|
|
12494
12970
|
ALTER TABLE public.product_packings ADD CONSTRAINT product_packings_source_check CHECK ((source = ANY (ARRAY['floriday'::text, 'eigen'::text])));
|
|
12971
|
+
ALTER TABLE public.productie_order_onderdelen DROP CONSTRAINT IF EXISTS productie_order_onderdelen_aantal_check;
|
|
12972
|
+
ALTER TABLE public.productie_order_onderdelen ADD CONSTRAINT productie_order_onderdelen_aantal_check CHECK ((aantal >= (0)::numeric));
|
|
12973
|
+
ALTER TABLE public.productie_orders DROP CONSTRAINT IF EXISTS productie_orders_aantal_check;
|
|
12974
|
+
ALTER TABLE public.productie_orders ADD CONSTRAINT productie_orders_aantal_check CHECK ((aantal > (0)::numeric));
|
|
12975
|
+
ALTER TABLE public.productie_orders DROP CONSTRAINT IF EXISTS productie_orders_status_check;
|
|
12976
|
+
ALTER TABLE public.productie_orders ADD CONSTRAINT productie_orders_status_check CHECK ((status = ANY (ARRAY['open'::text, 'verwerkt'::text, 'geannuleerd'::text, 'teruggedraaid'::text])));
|
|
12495
12977
|
ALTER TABLE public.stock_import_chunks DROP CONSTRAINT IF EXISTS stock_import_chunks_status_check;
|
|
12496
12978
|
ALTER TABLE public.stock_import_chunks ADD CONSTRAINT stock_import_chunks_status_check CHECK ((status = ANY (ARRAY['wacht'::text, 'klaar'::text, 'ongedaan'::text])));
|
|
12497
12979
|
ALTER TABLE public.stock_import_rows DROP CONSTRAINT IF EXISTS stock_import_rows_status_check;
|
|
@@ -12506,6 +12988,8 @@ ALTER TABLE public.trade_item_drafts DROP CONSTRAINT IF EXISTS trade_item_drafts
|
|
|
12506
12988
|
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])));
|
|
12507
12989
|
ALTER TABLE public.voorraad_defaults_state DROP CONSTRAINT IF EXISTS voorraad_defaults_state_id_check;
|
|
12508
12990
|
ALTER TABLE public.voorraad_defaults_state ADD CONSTRAINT voorraad_defaults_state_id_check CHECK (id);
|
|
12991
|
+
ALTER TABLE public.voorraad_floriday_mutaties DROP CONSTRAINT IF EXISTS voorraad_floriday_mutaties_status_check;
|
|
12992
|
+
ALTER TABLE public.voorraad_floriday_mutaties ADD CONSTRAINT voorraad_floriday_mutaties_status_check CHECK ((status = ANY (ARRAY['open'::text, 'in_wachtrij'::text, 'verzonden'::text, 'bevestigd'::text, 'mislukt'::text])));
|
|
12509
12993
|
ALTER TABLE public.voorraad_instellingen DROP CONSTRAINT IF EXISTS voorraad_instellingen_id_check;
|
|
12510
12994
|
ALTER TABLE public.voorraad_instellingen ADD CONSTRAINT voorraad_instellingen_id_check CHECK (id);
|
|
12511
12995
|
ALTER TABLE public.voorraad_instellingen DROP CONSTRAINT IF EXISTS voorraad_instellingen_standaard_sturing_nieuwe_floriday_check;
|
|
@@ -12523,6 +13007,7 @@ DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'order_f
|
|
|
12523
13007
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'product_packings_fust_type_id_fkey' AND conrelid = 'public.product_packings'::regclass) THEN ALTER TABLE public.product_packings ADD CONSTRAINT product_packings_fust_type_id_fkey FOREIGN KEY (fust_type_id) REFERENCES fust_types(id) ON DELETE SET NULL; END IF; END $c$;
|
|
12524
13008
|
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 = 'product_packings_product_id_fkey' AND conrelid = 'public.product_packings'::regclass) THEN ALTER TABLE public.product_packings ADD CONSTRAINT product_packings_product_id_fkey FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE CASCADE; END IF; END $c$$q$; END IF; END $g$;
|
|
12525
13009
|
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 = 'product_tray_stickers_product_id_fkey' AND conrelid = 'public.product_tray_stickers'::regclass) THEN ALTER TABLE public.product_tray_stickers ADD CONSTRAINT product_tray_stickers_product_id_fkey FOREIGN KEY (product_id) REFERENCES products(id) ON DELETE CASCADE; END IF; END $c$$q$; END IF; END $g$;
|
|
13010
|
+
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'productie_order_onderdelen_productie_order_id_fkey' AND conrelid = 'public.productie_order_onderdelen'::regclass) THEN ALTER TABLE public.productie_order_onderdelen ADD CONSTRAINT productie_order_onderdelen_productie_order_id_fkey FOREIGN KEY (productie_order_id) REFERENCES productie_orders(id) ON DELETE RESTRICT; END IF; END $c$;
|
|
12526
13011
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'stock_import_chunks_run_id_fkey' AND conrelid = 'public.stock_import_chunks'::regclass) THEN ALTER TABLE public.stock_import_chunks ADD CONSTRAINT stock_import_chunks_run_id_fkey FOREIGN KEY (run_id) REFERENCES stock_import_runs(id) ON DELETE CASCADE; END IF; END $c$;
|
|
12527
13012
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'stock_import_rows_run_id_fkey' AND conrelid = 'public.stock_import_rows'::regclass) THEN ALTER TABLE public.stock_import_rows ADD CONSTRAINT stock_import_rows_run_id_fkey FOREIGN KEY (run_id) REFERENCES stock_import_runs(id) ON DELETE CASCADE; END IF; END $c$;
|
|
12528
13013
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'stock_import_runs_user_id_fkey' AND conrelid = 'public.stock_import_runs'::regclass) THEN ALTER TABLE public.stock_import_runs ADD CONSTRAINT stock_import_runs_user_id_fkey FOREIGN KEY (user_id) REFERENCES auth.users(id) ON DELETE CASCADE; END IF; END $c$;
|
|
@@ -12557,6 +13042,11 @@ CREATE INDEX IF NOT EXISTS idx_voorraad_publish_attempts_user_created ON public.
|
|
|
12557
13042
|
CREATE INDEX IF NOT EXISTS inventory_stock_snapshots_time_idx ON public.inventory_stock_snapshots USING btree (connection_id, snapshot_at DESC);
|
|
12558
13043
|
CREATE INDEX IF NOT EXISTS product_packings_primary_idx ON public.product_packings USING btree (product_id) WHERE is_primary;
|
|
12559
13044
|
CREATE INDEX IF NOT EXISTS product_packings_product_idx ON public.product_packings USING btree (product_id);
|
|
13045
|
+
CREATE INDEX IF NOT EXISTS productie_order_onderdelen_key_idx ON public.productie_order_onderdelen USING btree (trade_item_key);
|
|
13046
|
+
CREATE INDEX IF NOT EXISTS productie_order_onderdelen_order_idx ON public.productie_order_onderdelen USING btree (productie_order_id);
|
|
13047
|
+
CREATE INDEX IF NOT EXISTS productie_orders_nummer_trgm_idx ON public.productie_orders USING btree (lower(nummer) text_pattern_ops);
|
|
13048
|
+
CREATE INDEX IF NOT EXISTS productie_orders_product_idx ON public.productie_orders USING btree (product_id);
|
|
13049
|
+
CREATE INDEX IF NOT EXISTS productie_orders_status_idx ON public.productie_orders USING btree (status, aangemaakt_op DESC);
|
|
12560
13050
|
CREATE INDEX IF NOT EXISTS stock_import_rows_chunk_idx ON public.stock_import_rows USING btree (run_id, chunk_no);
|
|
12561
13051
|
CREATE INDEX IF NOT EXISTS stock_import_runs_hash_idx ON public.stock_import_runs USING btree (file_hash) WHERE (file_hash IS NOT NULL);
|
|
12562
13052
|
CREATE INDEX IF NOT EXISTS stock_import_runs_user_created_idx ON public.stock_import_runs USING btree (user_id, created_at DESC);
|
|
@@ -12564,8 +13054,14 @@ CREATE INDEX IF NOT EXISTS stock_integrity_alerts_open_idx ON public.stock_integ
|
|
|
12564
13054
|
CREATE INDEX IF NOT EXISTS trade_item_prices_lookup ON public.trade_item_prices USING btree (trade_item_key, price_group_id);
|
|
12565
13055
|
CREATE INDEX IF NOT EXISTS trade_item_stock_trade_item_key_idx ON public.trade_item_stock USING btree (trade_item_key);
|
|
12566
13056
|
CREATE INDEX IF NOT EXISTS voorraad_floriday_alias_lower_idx ON public.voorraad_floriday_alias USING btree (lower(floriday_id));
|
|
13057
|
+
CREATE INDEX IF NOT EXISTS voorraad_floriday_mutaties_open_idx ON public.voorraad_floriday_mutaties USING btree (product_id) WHERE (status <> 'bevestigd'::text);
|
|
13058
|
+
CREATE INDEX IF NOT EXISTS voorraad_floriday_mutaties_ref_idx ON public.voorraad_floriday_mutaties USING btree (referentie);
|
|
13059
|
+
CREATE INDEX IF NOT EXISTS voorraad_floriday_mutaties_regel_idx ON public.voorraad_floriday_mutaties USING btree (order_item_id);
|
|
13060
|
+
CREATE INDEX IF NOT EXISTS voorraad_integriteit_runs_op_idx ON public.voorraad_integriteit_runs USING btree (uitgevoerd_op DESC);
|
|
12567
13061
|
CREATE INDEX IF NOT EXISTS voorraad_koppel_log_item_idx ON public.voorraad_koppel_log USING btree (order_item_id);
|
|
12568
13062
|
CREATE INDEX IF NOT EXISTS voorraad_koppel_log_run_idx ON public.voorraad_koppel_log USING btree (run_id);
|
|
13063
|
+
CREATE INDEX IF NOT EXISTS voorraad_orderregel_afboeking_key_idx ON public.voorraad_orderregel_afboeking USING btree (trade_item_key);
|
|
13064
|
+
CREATE INDEX IF NOT EXISTS voorraad_orderregel_afboeking_order_idx ON public.voorraad_orderregel_afboeking USING btree (order_id);
|
|
12569
13065
|
CREATE UNIQUE INDEX IF NOT EXISTS fcsq_one_open_per_week ON public.floriday_continuous_stock_queue USING btree (connection_id, trade_item_id, COALESCE(target_year, '-1'::integer), COALESCE(target_week, '-1'::integer)) WHERE (status = ANY (ARRAY['pending'::text, 'needs_base_supply'::text, 'skipped_no_price'::text, 'failed'::text]));
|
|
12570
13066
|
CREATE UNIQUE INDEX IF NOT EXISTS fust_startmoment_uniek ON public.fust_startmoment USING btree (COALESCE(fust_type_id, '00000000-0000-0000-0000-000000000000'::uuid));
|
|
12571
13067
|
CREATE UNIQUE INDEX IF NOT EXISTS fust_types_fust_key_active_uidx ON public.fust_types USING btree (fust_key) WHERE ((connection_id IS NULL) AND (merged_into IS NULL));
|
|
@@ -12662,6 +13158,14 @@ ALTER TABLE public.product_tray_stickers ENABLE ROW LEVEL SECURITY;
|
|
|
12662
13158
|
REVOKE ALL ON public.product_tray_stickers FROM anon;
|
|
12663
13159
|
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.product_tray_stickers TO authenticated;
|
|
12664
13160
|
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.product_tray_stickers TO service_role;
|
|
13161
|
+
ALTER TABLE public.productie_order_onderdelen ENABLE ROW LEVEL SECURITY;
|
|
13162
|
+
REVOKE ALL ON public.productie_order_onderdelen FROM anon;
|
|
13163
|
+
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.productie_order_onderdelen TO authenticated;
|
|
13164
|
+
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.productie_order_onderdelen TO service_role;
|
|
13165
|
+
ALTER TABLE public.productie_orders ENABLE ROW LEVEL SECURITY;
|
|
13166
|
+
REVOKE ALL ON public.productie_orders FROM anon;
|
|
13167
|
+
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.productie_orders TO authenticated;
|
|
13168
|
+
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.productie_orders TO service_role;
|
|
12665
13169
|
ALTER TABLE public.stock_import_chunks ENABLE ROW LEVEL SECURITY;
|
|
12666
13170
|
REVOKE ALL ON public.stock_import_chunks FROM anon;
|
|
12667
13171
|
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.stock_import_chunks TO authenticated;
|
|
@@ -12728,6 +13232,14 @@ ALTER TABLE public.voorraad_floriday_artikel_wachtrij ENABLE ROW LEVEL SECURITY;
|
|
|
12728
13232
|
REVOKE ALL ON public.voorraad_floriday_artikel_wachtrij FROM anon;
|
|
12729
13233
|
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_floriday_artikel_wachtrij TO authenticated;
|
|
12730
13234
|
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_floriday_artikel_wachtrij TO service_role;
|
|
13235
|
+
ALTER TABLE public.voorraad_floriday_mutaties ENABLE ROW LEVEL SECURITY;
|
|
13236
|
+
REVOKE ALL ON public.voorraad_floriday_mutaties FROM anon;
|
|
13237
|
+
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_floriday_mutaties TO authenticated;
|
|
13238
|
+
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_floriday_mutaties TO service_role;
|
|
13239
|
+
ALTER TABLE public.voorraad_floriday_stand ENABLE ROW LEVEL SECURITY;
|
|
13240
|
+
REVOKE ALL ON public.voorraad_floriday_stand FROM anon;
|
|
13241
|
+
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_floriday_stand TO authenticated;
|
|
13242
|
+
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_floriday_stand TO service_role;
|
|
12731
13243
|
ALTER TABLE public.voorraad_floriday_versie_fouten ENABLE ROW LEVEL SECURITY;
|
|
12732
13244
|
REVOKE ALL ON public.voorraad_floriday_versie_fouten FROM anon;
|
|
12733
13245
|
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_floriday_versie_fouten TO authenticated;
|
|
@@ -12752,6 +13264,10 @@ ALTER TABLE public.voorraad_instellingen ENABLE ROW LEVEL SECURITY;
|
|
|
12752
13264
|
REVOKE ALL ON public.voorraad_instellingen FROM anon;
|
|
12753
13265
|
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_instellingen TO authenticated;
|
|
12754
13266
|
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_instellingen TO service_role;
|
|
13267
|
+
ALTER TABLE public.voorraad_integriteit_runs ENABLE ROW LEVEL SECURITY;
|
|
13268
|
+
REVOKE ALL ON public.voorraad_integriteit_runs FROM anon;
|
|
13269
|
+
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_integriteit_runs TO authenticated;
|
|
13270
|
+
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_integriteit_runs TO service_role;
|
|
12755
13271
|
ALTER TABLE public.voorraad_koppel_log ENABLE ROW LEVEL SECURITY;
|
|
12756
13272
|
REVOKE ALL ON public.voorraad_koppel_log FROM anon;
|
|
12757
13273
|
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_koppel_log TO authenticated;
|
|
@@ -12775,6 +13291,18 @@ ALTER TABLE public.voorraad_media_upload_failures ENABLE ROW LEVEL SECURITY;
|
|
|
12775
13291
|
REVOKE ALL ON public.voorraad_media_upload_failures FROM anon;
|
|
12776
13292
|
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_media_upload_failures TO authenticated;
|
|
12777
13293
|
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_media_upload_failures TO service_role;
|
|
13294
|
+
ALTER TABLE public.voorraad_order_terugdraaiing ENABLE ROW LEVEL SECURITY;
|
|
13295
|
+
REVOKE ALL ON public.voorraad_order_terugdraaiing FROM anon;
|
|
13296
|
+
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_order_terugdraaiing TO authenticated;
|
|
13297
|
+
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_order_terugdraaiing TO service_role;
|
|
13298
|
+
ALTER TABLE public.voorraad_orderregel_afboeking ENABLE ROW LEVEL SECURITY;
|
|
13299
|
+
REVOKE ALL ON public.voorraad_orderregel_afboeking FROM anon;
|
|
13300
|
+
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_orderregel_afboeking TO authenticated;
|
|
13301
|
+
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_orderregel_afboeking TO service_role;
|
|
13302
|
+
ALTER TABLE public.voorraad_orderregel_verzending ENABLE ROW LEVEL SECURITY;
|
|
13303
|
+
REVOKE ALL ON public.voorraad_orderregel_verzending FROM anon;
|
|
13304
|
+
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_orderregel_verzending TO authenticated;
|
|
13305
|
+
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_orderregel_verzending TO service_role;
|
|
12778
13306
|
ALTER TABLE public.voorraad_placeholder_codes ENABLE ROW LEVEL SECURITY;
|
|
12779
13307
|
REVOKE ALL ON public.voorraad_placeholder_codes FROM anon;
|
|
12780
13308
|
GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.voorraad_placeholder_codes TO authenticated;
|
|
@@ -12865,6 +13393,10 @@ DROP POLICY IF EXISTS product_packings_write ON public.product_packings;
|
|
|
12865
13393
|
CREATE POLICY product_packings_write ON public.product_packings AS PERMISSIVE FOR ALL TO authenticated USING (voorraad_can_write()) WITH CHECK (voorraad_can_write());
|
|
12866
13394
|
DROP POLICY IF EXISTS "Ingelogden beheren traystickers" ON public.product_tray_stickers;
|
|
12867
13395
|
CREATE POLICY "Ingelogden beheren traystickers" ON public.product_tray_stickers AS PERMISSIVE FOR ALL TO authenticated USING (true) WITH CHECK (true);
|
|
13396
|
+
DROP POLICY IF EXISTS "Ingelogd lezen" ON public.productie_order_onderdelen;
|
|
13397
|
+
CREATE POLICY "Ingelogd lezen" ON public.productie_order_onderdelen AS PERMISSIVE FOR SELECT TO authenticated USING (true);
|
|
13398
|
+
DROP POLICY IF EXISTS "Ingelogd lezen" ON public.productie_orders;
|
|
13399
|
+
CREATE POLICY "Ingelogd lezen" ON public.productie_orders AS PERMISSIVE FOR SELECT TO authenticated USING (true);
|
|
12868
13400
|
DROP POLICY IF EXISTS "Eigenaar leest importporties" ON public.stock_import_chunks;
|
|
12869
13401
|
CREATE POLICY "Eigenaar leest importporties" ON public.stock_import_chunks AS PERMISSIVE FOR SELECT TO authenticated USING ((EXISTS ( SELECT 1
|
|
12870
13402
|
FROM stock_import_runs r
|
|
@@ -12929,6 +13461,10 @@ DROP POLICY IF EXISTS "Ingelogd lezen alias" ON public.voorraad_floriday_alias;
|
|
|
12929
13461
|
CREATE POLICY "Ingelogd lezen alias" ON public.voorraad_floriday_alias AS PERMISSIVE FOR SELECT TO authenticated USING (true);
|
|
12930
13462
|
DROP POLICY IF EXISTS voorraad_floriday_artikel_wachtrij_lezen ON public.voorraad_floriday_artikel_wachtrij;
|
|
12931
13463
|
CREATE POLICY voorraad_floriday_artikel_wachtrij_lezen ON public.voorraad_floriday_artikel_wachtrij AS PERMISSIVE FOR SELECT TO authenticated USING (true);
|
|
13464
|
+
DROP POLICY IF EXISTS "Ingelogd lezen" ON public.voorraad_floriday_mutaties;
|
|
13465
|
+
CREATE POLICY "Ingelogd lezen" ON public.voorraad_floriday_mutaties AS PERMISSIVE FOR SELECT TO authenticated USING (true);
|
|
13466
|
+
DROP POLICY IF EXISTS "Ingelogd lezen" ON public.voorraad_floriday_stand;
|
|
13467
|
+
CREATE POLICY "Ingelogd lezen" ON public.voorraad_floriday_stand AS PERMISSIVE FOR SELECT TO authenticated USING (true);
|
|
12932
13468
|
DROP POLICY IF EXISTS "Ingelogd lezen versie fouten" ON public.voorraad_floriday_versie_fouten;
|
|
12933
13469
|
CREATE POLICY "Ingelogd lezen versie fouten" ON public.voorraad_floriday_versie_fouten AS PERMISSIVE FOR SELECT TO authenticated USING (true);
|
|
12934
13470
|
DROP POLICY IF EXISTS "Ingelogd lezen versierondes" ON public.voorraad_floriday_versie_rondes;
|
|
@@ -12939,6 +13475,8 @@ DROP POLICY IF EXISTS "Ingelogd lezen vervallen" ON public.voorraad_floriday_ver
|
|
|
12939
13475
|
CREATE POLICY "Ingelogd lezen vervallen" ON public.voorraad_floriday_vervallen AS PERMISSIVE FOR SELECT TO authenticated USING (true);
|
|
12940
13476
|
DROP POLICY IF EXISTS voorraad_instellingen_lezen ON public.voorraad_instellingen;
|
|
12941
13477
|
CREATE POLICY voorraad_instellingen_lezen ON public.voorraad_instellingen AS PERMISSIVE FOR SELECT TO authenticated USING (true);
|
|
13478
|
+
DROP POLICY IF EXISTS "Ingelogd lezen" ON public.voorraad_integriteit_runs;
|
|
13479
|
+
CREATE POLICY "Ingelogd lezen" ON public.voorraad_integriteit_runs AS PERMISSIVE FOR SELECT TO authenticated USING (true);
|
|
12942
13480
|
DROP POLICY IF EXISTS voorraad_koppel_log_lezen ON public.voorraad_koppel_log;
|
|
12943
13481
|
CREATE POLICY voorraad_koppel_log_lezen ON public.voorraad_koppel_log AS PERMISSIVE FOR SELECT TO authenticated USING (true);
|
|
12944
13482
|
DROP POLICY IF EXISTS voorraad_koppel_twijfel_lezen ON public.voorraad_koppel_twijfel;
|
|
@@ -12951,6 +13489,12 @@ DROP POLICY IF EXISTS "Ingelogde gebruikers kunnen de eventlog lezen" ON public.
|
|
|
12951
13489
|
CREATE POLICY "Ingelogde gebruikers kunnen de eventlog lezen" ON public.voorraad_logistics_event_log AS PERMISSIVE FOR SELECT TO authenticated USING (true);
|
|
12952
13490
|
DROP POLICY IF EXISTS "service role only" ON public.voorraad_media_upload_failures;
|
|
12953
13491
|
CREATE POLICY "service role only" ON public.voorraad_media_upload_failures AS PERMISSIVE FOR ALL TO service_role USING (true) WITH CHECK (true);
|
|
13492
|
+
DROP POLICY IF EXISTS "Ingelogd lezen" ON public.voorraad_order_terugdraaiing;
|
|
13493
|
+
CREATE POLICY "Ingelogd lezen" ON public.voorraad_order_terugdraaiing AS PERMISSIVE FOR SELECT TO authenticated USING (true);
|
|
13494
|
+
DROP POLICY IF EXISTS "Ingelogd lezen" ON public.voorraad_orderregel_afboeking;
|
|
13495
|
+
CREATE POLICY "Ingelogd lezen" ON public.voorraad_orderregel_afboeking AS PERMISSIVE FOR SELECT TO authenticated USING (true);
|
|
13496
|
+
DROP POLICY IF EXISTS "Ingelogd lezen" ON public.voorraad_orderregel_verzending;
|
|
13497
|
+
CREATE POLICY "Ingelogd lezen" ON public.voorraad_orderregel_verzending AS PERMISSIVE FOR SELECT TO authenticated USING (true);
|
|
12954
13498
|
DROP POLICY IF EXISTS "Ingelogd mag invulteksten lezen" ON public.voorraad_placeholder_codes;
|
|
12955
13499
|
CREATE POLICY "Ingelogd mag invulteksten lezen" ON public.voorraad_placeholder_codes AS PERMISSIVE FOR SELECT TO authenticated USING (true);
|
|
12956
13500
|
DROP POLICY IF EXISTS "Users can insert own publish attempts" ON public.voorraad_publish_attempts;
|
|
@@ -13026,12 +13570,14 @@ DO $g$ BEGIN IF to_regclass('public.order_items') IS NULL THEN RAISE NOTICE 'Voo
|
|
|
13026
13570
|
DO $g$ BEGIN IF to_regclass('public.order_items') IS NULL THEN RAISE NOTICE 'Voorraad: order_items (Verkoop) ontbreekt, triggers overgeslagen; draai de schema-update opnieuw na die module'; ELSE EXECUTE $q$DROP TRIGGER IF EXISTS trg_order_items_fusten_aid ON public.order_items$q$; EXECUTE $q$CREATE TRIGGER trg_order_items_fusten_aid AFTER INSERT OR DELETE ON public.order_items FOR EACH ROW EXECUTE FUNCTION trg_order_items_fusten()$q$; END IF; END $g$;
|
|
13027
13571
|
DO $g$ BEGIN IF to_regclass('public.order_items') IS NULL THEN RAISE NOTICE 'Voorraad: order_items (Verkoop) ontbreekt, triggers overgeslagen; draai de schema-update opnieuw na die module'; ELSE EXECUTE $q$DROP TRIGGER IF EXISTS trg_order_items_fusten_au ON public.order_items$q$; EXECUTE $q$CREATE TRIGGER trg_order_items_fusten_au AFTER UPDATE OF quantity, product_id, plants_per_crate, quantity_crates, vbn_package_code, packing_source, quarantined_at ON public.order_items FOR EACH ROW WHEN (((old.quantity IS DISTINCT FROM new.quantity) OR (old.product_id IS DISTINCT FROM new.product_id) OR (old.plants_per_crate IS DISTINCT FROM new.plants_per_crate) OR (old.quantity_crates IS DISTINCT FROM new.quantity_crates) OR (old.vbn_package_code IS DISTINCT FROM new.vbn_package_code) OR (old.packing_source IS DISTINCT FROM new.packing_source) OR ((old.quarantined_at IS NULL) IS DISTINCT FROM (new.quarantined_at IS NULL)))) EXECUTE FUNCTION trg_order_items_fusten()$q$; END IF; END $g$;
|
|
13028
13572
|
DO $g$ BEGIN IF to_regclass('public.order_items') IS NULL THEN RAISE NOTICE 'Voorraad: order_items (Verkoop) ontbreekt, triggers overgeslagen; draai de schema-update opnieuw na die module'; ELSE EXECUTE $q$DROP TRIGGER IF EXISTS trg_order_items_reserve ON public.order_items$q$; EXECUTE $q$CREATE TRIGGER trg_order_items_reserve AFTER INSERT OR DELETE OR UPDATE OF quantity, product_id, order_id, quarantined_at, source_line_key ON public.order_items FOR EACH ROW EXECUTE FUNCTION trg_order_items_reserve_fn()$q$; END IF; END $g$;
|
|
13573
|
+
DO $g$ BEGIN IF to_regclass('public.order_items') IS NULL THEN RAISE NOTICE 'Voorraad: order_items (Verkoop) ontbreekt, triggers overgeslagen; draai de schema-update opnieuw na die module'; ELSE EXECUTE $q$DROP TRIGGER IF EXISTS zz_voorraad_floriday_mutaties_items ON public.order_items$q$; EXECUTE $q$CREATE TRIGGER zz_voorraad_floriday_mutaties_items AFTER INSERT OR DELETE OR UPDATE OF quantity, product_id, quarantined_at ON public.order_items FOR EACH ROW EXECUTE FUNCTION voorraad_floriday_mutaties_trg()$q$; END IF; END $g$;
|
|
13029
13574
|
DO $g$ BEGIN IF to_regclass('public.orders') IS NULL THEN RAISE NOTICE 'Voorraad: orders (Verkoop) ontbreekt, triggers overgeslagen; draai de schema-update opnieuw na die module'; ELSE EXECUTE $q$DROP TRIGGER IF EXISTS trg_orders_cancel_release ON public.orders$q$; EXECUTE $q$CREATE TRIGGER trg_orders_cancel_release AFTER UPDATE OF status ON public.orders FOR EACH ROW EXECUTE FUNCTION trg_orders_cancel_release_fn()$q$; END IF; END $g$;
|
|
13030
13575
|
DO $g$ BEGIN IF to_regclass('public.orders') IS NULL THEN RAISE NOTICE 'Voorraad: orders (Verkoop) ontbreekt, triggers overgeslagen; draai de schema-update opnieuw na die module'; ELSE EXECUTE $q$DROP TRIGGER IF EXISTS trg_orders_consume_on_complete ON public.orders$q$; EXECUTE $q$CREATE TRIGGER trg_orders_consume_on_complete AFTER UPDATE OF status ON public.orders FOR EACH ROW EXECUTE FUNCTION trg_orders_consume_on_complete_fn()$q$; END IF; END $g$;
|
|
13031
13576
|
DO $g$ BEGIN IF to_regclass('public.orders') IS NULL THEN RAISE NOTICE 'Voorraad: orders (Verkoop) ontbreekt, triggers overgeslagen; draai de schema-update opnieuw na die module'; ELSE EXECUTE $q$DROP TRIGGER IF EXISTS trg_orders_default_phase ON public.orders$q$; EXECUTE $q$CREATE TRIGGER trg_orders_default_phase BEFORE INSERT ON public.orders FOR EACH ROW EXECUTE FUNCTION trg_orders_default_phase_fn()$q$; END IF; END $g$;
|
|
13032
13577
|
DO $g$ BEGIN IF to_regclass('public.orders') IS NULL THEN RAISE NOTICE 'Voorraad: orders (Verkoop) ontbreekt, triggers overgeslagen; draai de schema-update opnieuw na die module'; ELSE EXECUTE $q$DROP TRIGGER IF EXISTS trg_orders_external_fulfilled ON public.orders$q$; EXECUTE $q$CREATE TRIGGER trg_orders_external_fulfilled AFTER UPDATE OF custom_fields ON public.orders FOR EACH ROW EXECUTE FUNCTION trg_orders_external_fulfilled_fn()$q$; END IF; END $g$;
|
|
13033
13578
|
DO $g$ BEGIN IF to_regclass('public.orders') IS NULL THEN RAISE NOTICE 'Voorraad: orders (Verkoop) ontbreekt, triggers overgeslagen; draai de schema-update opnieuw na die module'; ELSE EXECUTE $q$DROP TRIGGER IF EXISTS trg_orders_fusten_au ON public.orders$q$; EXECUTE $q$CREATE TRIGGER trg_orders_fusten_au AFTER UPDATE OF status, cancelled_at, deleted_at ON public.orders FOR EACH ROW WHEN (((old.status IS DISTINCT FROM new.status) OR (old.cancelled_at IS DISTINCT FROM new.cancelled_at) OR (old.deleted_at IS DISTINCT FROM new.deleted_at))) EXECUTE FUNCTION trg_orders_fusten()$q$; END IF; END $g$;
|
|
13034
13579
|
DO $g$ BEGIN IF to_regclass('public.orders') IS NULL THEN RAISE NOTICE 'Voorraad: orders (Verkoop) ontbreekt, triggers overgeslagen; draai de schema-update opnieuw na die module'; ELSE EXECUTE $q$DROP TRIGGER IF EXISTS trg_orders_recompute_reserved ON public.orders$q$; EXECUTE $q$CREATE TRIGGER trg_orders_recompute_reserved AFTER DELETE OR UPDATE ON public.orders FOR EACH ROW EXECUTE FUNCTION trg_orders_recompute_reserved_fn()$q$; END IF; END $g$;
|
|
13580
|
+
DO $g$ BEGIN IF to_regclass('public.orders') IS NULL THEN RAISE NOTICE 'Voorraad: orders (Verkoop) ontbreekt, triggers overgeslagen; draai de schema-update opnieuw na die module'; ELSE EXECUTE $q$DROP TRIGGER IF EXISTS zz_voorraad_floriday_mutaties_orders ON public.orders$q$; EXECUTE $q$CREATE TRIGGER zz_voorraad_floriday_mutaties_orders AFTER DELETE OR UPDATE OF status, deleted_at, cancelled_at, order_source ON public.orders FOR EACH ROW EXECUTE FUNCTION voorraad_floriday_mutaties_trg()$q$; END IF; END $g$;
|
|
13035
13581
|
DO $g$ BEGIN IF to_regclass('public.product_bom_items') IS NULL THEN RAISE NOTICE 'Voorraad: product_bom_items (core) ontbreekt, triggers overgeslagen; draai de schema-update opnieuw na die module'; ELSE EXECUTE $q$DROP TRIGGER IF EXISTS set_product_bom_tenant_trigger ON public.product_bom_items$q$; EXECUTE $q$CREATE TRIGGER set_product_bom_tenant_trigger BEFORE INSERT ON public.product_bom_items FOR EACH ROW EXECUTE FUNCTION set_product_bom_tenant()$q$; END IF; END $g$;
|
|
13036
13582
|
DO $g$ BEGIN IF to_regclass('public.product_bom_items') IS NULL THEN RAISE NOTICE 'Voorraad: product_bom_items (core) ontbreekt, triggers overgeslagen; draai de schema-update opnieuw na die module'; ELSE EXECUTE $q$DROP TRIGGER IF EXISTS trg_check_product_structure ON public.product_bom_items$q$; EXECUTE $q$CREATE TRIGGER trg_check_product_structure BEFORE INSERT OR UPDATE ON public.product_bom_items FOR EACH ROW EXECUTE FUNCTION trg_check_product_structure()$q$; END IF; END $g$;
|
|
13037
13583
|
DO $g$ BEGIN IF to_regclass('public.product_bom_items') IS NULL THEN RAISE NOTICE 'Voorraad: product_bom_items (core) ontbreekt, triggers overgeslagen; draai de schema-update opnieuw na die module'; ELSE EXECUTE $q$DROP TRIGGER IF EXISTS trg_structure_change_recompute ON public.product_bom_items$q$; EXECUTE $q$CREATE TRIGGER trg_structure_change_recompute AFTER INSERT OR DELETE OR UPDATE ON public.product_bom_items FOR EACH ROW EXECUTE FUNCTION trg_structure_change_recompute()$q$; END IF; END $g$;
|
|
@@ -13047,6 +13593,8 @@ DROP TRIGGER IF EXISTS product_packings_updated_at ON public.product_packings;
|
|
|
13047
13593
|
CREATE TRIGGER product_packings_updated_at BEFORE UPDATE ON public.product_packings FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
13048
13594
|
DROP TRIGGER IF EXISTS trg_product_tray_stickers_touch ON public.product_tray_stickers;
|
|
13049
13595
|
CREATE TRIGGER trg_product_tray_stickers_touch BEFORE UPDATE ON public.product_tray_stickers FOR EACH ROW EXECUTE FUNCTION product_tray_stickers_touch();
|
|
13596
|
+
DROP TRIGGER IF EXISTS trg_productie_orders_updated_at ON public.productie_orders;
|
|
13597
|
+
CREATE TRIGGER trg_productie_orders_updated_at BEFORE UPDATE ON public.productie_orders FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
13050
13598
|
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$DROP TRIGGER IF EXISTS trg_floriday_ensure_inventory_settings ON public.products$q$; EXECUTE $q$CREATE TRIGGER trg_floriday_ensure_inventory_settings AFTER INSERT ON public.products FOR EACH ROW EXECUTE FUNCTION floriday_ensure_inventory_settings()$q$; END IF; END $g$;
|
|
13051
13599
|
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$DROP TRIGGER IF EXISTS trg_products_autolink ON public.products$q$; EXECUTE $q$CREATE TRIGGER trg_products_autolink BEFORE INSERT OR UPDATE OF product, trade_item_key ON public.products FOR EACH ROW EXECUTE FUNCTION trg_products_autolink_fn()$q$; END IF; END $g$;
|
|
13052
13600
|
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$DROP TRIGGER IF EXISTS trg_products_floriday_link_enqueue ON public.products$q$; 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$;
|
|
@@ -13067,6 +13615,8 @@ DROP TRIGGER IF EXISTS update_trade_item_drafts_updated_at ON public.trade_item_
|
|
|
13067
13615
|
CREATE TRIGGER update_trade_item_drafts_updated_at BEFORE UPDATE ON public.trade_item_drafts FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
13068
13616
|
DROP TRIGGER IF EXISTS trade_item_prices_set_updated_at ON public.trade_item_prices;
|
|
13069
13617
|
CREATE TRIGGER trade_item_prices_set_updated_at BEFORE UPDATE ON public.trade_item_prices FOR EACH ROW EXECUTE FUNCTION trade_item_prices_touch_updated_at();
|
|
13618
|
+
DROP TRIGGER IF EXISTS aa_voorraad_reservering_extra ON public.trade_item_stock;
|
|
13619
|
+
CREATE TRIGGER aa_voorraad_reservering_extra BEFORE UPDATE OF reserved_stock ON public.trade_item_stock FOR EACH ROW EXECUTE FUNCTION voorraad_reservering_extra_trg();
|
|
13070
13620
|
DROP TRIGGER IF EXISTS trg_floriday_stock_change_recompute ON public.trade_item_stock;
|
|
13071
13621
|
CREATE TRIGGER trg_floriday_stock_change_recompute AFTER INSERT OR UPDATE ON public.trade_item_stock FOR EACH ROW EXECUTE FUNCTION floriday_stock_change_recompute();
|
|
13072
13622
|
DROP TRIGGER IF EXISTS trg_stock_structure_recompute_ins ON public.trade_item_stock;
|
|
@@ -13103,6 +13653,8 @@ DROP TRIGGER IF EXISTS trg_voorraad_buffer_state_updated_at ON public.voorraad_b
|
|
|
13103
13653
|
CREATE TRIGGER trg_voorraad_buffer_state_updated_at BEFORE UPDATE ON public.voorraad_buffer_state FOR EACH ROW EXECUTE FUNCTION voorraad_touch_updated_at();
|
|
13104
13654
|
DROP TRIGGER IF EXISTS update_voorraad_custom_fields_updated_at ON public.voorraad_custom_fields;
|
|
13105
13655
|
CREATE TRIGGER update_voorraad_custom_fields_updated_at BEFORE UPDATE ON public.voorraad_custom_fields FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
13656
|
+
DROP TRIGGER IF EXISTS trg_voorraad_floriday_mutaties_updated_at ON public.voorraad_floriday_mutaties;
|
|
13657
|
+
CREATE TRIGGER trg_voorraad_floriday_mutaties_updated_at BEFORE UPDATE ON public.voorraad_floriday_mutaties FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
|
13106
13658
|
DROP TRIGGER IF EXISTS voorraad_floriday_vervallen_touch ON public.voorraad_floriday_vervallen;
|
|
13107
13659
|
CREATE TRIGGER voorraad_floriday_vervallen_touch BEFORE UPDATE ON public.voorraad_floriday_vervallen FOR EACH ROW EXECUTE FUNCTION voorraad_touch_updated_at();
|
|
13108
13660
|
DROP TRIGGER IF EXISTS trg_voorraad_event_log_updated_at ON public.voorraad_logistics_event_log;
|