@flowselections/floriday-voorraad 1.0.108 → 1.0.113
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/voorraad/FustenPage.d.ts.map +1 -1
- package/dist-lib/components/voorraad/FustenPage.js +10 -6
- package/dist-lib/components/voorraad/PriceStatusBadge.d.ts.map +1 -1
- package/dist-lib/components/voorraad/PriceStatusBadge.js +6 -1
- package/dist-lib/components/voorraad/VoorraadPage.d.ts.map +1 -1
- package/dist-lib/components/voorraad/VoorraadPage.js +8 -37
- package/dist-lib/hooks/useNoPriceProducts.d.ts +10 -0
- package/dist-lib/hooks/useNoPriceProducts.d.ts.map +1 -0
- package/dist-lib/hooks/useNoPriceProducts.js +56 -0
- package/dist-lib/hooks/useStockPushJobs.d.ts.map +1 -1
- package/dist-lib/hooks/useStockPushJobs.js +6 -1
- package/dist-lib/hooks/useStockSyncHealth.d.ts.map +1 -1
- package/dist-lib/hooks/useStockSyncHealth.js +2 -9
- package/dist-lib/hooks/useVoorraadData.d.ts.map +1 -1
- package/dist-lib/hooks/useVoorraadData.js +45 -24
- package/dist-lib/integrations/supabase/types.d.ts +1049 -122
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/integrations/supabase/types.js +1 -0
- package/dist-lib/lib/__tests__/fust-dimensions.test.d.ts +2 -0
- package/dist-lib/lib/__tests__/fust-dimensions.test.d.ts.map +1 -0
- package/dist-lib/lib/__tests__/fust-dimensions.test.js +27 -0
- package/dist-lib/lib/__tests__/request-guard.test.d.ts +2 -0
- package/dist-lib/lib/__tests__/request-guard.test.d.ts.map +1 -0
- package/dist-lib/lib/__tests__/request-guard.test.js +50 -0
- package/dist-lib/lib/fusten.d.ts +14 -3
- package/dist-lib/lib/fusten.d.ts.map +1 -1
- package/dist-lib/lib/fusten.js +38 -7
- package/dist-lib/lib/request-guard.d.ts +46 -0
- package/dist-lib/lib/request-guard.d.ts.map +1 -0
- package/dist-lib/lib/request-guard.js +100 -0
- package/package.json +1 -1
- package/sql/floriday-voorraad-schema.sql +343 -28
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
-- @flowselections/floriday-voorraad 1.0.
|
|
1
|
+
-- @flowselections/floriday-voorraad 1.0.112 – volledig schema (idempotent, geen gegevens).
|
|
2
2
|
-- Gegenereerd uit de database met scripts/generate-voorraad-schema.py. Niet met de hand wijzigen.
|
|
3
3
|
-- Volgorde 20. Ontbrekende tabellen van andere modules worden overgeslagen met een NOTICE; draai opnieuw na die module.
|
|
4
4
|
-- De statuscontrole van floriday_continuous_stock_queue is van Voorraad en wordt hier opnieuw gemaakt.
|
|
@@ -209,6 +209,7 @@ ALTER TABLE public.fust_types ADD COLUMN IF NOT EXISTS length_mm integer;
|
|
|
209
209
|
ALTER TABLE public.fust_types ADD COLUMN IF NOT EXISTS width_mm integer;
|
|
210
210
|
ALTER TABLE public.fust_types ADD COLUMN IF NOT EXISTS height_mm integer;
|
|
211
211
|
ALTER TABLE public.fust_types ADD COLUMN IF NOT EXISTS capacity_units integer;
|
|
212
|
+
ALTER TABLE public.fust_types ADD COLUMN IF NOT EXISTS merged_into uuid;
|
|
212
213
|
|
|
213
214
|
-- inventory_recompute_limits
|
|
214
215
|
CREATE TABLE IF NOT EXISTS public.inventory_recompute_limits ();
|
|
@@ -2504,6 +2505,7 @@ $function$
|
|
|
2504
2505
|
;
|
|
2505
2506
|
REVOKE ALL ON FUNCTION ensure_trade_item_stock_row_key(text) FROM PUBLIC;
|
|
2506
2507
|
REVOKE ALL ON FUNCTION ensure_trade_item_stock_row_key(text) FROM anon;
|
|
2508
|
+
GRANT EXECUTE ON FUNCTION ensure_trade_item_stock_row_key(text) TO authenticated;
|
|
2507
2509
|
GRANT EXECUTE ON FUNCTION ensure_trade_item_stock_row_key(text) TO service_role;
|
|
2508
2510
|
CREATE OR REPLACE FUNCTION public.ensure_voorraad_local_context()
|
|
2509
2511
|
RETURNS uuid
|
|
@@ -4075,9 +4077,10 @@ CREATE OR REPLACE FUNCTION public.fust_types_duplicate_guard()
|
|
|
4075
4077
|
SET search_path TO 'public'
|
|
4076
4078
|
AS $function$
|
|
4077
4079
|
BEGIN
|
|
4078
|
-
IF EXISTS (SELECT 1 FROM public.fust_types f
|
|
4080
|
+
IF NEW.merged_into IS NULL AND EXISTS (SELECT 1 FROM public.fust_types f
|
|
4079
4081
|
WHERE f.fust_key = NEW.fust_key
|
|
4080
4082
|
AND f.connection_id IS NOT DISTINCT FROM NEW.connection_id
|
|
4083
|
+
AND f.merged_into IS NULL
|
|
4081
4084
|
AND f.id <> NEW.id) THEN
|
|
4082
4085
|
RAISE EXCEPTION 'Dit fusttype bestaat al (fustcode %).', NEW.fust_key USING ERRCODE = '23505';
|
|
4083
4086
|
END IF;
|
|
@@ -4279,7 +4282,9 @@ BEGIN
|
|
|
4279
4282
|
SELECT l.created_by INTO v_user FROM public.voorraad_local_context l WHERE l.id = v_local;
|
|
4280
4283
|
END IF;
|
|
4281
4284
|
RETURN QUERY SELECT v_local, 'lokaal'::text, v_local,
|
|
4282
|
-
COALESCE((SELECT t.user_id FROM public.trade_item_stock t WHERE t.connection_id = v_local ORDER BY t.created_at LIMIT 1), auth.uid(), v_user
|
|
4285
|
+
COALESCE((SELECT t.user_id FROM public.trade_item_stock t WHERE t.connection_id = v_local ORDER BY t.created_at LIMIT 1), auth.uid(), v_user,
|
|
4286
|
+
-- eigenaar: oudste voorraadrij van deze database (één database = één bedrijf), voor serveraanroepen zonder gebruiker
|
|
4287
|
+
(SELECT t.user_id FROM public.trade_item_stock t ORDER BY t.created_at LIMIT 1));
|
|
4283
4288
|
END $function$
|
|
4284
4289
|
;
|
|
4285
4290
|
REVOKE ALL ON FUNCTION get_stock_context(boolean) FROM PUBLIC;
|
|
@@ -7736,6 +7741,92 @@ END $function$
|
|
|
7736
7741
|
REVOKE ALL ON FUNCTION voorraad_alert_floriday_not_updated(text,numeric,uuid,uuid) FROM PUBLIC;
|
|
7737
7742
|
REVOKE ALL ON FUNCTION voorraad_alert_floriday_not_updated(text,numeric,uuid,uuid) FROM anon;
|
|
7738
7743
|
GRANT EXECUTE ON FUNCTION voorraad_alert_floriday_not_updated(text,numeric,uuid,uuid) TO service_role;
|
|
7744
|
+
CREATE OR REPLACE FUNCTION public.voorraad_article_vbn(p_product_id uuid)
|
|
7745
|
+
RETURNS jsonb
|
|
7746
|
+
LANGUAGE plpgsql
|
|
7747
|
+
STABLE SECURITY DEFINER
|
|
7748
|
+
SET search_path TO 'public'
|
|
7749
|
+
AS $function$
|
|
7750
|
+
-- Leesfunctie voor de Engine: VBN-kenmerken en gekozen fust van één artikel, live gelezen, met bron.
|
|
7751
|
+
-- Volgorde: handmatige afwijking op products (plant_height_cm, fust_type_id) → lokale wizardgegevens
|
|
7752
|
+
-- (custom_fields.floriday_payload, als niet gekoppeld of nog niet doorgegeven) → Floriday-cache → lokale wizardgegevens.
|
|
7753
|
+
DECLARE
|
|
7754
|
+
v_p record; v_pl jsonb; v_cache jsonb; v_dirty boolean; v_src text;
|
|
7755
|
+
v_feat jsonb := '{}'::jsonb; v_vbn text; v_pack jsonb; v_fust_code text; v_fust_custom text;
|
|
7756
|
+
v_s02 text; v_s02_src text; v_fust jsonb; v_fust_src text; v_ft uuid;
|
|
7757
|
+
BEGIN
|
|
7758
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_article_vbn');
|
|
7759
|
+
SELECT id, custom_fields, floriday_trade_item_id, plant_height_cm, fust_type_id INTO v_p
|
|
7760
|
+
FROM public.products WHERE id = p_product_id;
|
|
7761
|
+
IF NOT FOUND THEN RETURN jsonb_build_object('ok', false, 'reason', 'Artikel niet gevonden'); END IF;
|
|
7762
|
+
|
|
7763
|
+
v_pl := v_p.custom_fields->'floriday_payload';
|
|
7764
|
+
v_dirty := COALESCE((v_p.custom_fields->'floriday_sync'->>'dirty')::boolean, false);
|
|
7765
|
+
IF v_p.floriday_trade_item_id IS NOT NULL THEN
|
|
7766
|
+
SELECT c.data INTO v_cache FROM public.floriday_trade_items_cache c
|
|
7767
|
+
WHERE c.floriday_id = v_p.floriday_trade_item_id::text AND COALESCE(c.is_deleted,false) = false
|
|
7768
|
+
ORDER BY (c.connection_id IS NOT DISTINCT FROM (SELECT s.connection_id FROM public.get_stock_context() s)) DESC, c.fetched_at DESC NULLS LAST LIMIT 1;
|
|
7769
|
+
END IF;
|
|
7770
|
+
|
|
7771
|
+
IF v_pl IS NOT NULL AND (v_cache IS NULL OR v_dirty) THEN
|
|
7772
|
+
v_src := 'wizard';
|
|
7773
|
+
v_vbn := v_pl->>'vbnCode';
|
|
7774
|
+
v_feat := COALESCE(v_pl->'features', '{}'::jsonb);
|
|
7775
|
+
SELECT e INTO v_pack FROM jsonb_array_elements(COALESCE(v_pl->'packingConfigurations','[]')) e
|
|
7776
|
+
ORDER BY (COALESCE((e->>'isPrimary')::boolean,(e->>'primary')::boolean,false)) DESC LIMIT 1;
|
|
7777
|
+
IF v_pack IS NOT NULL THEN
|
|
7778
|
+
IF upper(COALESCE(v_pack->>'source','VBN')) = 'VBN' THEN v_fust_code := v_pack->>'packagingType';
|
|
7779
|
+
ELSE v_fust_custom := v_pack->>'packagingType'; END IF;
|
|
7780
|
+
END IF;
|
|
7781
|
+
ELSIF v_cache IS NOT NULL THEN
|
|
7782
|
+
v_src := 'floriday';
|
|
7783
|
+
v_vbn := COALESCE(v_cache->>'vbnProductCode', v_cache->>'vbnCode');
|
|
7784
|
+
SELECT COALESCE(jsonb_object_agg(e->>'vbnCode', e->>'vbnValueCode'), '{}'::jsonb) INTO v_feat
|
|
7785
|
+
FROM jsonb_array_elements(CASE WHEN jsonb_typeof(v_cache->'characteristics')='array' THEN v_cache->'characteristics' ELSE '[]' END) e
|
|
7786
|
+
WHERE e->>'vbnCode' IS NOT NULL;
|
|
7787
|
+
SELECT e INTO v_pack FROM jsonb_array_elements(CASE WHEN jsonb_typeof(v_cache->'packingConfigurations')='array' THEN v_cache->'packingConfigurations' ELSE '[]' END) e
|
|
7788
|
+
ORDER BY (COALESCE((e->>'primary')::boolean,(e->>'isPrimary')::boolean,false)) DESC LIMIT 1;
|
|
7789
|
+
IF v_pack IS NOT NULL THEN
|
|
7790
|
+
v_fust_code := v_pack->'package'->>'vbnPackageCode';
|
|
7791
|
+
v_fust_custom := v_pack->'package'->>'customPackageId';
|
|
7792
|
+
END IF;
|
|
7793
|
+
ELSE
|
|
7794
|
+
v_src := 'onbekend';
|
|
7795
|
+
END IF;
|
|
7796
|
+
|
|
7797
|
+
-- S02 (planthoogte inclusief pot)
|
|
7798
|
+
IF v_p.plant_height_cm IS NOT NULL THEN v_s02 := v_p.plant_height_cm::text; v_s02_src := 'handmatig';
|
|
7799
|
+
ELSIF v_feat ? 'S02' THEN v_s02 := v_feat->>'S02'; v_s02_src := v_src;
|
|
7800
|
+
END IF;
|
|
7801
|
+
|
|
7802
|
+
-- Fust
|
|
7803
|
+
IF v_p.fust_type_id IS NOT NULL THEN v_ft := v_p.fust_type_id; v_fust_src := 'handmatig';
|
|
7804
|
+
ELSIF v_fust_code IS NOT NULL OR v_fust_custom IS NOT NULL THEN
|
|
7805
|
+
SELECT f.id INTO v_ft FROM public.fust_types f
|
|
7806
|
+
WHERE f.connection_id IS NULL
|
|
7807
|
+
AND ((v_fust_code IS NOT NULL AND f.fust_key = 'vbn:' || v_fust_code)
|
|
7808
|
+
OR (v_fust_custom IS NOT NULL AND f.custom_package_id = v_fust_custom))
|
|
7809
|
+
ORDER BY f.created_at, f.id LIMIT 1;
|
|
7810
|
+
v_fust_src := v_src;
|
|
7811
|
+
END IF;
|
|
7812
|
+
IF v_ft IS NOT NULL THEN
|
|
7813
|
+
SELECT to_jsonb(d) INTO v_fust FROM public.voorraad_fust_dimensions() d WHERE d.fust_type_id = v_ft;
|
|
7814
|
+
END IF;
|
|
7815
|
+
IF v_fust IS NULL AND (v_fust_code IS NOT NULL OR v_fust_custom IS NOT NULL) THEN
|
|
7816
|
+
v_fust := jsonb_build_object('vbn_code', v_fust_code, 'custom_package_id', v_fust_custom, 'fust_type_id', NULL);
|
|
7817
|
+
END IF;
|
|
7818
|
+
|
|
7819
|
+
RETURN jsonb_build_object(
|
|
7820
|
+
'ok', true, 'product_id', v_p.id, 'source', v_src, 'vbn_code', v_vbn,
|
|
7821
|
+
'features', v_feat,
|
|
7822
|
+
's02', v_s02, 's02_source', v_s02_src,
|
|
7823
|
+
'fust', v_fust, 'fust_source', v_fust_src);
|
|
7824
|
+
END $function$
|
|
7825
|
+
;
|
|
7826
|
+
REVOKE ALL ON FUNCTION voorraad_article_vbn(uuid) FROM PUBLIC;
|
|
7827
|
+
REVOKE ALL ON FUNCTION voorraad_article_vbn(uuid) FROM anon;
|
|
7828
|
+
GRANT EXECUTE ON FUNCTION voorraad_article_vbn(uuid) TO authenticated;
|
|
7829
|
+
GRANT EXECUTE ON FUNCTION voorraad_article_vbn(uuid) TO service_role;
|
|
7739
7830
|
CREATE OR REPLACE FUNCTION public.voorraad_can_write()
|
|
7740
7831
|
RETURNS boolean
|
|
7741
7832
|
LANGUAGE sql
|
|
@@ -7974,6 +8065,66 @@ REVOKE ALL ON FUNCTION voorraad_correctie_1098(boolean) FROM PUBLIC;
|
|
|
7974
8065
|
REVOKE ALL ON FUNCTION voorraad_correctie_1098(boolean) FROM anon;
|
|
7975
8066
|
GRANT EXECUTE ON FUNCTION voorraad_correctie_1098(boolean) TO authenticated;
|
|
7976
8067
|
GRANT EXECUTE ON FUNCTION voorraad_correctie_1098(boolean) TO service_role;
|
|
8068
|
+
CREATE OR REPLACE FUNCTION public.voorraad_correctie_1112(p_uitvoeren boolean DEFAULT false)
|
|
8069
|
+
RETURNS jsonb
|
|
8070
|
+
LANGUAGE plpgsql
|
|
8071
|
+
SECURITY DEFINER
|
|
8072
|
+
SET search_path TO 'public'
|
|
8073
|
+
AS $function$
|
|
8074
|
+
-- Samenvoegen dubbele fusttypen (zelfde fust_key, connection_id NULL, niet samengevoegd).
|
|
8075
|
+
-- Per fust_key: bewaar de rij met de meeste mutaties; maten aanvullen; minimum = hoogste;
|
|
8076
|
+
-- mutaties overzetten op id; voorraad optellen; andere rij in_use=false, stock 0, merged_into = bewaarde rij. Nooit verwijderen.
|
|
8077
|
+
DECLARE v jsonb; v_keep record; v_oth record; v_moved int; v_total int := 0;
|
|
8078
|
+
BEGIN
|
|
8079
|
+
PERFORM public.voorraad_vereis('server', 'voorraad_correctie_1112');
|
|
8080
|
+
WITH m AS (
|
|
8081
|
+
SELECT f.*, (SELECT count(*) FROM public.fust_stock_mutations x WHERE x.fust_type_id = f.id) AS muts,
|
|
8082
|
+
count(*) OVER (PARTITION BY f.fust_key) AS n
|
|
8083
|
+
FROM public.fust_types f WHERE f.connection_id IS NULL AND f.merged_into IS NULL
|
|
8084
|
+
), q AS (
|
|
8085
|
+
SELECT m.*, row_number() OVER (PARTITION BY fust_key ORDER BY muts DESC, created_at, id) AS rn FROM m WHERE n > 1
|
|
8086
|
+
)
|
|
8087
|
+
SELECT COALESCE(jsonb_agg(jsonb_build_object(
|
|
8088
|
+
'fust_key', k.fust_key, 'naam', btrim(k.name),
|
|
8089
|
+
'bewaren', jsonb_build_object('id', k.id, 'mutaties', k.muts, 'voorraad', k.stock),
|
|
8090
|
+
'samenvoegen', (SELECT jsonb_agg(jsonb_build_object('id', q2.id, 'mutaties', q2.muts, 'voorraad', q2.stock)) FROM q q2 WHERE q2.fust_key = k.fust_key AND q2.rn > 1),
|
|
8091
|
+
'na_samenvoegen', jsonb_build_object(
|
|
8092
|
+
'voorraad', (SELECT sum(q3.stock) FROM q q3 WHERE q3.fust_key = k.fust_key),
|
|
8093
|
+
'mutaties', (SELECT sum(q4.muts) FROM q q4 WHERE q4.fust_key = k.fust_key))
|
|
8094
|
+
) ORDER BY k.name), '[]'::jsonb) INTO v
|
|
8095
|
+
FROM q k WHERE k.rn = 1;
|
|
8096
|
+
|
|
8097
|
+
IF p_uitvoeren THEN
|
|
8098
|
+
FOR v_keep IN SELECT (e->'bewaren'->>'id')::uuid AS keep_id, e->'samenvoegen' AS others FROM jsonb_array_elements(v) e LOOP
|
|
8099
|
+
PERFORM 1 FROM public.fust_types f WHERE f.id = v_keep.keep_id FOR UPDATE;
|
|
8100
|
+
FOR v_oth IN SELECT f.* FROM public.fust_types f
|
|
8101
|
+
WHERE f.id IN (SELECT (x->>'id')::uuid FROM jsonb_array_elements(v_keep.others) x)
|
|
8102
|
+
ORDER BY f.id FOR UPDATE LOOP
|
|
8103
|
+
UPDATE public.fust_stock_mutations SET fust_type_id = v_keep.keep_id WHERE fust_type_id = v_oth.id;
|
|
8104
|
+
GET DIAGNOSTICS v_moved = ROW_COUNT; v_total := v_total + v_moved;
|
|
8105
|
+
UPDATE public.fust_types k SET
|
|
8106
|
+
stock = k.stock + v_oth.stock,
|
|
8107
|
+
minimum_stock = GREATEST(k.minimum_stock, v_oth.minimum_stock),
|
|
8108
|
+
length_mm = COALESCE(k.length_mm, v_oth.length_mm),
|
|
8109
|
+
width_mm = COALESCE(k.width_mm, v_oth.width_mm),
|
|
8110
|
+
height_mm = COALESCE(k.height_mm, v_oth.height_mm),
|
|
8111
|
+
notes = COALESCE(k.notes, v_oth.notes)
|
|
8112
|
+
WHERE k.id = v_keep.keep_id;
|
|
8113
|
+
UPDATE public.fust_types SET stock = 0, in_use = false, used_by_count = 0, merged_into = v_keep.keep_id
|
|
8114
|
+
WHERE id = v_oth.id;
|
|
8115
|
+
END LOOP;
|
|
8116
|
+
END LOOP;
|
|
8117
|
+
END IF;
|
|
8118
|
+
|
|
8119
|
+
INSERT INTO public.voorraad_correcties(correctie, uitgevoerd_door, proef, aantallen, hash_ok)
|
|
8120
|
+
VALUES ('voorraad_correctie_1112', COALESCE(auth.uid()::text, session_user::text), NOT p_uitvoeren,
|
|
8121
|
+
jsonb_build_object('fusttypen', jsonb_array_length(v), 'mutaties_overgezet', v_total), true);
|
|
8122
|
+
RETURN jsonb_build_object('ok', true, 'proef', NOT p_uitvoeren, 'fusten', v, 'mutaties_overgezet', v_total);
|
|
8123
|
+
END $function$
|
|
8124
|
+
;
|
|
8125
|
+
REVOKE ALL ON FUNCTION voorraad_correctie_1112(boolean) FROM PUBLIC;
|
|
8126
|
+
REVOKE ALL ON FUNCTION voorraad_correctie_1112(boolean) FROM anon;
|
|
8127
|
+
GRANT EXECUTE ON FUNCTION voorraad_correctie_1112(boolean) TO service_role;
|
|
7977
8128
|
CREATE OR REPLACE FUNCTION public.voorraad_correctie_status(p_correctie text DEFAULT '1098'::text)
|
|
7978
8129
|
RETURNS jsonb
|
|
7979
8130
|
LANGUAGE plpgsql
|
|
@@ -8058,33 +8209,42 @@ CREATE OR REPLACE FUNCTION public.voorraad_fust_dimensions()
|
|
|
8058
8209
|
STABLE SECURITY DEFINER
|
|
8059
8210
|
SET search_path TO 'public'
|
|
8060
8211
|
AS $function$
|
|
8061
|
-
-- Leesfunctie voor de Engine:
|
|
8062
|
-
-- Maten: eerst Floricode (floricode_packaging_types, eigenaar Floriday-auth), anders handmatig ingevoerd, anders leeg (nooit standaardwaarden).
|
|
8212
|
+
-- Leesfunctie voor de Engine. Maten: Floricode → Floriday custom package (floriday_packings_cache) → handmatig → leeg (nooit standaardwaarden).
|
|
8063
8213
|
DECLARE v_fc boolean := to_regprocedure('public.floricode_packaging_types()') IS NOT NULL;
|
|
8064
8214
|
BEGIN
|
|
8065
8215
|
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_fust_dimensions');
|
|
8066
|
-
|
|
8067
|
-
|
|
8068
|
-
|
|
8069
|
-
|
|
8070
|
-
SELECT
|
|
8071
|
-
|
|
8072
|
-
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
|
|
8077
|
-
|
|
8078
|
-
|
|
8079
|
-
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
|
|
8085
|
-
|
|
8086
|
-
|
|
8087
|
-
|
|
8216
|
+
RETURN QUERY
|
|
8217
|
+
WITH fc AS (
|
|
8218
|
+
SELECT * FROM (SELECT NULL::text code, NULL::text name, NULL::numeric length_mm, NULL::numeric width_mm, NULL::numeric height_mm) z WHERE false
|
|
8219
|
+
), fcr AS (
|
|
8220
|
+
SELECT x.code, x.name, x.length_mm, x.width_mm, x.height_mm FROM fc x
|
|
8221
|
+
), cp AS (
|
|
8222
|
+
SELECT DISTINCT ON (p.floriday_id) p.floriday_id,
|
|
8223
|
+
NULLIF(COALESCE(p.data->'dimensions'->>'length', p.data->'dimension'->>'length', p.data->>'lengthMm', p.data->>'length'),'')::numeric AS l,
|
|
8224
|
+
NULLIF(COALESCE(p.data->'dimensions'->>'width', p.data->'dimension'->>'width', p.data->>'widthMm', p.data->>'width'),'')::numeric AS w,
|
|
8225
|
+
NULLIF(COALESCE(p.data->'dimensions'->>'height', p.data->'dimension'->>'height', p.data->>'heightMm', p.data->>'height'),'')::numeric AS h
|
|
8226
|
+
FROM public.floriday_packings_cache p
|
|
8227
|
+
WHERE COALESCE(p.is_deleted,false) = false
|
|
8228
|
+
ORDER BY p.floriday_id, p.updated_at DESC NULLS LAST
|
|
8229
|
+
)
|
|
8230
|
+
SELECT f.id, f.fust_key, f.vbn_code, f.name, d.fc_name,
|
|
8231
|
+
COALESCE(d.fl, cp.l, f.length_mm::numeric),
|
|
8232
|
+
COALESCE(d.fw, cp.w, f.width_mm::numeric),
|
|
8233
|
+
COALESCE(d.fh, cp.h, f.height_mm::numeric),
|
|
8234
|
+
CASE WHEN d.fl IS NOT NULL OR d.fw IS NOT NULL OR d.fh IS NOT NULL THEN 'floricode'
|
|
8235
|
+
WHEN cp.l IS NOT NULL OR cp.w IS NOT NULL OR cp.h IS NOT NULL THEN 'floriday'
|
|
8236
|
+
WHEN f.length_mm IS NOT NULL OR f.width_mm IS NOT NULL OR f.height_mm IS NOT NULL THEN 'handmatig'
|
|
8237
|
+
ELSE 'onbekend' END
|
|
8238
|
+
FROM public.fust_types f
|
|
8239
|
+
LEFT JOIN LATERAL (
|
|
8240
|
+
SELECT c.name AS fc_name, c.length_mm AS fl, c.width_mm AS fw, c.height_mm AS fh
|
|
8241
|
+
FROM public.floricode_packaging_types() c
|
|
8242
|
+
WHERE v_fc AND f.vbn_code IS NOT NULL AND c.code = f.vbn_code::text
|
|
8243
|
+
ORDER BY c.expiry_date DESC NULLS FIRST LIMIT 1
|
|
8244
|
+
) d ON v_fc
|
|
8245
|
+
LEFT JOIN cp ON f.custom_package_id IS NOT NULL AND cp.floriday_id = f.custom_package_id
|
|
8246
|
+
WHERE f.connection_id IS NULL
|
|
8247
|
+
ORDER BY f.name;
|
|
8088
8248
|
END $function$
|
|
8089
8249
|
;
|
|
8090
8250
|
REVOKE ALL ON FUNCTION voorraad_fust_dimensions() FROM PUBLIC;
|
|
@@ -8208,7 +8368,7 @@ CREATE OR REPLACE FUNCTION public.voorraad_install_check()
|
|
|
8208
8368
|
STABLE SECURITY DEFINER
|
|
8209
8369
|
SET search_path TO 'public'
|
|
8210
8370
|
AS $function$
|
|
8211
|
-
DECLARE v_f text[] := ARRAY['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'];
|
|
8371
|
+
DECLARE v_f text[] := ARRAY['voorraad_article_vbn','voorraad_correctie_1112','voorraad_reverse_order_mutations','voorraad_withdraw_stock_row','ensure_voorraad_local_context','get_stock_context','voorraad_stock_context_status','voorraad_fcsq_local_guard','_floriday_queue_cleanup_batch','_migrate_rewrite_stock_key','_stock_import_caller','apply_fust_stock_mutation','apply_stock_consumption','apply_stock_reservation','autolink_product_to_floriday','backfill_open_order_reservations','calculate_floriday_desired_stock','calculate_structure_available','canonicalize_trade_item_stock_key','check_product_structure','claim_floriday_base_supply','claim_floriday_stock_queue','cleanup_floriday_stock_queue','cleanup_voorraad_module_history','complete_floriday_base_supply','complete_floriday_stock_queue','complete_floriday_stock_queue_outcome','consume_bom_for_production','consume_order_item','drain_inventory_recompute_queue','enqueue_floriday_continuous_stock','enqueue_floriday_continuous_stock_after_warehouse_preference','enqueue_structure_recompute','ensure_inventory_recompute_drain','ensure_trade_item_stock_row','ensure_trade_item_stock_row_key','fcsq_block_disabled','fcsq_fallback_supersede','fcsq_wake_base_supply','find_trade_item_key','floriday_adopt_connection','floriday_autoheal_connections','floriday_capture_stock_snapshot','floriday_cleanup_stock_queue_v2','floriday_compact_stock_snapshots','floriday_default_owner','floriday_desired_stock_regression_check','floriday_ensure_inventory_settings','floriday_erp_leading_preview','floriday_fill_publish_horizon','floriday_follow_apply','floriday_ingest_sales_orders','floriday_leading_summary','floriday_make_erp_leading','floriday_norm_offer_forms','floriday_orphan_settings_count','floriday_publish_horizon_weeks','floriday_queue_erp_guard','floriday_queue_first_positive','floriday_recompute_inventory','floriday_relink_products','floriday_requeue_dead_letters','floriday_settings_change_recompute','floriday_settings_change_recompute_stmt','floriday_stock_change_recompute','floriday_stock_queue_supersede','floriday_takeover_apply','floriday_takeover_fetch_state','floriday_takeover_store_forms','floriday_takeover_undo','fust_negative_stock_report','fust_types_duplicate_guard','get_active_floriday_context','get_group_allocation_keys','get_group_head_key','get_product_stock','get_product_structure_totals','get_product_structure_totals_batch','inventory_inline_budget_ok','merge_products','normalize_order_source','process_inventory_recompute_queue','produce_designed_product','product_active_group_id','product_id_from_ref','product_is_set','product_label','product_member_group_ids','product_own_available','product_packings_derive','product_packings_replace','product_packings_sync_from_floriday','product_primary_pieces','product_set_depth_above','product_set_depth_below','product_structure_ancestors','product_structure_max_depth','product_structure_path','product_tray_stickers_touch','product_type','promote_trade_item_key','recompute_all_reserved_stock','recompute_order_status','recompute_reserved_for_order','recompute_reserved_stock','requeue_skipped_stock_rows','reset_stalled_floriday_stock_queue','resolve_group_allocation','resolve_group_member_stock_key','resolve_product_id_for_item','resolve_stock_trade_item_key','reverse_production','run_floriday_base_supply_process','run_floriday_continuous_stock_sync','run_floriday_follow','run_floriday_stock_queue_process','run_floriday_stock_reconcile','run_logistics_tasks_dispatch','self_heal_floriday_links','set_module_runtime_config_updated_at','set_product_bom_tenant','set_product_stock','set_updated_at_order_fust_bookings','stock_import_cleanup','stock_import_create','stock_import_process_chunk','stock_import_stop','stock_import_undo_chunk','sync_order_item_fusten','sync_products_quantity_from_stock','touch_fust_types_updated_at','trade_item_drafts_readonly','trade_item_prices_touch_updated_at','trade_item_stock_duplicates','trg_cart_numbers_sync_order_status_fn','trg_cart_session_consume_fn','trg_check_product_structure','trg_floriday_cache_relink_fn','trg_floriday_trade_items_autolink_fn','trg_order_items_autolink_fn','trg_order_items_fusten','trg_order_items_reserve_fn','trg_orders_cancel_release_fn','trg_orders_consume_on_complete_fn','trg_orders_default_phase_fn','trg_orders_external_fulfilled_fn','trg_orders_recompute_reserved_fn','trg_pgi_assign_sort_order','trg_pgi_order_taken_check','trg_process_recompute_on_commit','trg_product_packings_derive_fn','trg_products_autolink_fn','trg_products_floriday_link_enqueue','trg_products_seed_stock_fn','trg_requeue_no_warehouse_cache','trg_requeue_no_warehouse_connection','trg_requeue_no_warehouse_item_pref','trg_requeue_skipped_no_price','trg_stock_structure_recompute_ins','trg_stock_structure_recompute_upd','trg_structure_change_recompute','trg_trade_item_drafts_autolink_fn','trg_trade_item_stock_auto_bom','trg_trade_item_stock_auto_bom_reverse','trg_trade_item_stock_log_change','trg_trade_item_stock_reserve_fn','trg_trade_item_stock_zero_watch','trg_trade_items_cache_autolink_fn','update_updated_at_column','voorraad_alert_floriday_not_updated','voorraad_can_write','voorraad_cleanup_old_rows','voorraad_consume_external_fulfilled','voorraad_correctie_1098','voorraad_correctie_status','voorraad_external_fulfilled_ids','voorraad_floriday_leads_key','voorraad_fust_dimensions','voorraad_hook_base_url','voorraad_hook_on','voorraad_hook_post','voorraad_hook_switch_jobs','voorraad_install_check','voorraad_is_server','voorraad_mark_floriday_sold_before_switch','voorraad_production_enabled','voorraad_schema_ddl','voorraad_touch_updated_at','voorraad_vereis','voorraad_week_is_past'];
|
|
8212
8372
|
v_t text[] := ARRAY['aa0_fcsq_local_context_guard@floriday_continuous_stock_queue','aa_fcsq_erp_leading_guard@floriday_continuous_stock_queue','aa_fis_norm_offer_forms@floriday_inventory_settings','aa_pgi_assign_sort_order@product_group_items','fcsq_block_disabled@floriday_continuous_stock_queue','fcsq_wake_base_supply_ins@floriday_continuous_stock_queue','fcsq_wake_base_supply_upd@floriday_continuous_stock_queue','fust_stock_mutations_apply@fust_stock_mutations','fust_types_duplicate_guard@fust_types','fust_types_touch@fust_types','product_packings_derive_trg@product_packings','product_packings_updated_at@product_packings','set_product_bom_tenant_trigger@product_bom_items','trade_item_prices_set_updated_at@trade_item_prices','trg_cart_numbers_sync_order_status@cart_numbers','trg_cart_session_consume@cart_control_sessions','trg_check_product_structure@product_bom_items','trg_check_product_structure@product_group_items','trg_check_product_structure@product_groups','trg_fcs_queue_updated_at@floriday_continuous_stock_queue','trg_fcsq_fallback_supersede@floriday_continuous_stock_queue','trg_fcsq_supersede@floriday_continuous_stock_queue','trg_floriday_cache_relink@floriday_trade_items_cache','trg_floriday_ensure_inventory_settings@products','trg_floriday_gate_stock_queue@floriday_continuous_stock_queue','trg_floriday_settings_change_recompute_ins@floriday_inventory_settings','trg_floriday_settings_change_recompute_upd@floriday_inventory_settings','trg_floriday_stock_change_recompute@trade_item_stock','trg_floriday_takeover_runs_updated_at@floriday_takeover_runs','trg_floriday_trade_items_autolink@floriday_trade_items_cache','trg_fust_types_requeue_blocked@fust_types','trg_module_runtime_config_updated_at@module_runtime_config','trg_order_fust_bookings_updated_at@order_fust_bookings','trg_order_items_autolink@order_items','trg_order_items_fusten_aiud@order_items','trg_order_items_reserve@order_items','trg_orders_cancel_release@orders','trg_orders_consume_on_complete@orders','trg_orders_default_phase@orders','trg_orders_external_fulfilled@orders','trg_orders_recompute_reserved@orders','trg_prevent_duplicate_product_draft@trade_item_drafts','trg_product_tray_stickers_touch@product_tray_stickers','trg_products_autolink@products','trg_products_floriday_link_enqueue@products','trg_products_seed_stock@products','trg_requeue_no_warehouse_cache@floriday_trade_items_cache','trg_requeue_no_warehouse_connection@floriday_connections','trg_requeue_no_warehouse_item_pref@trade_item_warehouse_preferences','trg_requeue_skipped_no_price@products','trg_stock_mutation_alert@stock_mutation_log','trg_stock_structure_recompute_ins@trade_item_stock','trg_stock_structure_recompute_upd@trade_item_stock','trg_structure_change_recompute@product_bom_items','trg_structure_change_recompute@product_group_items','trg_structure_change_recompute@product_groups','trg_sync_layer_stock_from_trade_stock@trade_item_stock','trg_sync_products_quantity_from_stock_del@trade_item_stock','trg_sync_products_quantity_from_stock_iu@trade_item_stock','trg_trade_item_drafts_autolink@trade_item_drafts','trg_trade_item_drafts_readonly@trade_item_drafts','trg_trade_item_stock_canonical_key@trade_item_stock','trg_trade_item_stock_publish@trade_item_stock','trg_trade_item_stock_reserve@trade_item_stock','trg_trade_item_stock_updated_at@trade_item_stock','trg_trade_item_stock_zero_watch@trade_item_stock','trg_trade_item_supply_lines_touch@trade_item_supply_lines','trg_trade_item_warehouse_preference_enqueue_stock@trade_item_warehouse_preferences','trg_trade_items_cache_autolink@floriday_trade_items_cache','trg_voorraad_buffer_state_updated_at@voorraad_buffer_state','trg_voorraad_event_log_updated_at@voorraad_logistics_event_log','update_trade_item_drafts_updated_at@trade_item_drafts','update_trade_item_warehouse_preferences_updated_at@trade_item_warehouse_preferences','update_voorraad_custom_fields_updated_at@voorraad_custom_fields','update_voorraad_publish_jobs_updated_at@voorraad_publish_jobs','update_voorraad_publish_learnings_updated_at@voorraad_publish_learnings','update_voorraad_publish_steps_updated_at@voorraad_publish_steps','voorraad_hook_switch_jobs@module_runtime_config','zz_fcsq_first_positive@floriday_continuous_stock_queue'];
|
|
8213
8373
|
v_p text[] := ARRAY['Authenticated can add learnings@voorraad_publish_learnings','Authenticated can delete voorraad custom fields@voorraad_custom_fields','Authenticated can insert vbn required characteristics@floriday_vbn_required_characteristics','Authenticated can insert voorraad custom fields@voorraad_custom_fields','Authenticated can read continuous stock cache@floriday_continuous_stock_cache','Authenticated can read learnings@voorraad_publish_learnings','Authenticated can read vbn required characteristics@floriday_vbn_required_characteristics','Authenticated can read voorraad custom fields@voorraad_custom_fields','Authenticated can update learnings@voorraad_publish_learnings','Authenticated can update vbn required characteristics@floriday_vbn_required_characteristics','Authenticated can update voorraad custom fields@voorraad_custom_fields','Authenticated delete trade_item_warehouse_preferences@trade_item_warehouse_preferences','Authenticated insert trade_item_warehouse_preferences@trade_item_warehouse_preferences','Authenticated select trade_item_warehouse_preferences@trade_item_warehouse_preferences','Authenticated update trade_item_warehouse_preferences@trade_item_warehouse_preferences','Eigen momentopnamen lezen@inventory_stock_snapshots','Eigen voorraadinstellingen beheren@floriday_inventory_settings','Eigenaar leest importporties@stock_import_chunks','Eigenaar leest importregels@stock_import_rows','Fust mutations delete@fust_stock_mutations','Fust mutations insert@fust_stock_mutations','Fust mutations read@fust_stock_mutations','Fust mutations update@fust_stock_mutations','Fust types delete@fust_types','Fust types insert@fust_types','Fust types read@fust_types','Fust types update@fust_types','Ingelogde gebruikers kunnen bufferstatus lezen@voorraad_buffer_state','Ingelogde gebruikers kunnen de eventlog lezen@voorraad_logistics_event_log','Ingelogde gebruikers kunnen fustboekingen lezen@order_fust_bookings','Ingelogde gebruikers lezen drempels@inventory_recompute_limits','Ingelogde gebruikers lezen opruimlogboek@structure_cleanup_log','Ingelogde gebruikers lezen opruimruns@floriday_queue_cleanup_runs','Ingelogden beheren traystickers@product_tray_stickers','Ingelogden lezen herberekenwachtrij@inventory_recompute_queue','Ingelogden lezen voorraadmeldingen@stock_integrity_alerts','Ingelogden markeren voorraadmeldingen als gezien@stock_integrity_alerts','Own queue rows select@floriday_continuous_stock_queue','Owner delete trade_item_drafts@trade_item_drafts','Owner insert trade_item_drafts@trade_item_drafts','Owner select trade_item_drafts@trade_item_drafts','Owner update trade_item_drafts@trade_item_drafts','Signed-in users read reconcile runs@floriday_reconcile_runs','Stock delete@trade_item_stock','Stock insert@trade_item_stock','Stock read@trade_item_stock','Stock update@trade_item_stock','Synchronisatieposities lezen@floriday_sync_cursors','Users can insert own publish attempts@voorraad_publish_attempts','Users can read own publish attempts@voorraad_publish_attempts','Users can read own stock mutations@stock_mutation_log','Users manage own import runs@stock_import_runs','Users manage own supply lines@trade_item_supply_lines','Users manage own trade item prices@trade_item_prices','Users manage their own publish jobs@voorraad_publish_jobs','Users manage their own publish steps@voorraad_publish_steps','Verwerkte orders lezen@floriday_sales_order_ingest','Voorraadschrijvers lezen overnameregels@floriday_takeover_items','Voorraadschrijvers lezen overnames@floriday_takeover_runs','authenticated can insert merge log@product_merge_log','authenticated can read merge log@product_merge_log','service role only@voorraad_media_upload_failures','product_packings_read@product_packings','product_packings_write@product_packings'];
|
|
8214
8374
|
v_open text[] := ARRAY['voorraad_is_server','voorraad_vereis'];
|
|
@@ -8319,6 +8479,101 @@ GRANT EXECUTE ON FUNCTION voorraad_production_enabled() TO service_role;
|
|
|
8319
8479
|
REVOKE EXECUTE ON FUNCTION voorraad_production_enabled() FROM anon;
|
|
8320
8480
|
GRANT EXECUTE ON FUNCTION voorraad_production_enabled() TO authenticated;
|
|
8321
8481
|
GRANT EXECUTE ON FUNCTION voorraad_production_enabled() TO service_role;
|
|
8482
|
+
CREATE OR REPLACE FUNCTION public.voorraad_reverse_order_mutations(p_order_id uuid, p_reason text)
|
|
8483
|
+
RETURNS jsonb
|
|
8484
|
+
LANGUAGE plpgsql
|
|
8485
|
+
SECURITY DEFINER
|
|
8486
|
+
SET search_path TO 'public'
|
|
8487
|
+
AS $function$
|
|
8488
|
+
DECLARE
|
|
8489
|
+
v_ctx uuid;
|
|
8490
|
+
v_r record;
|
|
8491
|
+
v_s record;
|
|
8492
|
+
v_keys text[] := ARRAY[]::text[];
|
|
8493
|
+
v_rows int := 0;
|
|
8494
|
+
v_after int;
|
|
8495
|
+
v_k text;
|
|
8496
|
+
BEGIN
|
|
8497
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_reverse_order_mutations');
|
|
8498
|
+
IF p_order_id IS NULL THEN
|
|
8499
|
+
RAISE EXCEPTION 'Geen order opgegeven.' USING ERRCODE = '22023';
|
|
8500
|
+
END IF;
|
|
8501
|
+
IF p_reason IS NULL OR btrim(p_reason) = '' THEN
|
|
8502
|
+
RAISE EXCEPTION 'Geef een reden op voor het terugdraaien.' USING ERRCODE = '22023';
|
|
8503
|
+
END IF;
|
|
8504
|
+
|
|
8505
|
+
-- Vaste sleutel per order: twee aanroepen voor dezelfde order wachten op elkaar.
|
|
8506
|
+
PERFORM pg_advisory_xact_lock(hashtext('voorraad_reverse:' || p_order_id::text));
|
|
8507
|
+
|
|
8508
|
+
SELECT c.connection_id INTO v_ctx FROM public.get_stock_context(false) c;
|
|
8509
|
+
|
|
8510
|
+
-- Voorraadrijen altijd in vaste volgorde (id) vergrendelen: geen deadlock tussen orders.
|
|
8511
|
+
PERFORM 1
|
|
8512
|
+
FROM public.trade_item_stock s
|
|
8513
|
+
WHERE (s.connection_id, s.trade_item_key) IN (
|
|
8514
|
+
SELECT COALESCE(l.connection_id, v_ctx), l.trade_item_key
|
|
8515
|
+
FROM public.stock_mutation_log l
|
|
8516
|
+
WHERE l.order_id = p_order_id AND l.trade_item_key IS NOT NULL)
|
|
8517
|
+
ORDER BY s.id
|
|
8518
|
+
FOR UPDATE OF s;
|
|
8519
|
+
|
|
8520
|
+
PERFORM set_config('stock.change_source', 'ORDER_REVERSAL', true);
|
|
8521
|
+
|
|
8522
|
+
-- Netto som van ALLE fysieke mutaties van deze order, inclusief eerdere [reversal]-regels.
|
|
8523
|
+
FOR v_r IN
|
|
8524
|
+
SELECT l.trade_item_key AS k,
|
|
8525
|
+
COALESCE(l.connection_id, v_ctx) AS conn,
|
|
8526
|
+
SUM(COALESCE(l.physical_after - l.physical_before, 0)) AS net
|
|
8527
|
+
FROM public.stock_mutation_log l
|
|
8528
|
+
WHERE l.order_id = p_order_id AND l.trade_item_key IS NOT NULL
|
|
8529
|
+
GROUP BY 1, 2
|
|
8530
|
+
ORDER BY 1, 2
|
|
8531
|
+
LOOP
|
|
8532
|
+
IF v_r.net = 0 OR v_r.conn IS NULL THEN CONTINUE; END IF;
|
|
8533
|
+
|
|
8534
|
+
SELECT s.id, s.physical_stock, s.reserved_stock INTO v_s
|
|
8535
|
+
FROM public.trade_item_stock s
|
|
8536
|
+
WHERE s.connection_id = v_r.conn AND s.trade_item_key = v_r.k;
|
|
8537
|
+
IF NOT FOUND THEN CONTINUE; END IF;
|
|
8538
|
+
|
|
8539
|
+
v_after := COALESCE(v_s.physical_stock, 0) - v_r.net::int;
|
|
8540
|
+
|
|
8541
|
+
-- Logtrigger niet nog een regel laten schrijven: deze functie logt zelf.
|
|
8542
|
+
PERFORM set_config('stock.log_handled',
|
|
8543
|
+
COALESCE(current_setting('stock.log_handled', true), '') || ';' || v_r.conn || '|' || v_r.k || '|' || v_after || '|' || COALESCE(v_s.reserved_stock, 0) || ';', true);
|
|
8544
|
+
|
|
8545
|
+
UPDATE public.trade_item_stock
|
|
8546
|
+
SET physical_stock = v_after
|
|
8547
|
+
WHERE id = v_s.id;
|
|
8548
|
+
|
|
8549
|
+
INSERT INTO public.stock_mutation_log
|
|
8550
|
+
(trade_item_key, connection_id, order_id, mutation_type, qty_delta,
|
|
8551
|
+
physical_before, physical_after, reserved_before, reserved_after, reason, created_by)
|
|
8552
|
+
VALUES
|
|
8553
|
+
(v_r.k, v_r.conn, p_order_id, 'manual_correction', -v_r.net,
|
|
8554
|
+
COALESCE(v_s.physical_stock, 0), v_after, COALESCE(v_s.reserved_stock, 0), COALESCE(v_s.reserved_stock, 0),
|
|
8555
|
+
'[reversal] ' || p_reason, auth.uid());
|
|
8556
|
+
|
|
8557
|
+
v_rows := v_rows + 1;
|
|
8558
|
+
IF NOT v_r.k = ANY (v_keys) THEN v_keys := v_keys || v_r.k; END IF;
|
|
8559
|
+
END LOOP;
|
|
8560
|
+
|
|
8561
|
+
-- Gereserveerd heeft één bron: opnieuw berekenen per geraakte sleutel.
|
|
8562
|
+
FOR v_r IN SELECT DISTINCT l.trade_item_key AS k FROM public.stock_mutation_log l
|
|
8563
|
+
WHERE l.order_id = p_order_id AND l.trade_item_key IS NOT NULL ORDER BY 1
|
|
8564
|
+
LOOP
|
|
8565
|
+
PERFORM public.recompute_reserved_stock(v_r.k);
|
|
8566
|
+
IF NOT v_r.k = ANY (v_keys) THEN v_k := v_r.k; END IF;
|
|
8567
|
+
END LOOP;
|
|
8568
|
+
|
|
8569
|
+
RETURN jsonb_build_object('ok', true, 'keys', to_jsonb(v_keys), 'rows', v_rows);
|
|
8570
|
+
END;
|
|
8571
|
+
$function$
|
|
8572
|
+
;
|
|
8573
|
+
REVOKE ALL ON FUNCTION voorraad_reverse_order_mutations(uuid,text) FROM PUBLIC;
|
|
8574
|
+
REVOKE ALL ON FUNCTION voorraad_reverse_order_mutations(uuid,text) FROM anon;
|
|
8575
|
+
GRANT EXECUTE ON FUNCTION voorraad_reverse_order_mutations(uuid,text) TO authenticated;
|
|
8576
|
+
GRANT EXECUTE ON FUNCTION voorraad_reverse_order_mutations(uuid,text) TO service_role;
|
|
8322
8577
|
CREATE OR REPLACE FUNCTION public.voorraad_schema_ddl(p_tables text[], p_functions text[])
|
|
8323
8578
|
RETURNS text
|
|
8324
8579
|
LANGUAGE plpgsql
|
|
@@ -8506,6 +8761,64 @@ REVOKE ALL ON FUNCTION voorraad_week_is_past(integer,integer) FROM PUBLIC;
|
|
|
8506
8761
|
REVOKE ALL ON FUNCTION voorraad_week_is_past(integer,integer) FROM anon;
|
|
8507
8762
|
GRANT EXECUTE ON FUNCTION voorraad_week_is_past(integer,integer) TO authenticated;
|
|
8508
8763
|
GRANT EXECUTE ON FUNCTION voorraad_week_is_past(integer,integer) TO service_role;
|
|
8764
|
+
CREATE OR REPLACE FUNCTION public.voorraad_withdraw_stock_row(p_key text, p_reason text)
|
|
8765
|
+
RETURNS jsonb
|
|
8766
|
+
LANGUAGE plpgsql
|
|
8767
|
+
SECURITY DEFINER
|
|
8768
|
+
SET search_path TO 'public'
|
|
8769
|
+
AS $function$
|
|
8770
|
+
DECLARE
|
|
8771
|
+
v_c record;
|
|
8772
|
+
v_s public.trade_item_stock%ROWTYPE;
|
|
8773
|
+
BEGIN
|
|
8774
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_withdraw_stock_row');
|
|
8775
|
+
IF p_key IS NULL OR btrim(p_key) = '' THEN
|
|
8776
|
+
RAISE EXCEPTION 'Geen artikelsleutel opgegeven.' USING ERRCODE = '22023';
|
|
8777
|
+
END IF;
|
|
8778
|
+
IF p_reason IS NULL OR btrim(p_reason) = '' THEN
|
|
8779
|
+
RAISE EXCEPTION 'Geef een reden op voor het intrekken.' USING ERRCODE = '22023';
|
|
8780
|
+
END IF;
|
|
8781
|
+
|
|
8782
|
+
SELECT * INTO v_c FROM public.get_stock_context(false);
|
|
8783
|
+
IF v_c.connection_id IS NULL THEN
|
|
8784
|
+
RETURN jsonb_build_object('ok', true, 'withdrawn', false, 'reason', 'geen voorraadcontext');
|
|
8785
|
+
END IF;
|
|
8786
|
+
|
|
8787
|
+
SELECT * INTO v_s FROM public.trade_item_stock
|
|
8788
|
+
WHERE connection_id = v_c.connection_id AND trade_item_key = p_key
|
|
8789
|
+
FOR UPDATE;
|
|
8790
|
+
IF NOT FOUND THEN
|
|
8791
|
+
RETURN jsonb_build_object('ok', true, 'withdrawn', false, 'reason', 'geen registratie');
|
|
8792
|
+
END IF;
|
|
8793
|
+
|
|
8794
|
+
IF COALESCE(v_s.physical_stock, 0) <> 0 OR COALESCE(v_s.reserved_stock, 0) <> 0 OR COALESCE(v_s.incoming_stock, 0) <> 0 THEN
|
|
8795
|
+
RAISE EXCEPTION 'Registratie % kan niet worden ingetrokken: er is nog voorraad (liggend %, gereserveerd %, inkomend %).',
|
|
8796
|
+
p_key, COALESCE(v_s.physical_stock, 0), COALESCE(v_s.reserved_stock, 0), COALESCE(v_s.incoming_stock, 0)
|
|
8797
|
+
USING ERRCODE = 'VR005';
|
|
8798
|
+
END IF;
|
|
8799
|
+
|
|
8800
|
+
-- Volledige rij vóór het wissen vastleggen.
|
|
8801
|
+
INSERT INTO public.stock_mutation_log
|
|
8802
|
+
(trade_item_key, connection_id, mutation_type, qty_delta,
|
|
8803
|
+
physical_before, physical_after, reserved_before, reserved_after, reason, created_by)
|
|
8804
|
+
VALUES
|
|
8805
|
+
(p_key, v_c.connection_id, 'manual_correction', 0, 0, 0, 0, 0,
|
|
8806
|
+
'[registration_withdrawn] ' || p_reason
|
|
8807
|
+
|| ' | context=' || v_c.context_kind || ':' || v_c.connection_id
|
|
8808
|
+
|| ' | bron=' || COALESCE(NULLIF(btrim(current_setting('stock.change_source', true)), ''), 'onbekend')
|
|
8809
|
+
|| ' | rij=' || row_to_json(v_s)::text,
|
|
8810
|
+
auth.uid());
|
|
8811
|
+
|
|
8812
|
+
DELETE FROM public.trade_item_stock WHERE id = v_s.id;
|
|
8813
|
+
|
|
8814
|
+
RETURN jsonb_build_object('ok', true, 'withdrawn', true, 'key', p_key, 'context', v_c.context_kind);
|
|
8815
|
+
END;
|
|
8816
|
+
$function$
|
|
8817
|
+
;
|
|
8818
|
+
REVOKE ALL ON FUNCTION voorraad_withdraw_stock_row(text,text) FROM PUBLIC;
|
|
8819
|
+
REVOKE ALL ON FUNCTION voorraad_withdraw_stock_row(text,text) FROM anon;
|
|
8820
|
+
GRANT EXECUTE ON FUNCTION voorraad_withdraw_stock_row(text,text) TO authenticated;
|
|
8821
|
+
GRANT EXECUTE ON FUNCTION voorraad_withdraw_stock_row(text,text) TO service_role;
|
|
8509
8822
|
|
|
8510
8823
|
-- controles en sleutels
|
|
8511
8824
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'floriday_continuous_stock_cache_pkey' AND conrelid = 'public.floriday_continuous_stock_cache'::regclass) THEN ALTER TABLE public.floriday_continuous_stock_cache ADD CONSTRAINT floriday_continuous_stock_cache_pkey PRIMARY KEY (connection_id, trade_item_id); END IF; END $c$;
|
|
@@ -8611,6 +8924,7 @@ DO $g$ BEGIN IF to_regclass('public.products') IS NULL THEN RAISE NOTICE 'Voorra
|
|
|
8611
8924
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'floriday_takeover_items_run_id_fkey' AND conrelid = 'public.floriday_takeover_items'::regclass) THEN ALTER TABLE public.floriday_takeover_items ADD CONSTRAINT floriday_takeover_items_run_id_fkey FOREIGN KEY (run_id) REFERENCES floriday_takeover_runs(id) ON DELETE CASCADE; END IF; END $c$;
|
|
8612
8925
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'floriday_vbn_required_characteristics_updated_by_fkey' AND conrelid = 'public.floriday_vbn_required_characteristics'::regclass) THEN ALTER TABLE public.floriday_vbn_required_characteristics ADD CONSTRAINT floriday_vbn_required_characteristics_updated_by_fkey FOREIGN KEY (updated_by) REFERENCES auth.users(id) ON DELETE SET NULL; END IF; END $c$;
|
|
8613
8926
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fust_stock_mutations_fust_type_id_fkey' AND conrelid = 'public.fust_stock_mutations'::regclass) THEN ALTER TABLE public.fust_stock_mutations ADD CONSTRAINT fust_stock_mutations_fust_type_id_fkey FOREIGN KEY (fust_type_id) REFERENCES fust_types(id) ON DELETE CASCADE; END IF; END $c$;
|
|
8927
|
+
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fust_types_merged_into_fkey' AND conrelid = 'public.fust_types'::regclass) THEN ALTER TABLE public.fust_types ADD CONSTRAINT fust_types_merged_into_fkey FOREIGN KEY (merged_into) REFERENCES fust_types(id); END IF; END $c$;
|
|
8614
8928
|
DO $c$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'order_fust_bookings_fust_type_id_fkey' AND conrelid = 'public.order_fust_bookings'::regclass) THEN ALTER TABLE public.order_fust_bookings ADD CONSTRAINT order_fust_bookings_fust_type_id_fkey FOREIGN KEY (fust_type_id) REFERENCES fust_types(id) ON DELETE CASCADE; END IF; END $c$;
|
|
8615
8929
|
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$;
|
|
8616
8930
|
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$;
|
|
@@ -8654,6 +8968,7 @@ CREATE INDEX IF NOT EXISTS stock_integrity_alerts_open_idx ON public.stock_integ
|
|
|
8654
8968
|
CREATE INDEX IF NOT EXISTS trade_item_prices_lookup ON public.trade_item_prices USING btree (trade_item_key, price_group_id);
|
|
8655
8969
|
CREATE INDEX IF NOT EXISTS trade_item_stock_trade_item_key_idx ON public.trade_item_stock USING btree (trade_item_key);
|
|
8656
8970
|
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]));
|
|
8971
|
+
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));
|
|
8657
8972
|
CREATE UNIQUE INDEX IF NOT EXISTS fust_types_user_key_global_idx ON public.fust_types USING btree (user_id, fust_key) WHERE (connection_id IS NULL);
|
|
8658
8973
|
CREATE UNIQUE INDEX IF NOT EXISTS product_packings_one_primary ON public.product_packings USING btree (product_id) WHERE is_primary;
|
|
8659
8974
|
CREATE UNIQUE INDEX IF NOT EXISTS stock_import_runs_one_active ON public.stock_import_runs USING btree (COALESCE(connection_id, '00000000-0000-0000-0000-000000000000'::uuid)) WHERE (status = ANY (ARRAY['ontvangen'::text, 'bezig'::text, 'gestopt'::text]));
|