@flowselections/floriday-voorraad 1.0.145 → 1.0.147
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/ArtikelWizard.d.ts +3 -1
- package/dist-lib/components/voorraad/ArtikelWizard.d.ts.map +1 -1
- package/dist-lib/components/voorraad/ArtikelWizard.js +56 -52
- package/dist-lib/components/voorraad/EditArtikelPage.d.ts.map +1 -1
- package/dist-lib/components/voorraad/EditArtikelPage.js +3 -4
- package/dist-lib/components/voorraad/ProductCustomFieldsCard.d.ts.map +1 -1
- package/dist-lib/components/voorraad/ProductCustomFieldsCard.js +29 -13
- package/dist-lib/components/voorraad/ProductSalePriceField.d.ts.map +1 -1
- package/dist-lib/components/voorraad/ProductSalePriceField.js +9 -8
- package/dist-lib/components/voorraad/StepSamenstelling.d.ts.map +1 -1
- package/dist-lib/components/voorraad/StepSamenstelling.js +35 -10
- package/dist-lib/components/voorraad/TrayStickerCard.d.ts +5 -1
- package/dist-lib/components/voorraad/TrayStickerCard.d.ts.map +1 -1
- package/dist-lib/components/voorraad/TrayStickerCard.js +64 -66
- package/dist-lib/components/voorraad/ValidationOverviewTable.d.ts +0 -5
- package/dist-lib/components/voorraad/ValidationOverviewTable.d.ts.map +1 -1
- package/dist-lib/components/voorraad/ValidationOverviewTable.js +10 -4
- package/dist-lib/components/voorraad/VoorraadPage.d.ts +1 -13
- package/dist-lib/components/voorraad/VoorraadPage.d.ts.map +1 -1
- package/dist-lib/components/voorraad/VoorraadPage.js +102 -140
- package/dist-lib/components/voorraad/VoorraadSturingCard.d.ts +6 -0
- package/dist-lib/components/voorraad/VoorraadSturingCard.d.ts.map +1 -0
- package/dist-lib/components/voorraad/VoorraadSturingCard.js +47 -0
- package/dist-lib/components/voorraad/artikel/ArtikelPagina.d.ts +5 -0
- package/dist-lib/components/voorraad/artikel/ArtikelPagina.d.ts.map +1 -0
- package/dist-lib/components/voorraad/artikel/ArtikelPagina.js +263 -0
- package/dist-lib/components/voorraad/artikel/TwijfelKiezen.d.ts +7 -0
- package/dist-lib/components/voorraad/artikel/TwijfelKiezen.d.ts.map +1 -0
- package/dist-lib/components/voorraad/artikel/TwijfelKiezen.js +54 -0
- package/dist-lib/components/voorraad/artikel/opslaan-context.d.ts +21 -0
- package/dist-lib/components/voorraad/artikel/opslaan-context.d.ts.map +1 -0
- package/dist-lib/components/voorraad/artikel/opslaan-context.js +15 -0
- package/dist-lib/components/voorraad/lijst/ImporteerKnop.d.ts +5 -0
- package/dist-lib/components/voorraad/lijst/ImporteerKnop.d.ts.map +1 -0
- package/dist-lib/components/voorraad/lijst/ImporteerKnop.js +20 -0
- package/dist-lib/components/voorraad/lijst/LijstExportKnop.d.ts +6 -0
- package/dist-lib/components/voorraad/lijst/LijstExportKnop.d.ts.map +1 -0
- package/dist-lib/components/voorraad/lijst/LijstExportKnop.js +43 -0
- package/dist-lib/components/voorraad/lijst/SnelActieDialogen.d.ts +16 -0
- package/dist-lib/components/voorraad/lijst/SnelActieDialogen.d.ts.map +1 -0
- package/dist-lib/components/voorraad/lijst/SnelActieDialogen.js +95 -0
- package/dist-lib/components/voorraad/lijst/VoorraadLijstTabel.d.ts +21 -0
- package/dist-lib/components/voorraad/lijst/VoorraadLijstTabel.d.ts.map +1 -0
- package/dist-lib/components/voorraad/lijst/VoorraadLijstTabel.js +38 -0
- package/dist-lib/hooks/useVoorraadLijst.d.ts +21 -0
- package/dist-lib/hooks/useVoorraadLijst.d.ts.map +1 -0
- package/dist-lib/hooks/useVoorraadLijst.js +71 -0
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +2 -0
- package/dist-lib/integrations/supabase/types.d.ts +465 -1
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/artikel-pagina.d.ts +57 -0
- package/dist-lib/lib/artikel-pagina.d.ts.map +1 -0
- package/dist-lib/lib/artikel-pagina.js +93 -0
- package/dist-lib/lib/count-stock.d.ts +17 -0
- package/dist-lib/lib/count-stock.d.ts.map +1 -0
- package/dist-lib/lib/count-stock.js +26 -0
- package/dist-lib/lib/floriday-import-validator.d.ts +9 -0
- package/dist-lib/lib/floriday-import-validator.d.ts.map +1 -1
- package/dist-lib/lib/floriday-import-validator.js +13 -0
- package/dist-lib/lib/pending-photos.d.ts +20 -0
- package/dist-lib/lib/pending-photos.d.ts.map +1 -0
- package/dist-lib/lib/pending-photos.js +90 -0
- package/dist-lib/lib/voorraad-custom-fields.d.ts +16 -1
- package/dist-lib/lib/voorraad-custom-fields.d.ts.map +1 -1
- package/dist-lib/lib/voorraad-custom-fields.js +12 -6
- package/dist-lib/lib/voorraad-lijst.d.ts +91 -0
- package/dist-lib/lib/voorraad-lijst.d.ts.map +1 -0
- package/dist-lib/lib/voorraad-lijst.js +82 -0
- package/package.json +1 -1
- package/sql/AGENTS.md +4 -0
- package/sql/floriday-voorraad-schema.sql +723 -10
|
@@ -1,9 +1,24 @@
|
|
|
1
|
-
-- @flowselections/floriday-voorraad 1.0.
|
|
2
|
-
-- Laatste migratie:
|
|
1
|
+
-- @flowselections/floriday-voorraad 1.0.146 – volledig schema (idempotent, geen gegevens).
|
|
2
|
+
-- Laatste migratie: 20261103225325_855bad38-f69b-4701-85b7-2d35ee33c08f.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.
|
|
6
6
|
SET check_function_bodies = off;
|
|
7
|
+
-- eigen kolommen/indexen op tabellen van andere modules
|
|
8
|
+
DO $fk$ BEGIN IF to_regclass('public.products') IS NOT NULL THEN EXECUTE 'CREATE INDEX IF NOT EXISTS idx_products_trade_item_key ON public.products(trade_item_key);'; ELSE RAISE NOTICE 'Voorraad: tabel products ontbreekt, overgeslagen'; END IF; END $fk$;
|
|
9
|
+
DO $fk$ BEGIN IF to_regclass('public.product_groups') IS NOT NULL THEN EXECUTE 'CREATE UNIQUE INDEX IF NOT EXISTS product_groups_one_active_per_head_product ON public.product_groups(head_product_id) WHERE is_active AND head_product_id IS NOT NULL;'; ELSE RAISE NOTICE 'Voorraad: tabel product_groups ontbreekt, overgeslagen'; END IF; END $fk$;
|
|
10
|
+
DO $fk$ BEGIN IF to_regclass('public.product_groups') IS NOT NULL THEN EXECUTE 'CREATE UNIQUE INDEX IF NOT EXISTS product_groups_one_active_per_head_floriday ON public.product_groups(head_trade_item_floriday_id) WHERE is_active AND head_trade_item_floriday_id IS NOT NULL;'; ELSE RAISE NOTICE 'Voorraad: tabel product_groups ontbreekt, overgeslagen'; END IF; END $fk$;
|
|
11
|
+
DO $fk$ BEGIN IF to_regclass('public.product_groups') IS NOT NULL THEN EXECUTE 'CREATE UNIQUE INDEX IF NOT EXISTS product_groups_active_name_uq ON public.product_groups (lower(btrim(name))) WHERE is_active IS TRUE;'; ELSE RAISE NOTICE 'Voorraad: tabel product_groups ontbreekt, overgeslagen'; END IF; END $fk$;
|
|
12
|
+
DO $fk$ BEGIN IF to_regclass('public.products') IS NOT NULL THEN EXECUTE 'ALTER TABLE public.products ADD COLUMN IF NOT EXISTS floriday_velden_aangepast text[];'; ELSE RAISE NOTICE 'Voorraad: tabel products ontbreekt, overgeslagen'; END IF; END $fk$;
|
|
13
|
+
DO $fk$ BEGIN IF to_regclass('public.products') IS NOT NULL THEN EXECUTE 'ALTER TABLE public.products ADD COLUMN IF NOT EXISTS floriday_verwijderd_at timestamptz;'; ELSE RAISE NOTICE 'Voorraad: tabel products ontbreekt, overgeslagen'; END IF; END $fk$;
|
|
14
|
+
DO $fk$ BEGIN IF to_regclass('public.products') IS NOT NULL THEN EXECUTE 'ALTER TABLE public.products ADD COLUMN IF NOT EXISTS gearchiveerd_at timestamptz;'; ELSE RAISE NOTICE 'Voorraad: tabel products ontbreekt, overgeslagen'; END IF; END $fk$;
|
|
15
|
+
DO $fk$ BEGIN IF to_regclass('public.products') IS NOT NULL THEN EXECUTE 'ALTER TABLE public.products ADD COLUMN IF NOT EXISTS gearchiveerd_door uuid;'; ELSE RAISE NOTICE 'Voorraad: tabel products ontbreekt, overgeslagen'; END IF; END $fk$;
|
|
16
|
+
DO $fk$ BEGIN IF to_regclass('public.products') IS NOT NULL THEN EXECUTE 'CREATE INDEX IF NOT EXISTS products_gearchiveerd_at_idx ON public.products (gearchiveerd_at) WHERE gearchiveerd_at IS NOT NULL;'; ELSE RAISE NOTICE 'Voorraad: tabel products ontbreekt, overgeslagen'; END IF; END $fk$;
|
|
17
|
+
DO $fk$ BEGIN IF to_regclass('public.product_bom_items') IS NOT NULL THEN EXECUTE 'CREATE INDEX IF NOT EXISTS product_bom_items_component_idx ON public.product_bom_items (component_product_id);'; ELSE RAISE NOTICE 'Voorraad: tabel product_bom_items ontbreekt, overgeslagen'; END IF; END $fk$;
|
|
18
|
+
DO $fk$ BEGIN IF to_regclass('public.product_bom_items') IS NOT NULL THEN EXECUTE 'CREATE INDEX IF NOT EXISTS product_bom_items_parent_idx ON public.product_bom_items (parent_product_id);'; ELSE RAISE NOTICE 'Voorraad: tabel product_bom_items ontbreekt, overgeslagen'; END IF; END $fk$;
|
|
19
|
+
DO $fk$ BEGIN IF to_regclass('public.products') IS NOT NULL THEN EXECUTE 'CREATE INDEX IF NOT EXISTS products_id_text_idx ON public.products ((id::text));'; ELSE RAISE NOTICE 'Voorraad: tabel products ontbreekt, overgeslagen'; END IF; END $fk$;
|
|
20
|
+
DO $fk$ BEGIN IF to_regclass('public.products') IS NOT NULL THEN EXECUTE 'ALTER TABLE public.products ADD COLUMN IF NOT EXISTS gearchiveerd_floriday_nul boolean NOT NULL DEFAULT false;'; ELSE RAISE NOTICE 'Voorraad: tabel products ontbreekt, overgeslagen'; END IF; END $fk$;
|
|
21
|
+
DO $fk$ BEGIN IF to_regclass('public.floriday_salesorders_cache') IS NOT NULL THEN EXECUTE 'CREATE INDEX IF NOT EXISTS voorraad_fsc_floriday_id_idx ON public.floriday_salesorders_cache (floriday_id);'; ELSE RAISE NOTICE 'Voorraad: tabel floriday_salesorders_cache ontbreekt, overgeslagen'; END IF; END $fk$;
|
|
7
22
|
|
|
8
23
|
-- floriday_continuous_stock_cache
|
|
9
24
|
CREATE TABLE IF NOT EXISTS public.floriday_continuous_stock_cache ();
|
|
@@ -1085,6 +1100,10 @@ BEGIN
|
|
|
1085
1100
|
IF v_type IS DISTINCT FROM 'GROUP' AND cardinality(public.product_member_group_ids(p_product_id)) > 0 THEN
|
|
1086
1101
|
desired_quantity := 0; desired_availability := false; reason := 'GROUP_MEMBER_OFF'; RETURN NEXT; RETURN;
|
|
1087
1102
|
END IF;
|
|
1103
|
+
-- 1.0.146: gearchiveerd met "Ook in Floriday" = 0 op Floriday (nooit raisen).
|
|
1104
|
+
IF EXISTS (SELECT 1 FROM public.products ap WHERE ap.id = p_product_id AND ap.gearchiveerd_at IS NOT NULL AND ap.gearchiveerd_floriday_nul) THEN
|
|
1105
|
+
desired_quantity := 0; desired_availability := false; reason := 'ARCHIVED'; RETURN NEXT; RETURN;
|
|
1106
|
+
END IF;
|
|
1088
1107
|
IF stock_mode = 'DISABLED' THEN
|
|
1089
1108
|
desired_quantity := 0; desired_availability := false; RETURN NEXT; RETURN;
|
|
1090
1109
|
END IF;
|
|
@@ -2994,7 +3013,7 @@ CREATE OR REPLACE FUNCTION public.floriday_desired_stock_regression_check()
|
|
|
2994
3013
|
AS $function$
|
|
2995
3014
|
WITH b AS (
|
|
2996
3015
|
SELECT s.connection_id, s.product_id, p.product, s.stock_mode, s.buffer_quantity, s.maximum_quantity, s.fixed_quantity, s.manual_quantity,
|
|
2997
|
-
public.product_primary_pieces(p.id) AS pack,
|
|
3016
|
+
public.product_primary_pieces(p.id) AS pack, (p.gearchiveerd_at IS NOT NULL AND p.gearchiveerd_floriday_nul) AS archief_nul,
|
|
2998
3017
|
(SELECT GREATEST(0, floor(ts.physical_stock - ts.reserved_stock))::int FROM public.trade_item_stock ts
|
|
2999
3018
|
WHERE ts.connection_id = s.connection_id
|
|
3000
3019
|
AND ts.trade_item_key = COALESCE(NULLIF(btrim(p.floriday_trade_item_id),''), NULLIF(btrim(p.trade_item_key),''))) AS avail
|
|
@@ -3006,6 +3025,7 @@ AS $function$
|
|
|
3006
3025
|
), e AS (
|
|
3007
3026
|
SELECT b.*, (public.calculate_floriday_desired_stock(b.connection_id, b.product_id)).desired_quantity AS act,
|
|
3008
3027
|
CASE WHEN b.avail IS NULL OR b.pack IS NULL THEN 0
|
|
3028
|
+
WHEN b.archief_nul THEN 0
|
|
3009
3029
|
WHEN b.stock_mode = 'DISABLED' THEN 0
|
|
3010
3030
|
ELSE GREATEST(0, (GREATEST(0, CASE b.stock_mode
|
|
3011
3031
|
WHEN 'MAXIMUM' THEN LEAST(b.avail - b.buffer_quantity, COALESCE(b.maximum_quantity, b.avail - b.buffer_quantity))
|
|
@@ -6813,25 +6833,32 @@ AS $function$
|
|
|
6813
6833
|
DECLARE v_resolved uuid; v_m jsonb;
|
|
6814
6834
|
BEGIN
|
|
6815
6835
|
-- Floriday-orderregel: koppelen op het Floriday-artikel (eenduidig), nooit op naam.
|
|
6836
|
+
-- Een al ingevuld artikel wordt nooit overschreven (Engine of gebruiker koos het).
|
|
6816
6837
|
IF NEW.source_line_key IS NOT NULL AND btrim(NEW.source_line_key) <> '' THEN
|
|
6817
6838
|
BEGIN
|
|
6818
6839
|
v_m := public.voorraad_orderregel_trade_item_bron(NEW.order_id, NEW.source_line_key);
|
|
6819
6840
|
EXCEPTION WHEN others THEN v_m := NULL;
|
|
6820
6841
|
END;
|
|
6821
6842
|
IF v_m->>'status' = 'eenduidig' THEN
|
|
6822
|
-
IF NEW.product_id IS
|
|
6843
|
+
IF NEW.product_id IS NULL THEN
|
|
6823
6844
|
BEGIN
|
|
6824
6845
|
INSERT INTO public.voorraad_koppel_log(soort, floriday_id, product_id, order_item_id, oud, nieuw)
|
|
6825
6846
|
VALUES ('orderregel_op_floriday_artikel', v_m->>'trade_item_id', (v_m->>'product_id')::uuid, NEW.id,
|
|
6826
|
-
jsonb_build_object('product_id',
|
|
6847
|
+
jsonb_build_object('product_id', NULL), jsonb_build_object('product_id', v_m->>'product_id'));
|
|
6827
6848
|
EXCEPTION WHEN others THEN NULL;
|
|
6828
6849
|
END;
|
|
6829
6850
|
NEW.product_id := (v_m->>'product_id')::uuid;
|
|
6851
|
+
ELSIF NEW.product_id IS DISTINCT FROM (v_m->>'product_id')::uuid THEN
|
|
6852
|
+
BEGIN
|
|
6853
|
+
INSERT INTO public.voorraad_koppel_log(soort, floriday_id, product_id, order_item_id, oud, nieuw)
|
|
6854
|
+
VALUES ('orderregel_afwijkend_behouden', v_m->>'trade_item_id', NEW.product_id, NEW.id,
|
|
6855
|
+
jsonb_build_object('product_id', NEW.product_id), jsonb_build_object('floriday_product_id', v_m->>'product_id'));
|
|
6856
|
+
EXCEPTION WHEN others THEN NULL;
|
|
6857
|
+
END;
|
|
6830
6858
|
END IF;
|
|
6831
6859
|
END IF;
|
|
6832
6860
|
RETURN NEW;
|
|
6833
6861
|
END IF;
|
|
6834
|
-
-- Mailbox- en handmatige orders: naam als terugval.
|
|
6835
6862
|
IF NEW.product_id IS NULL AND NEW.product_name IS NOT NULL THEN
|
|
6836
6863
|
v_resolved := public.resolve_product_id_for_item(NEW.product_name);
|
|
6837
6864
|
IF v_resolved IS NOT NULL THEN NEW.product_id := v_resolved; END IF;
|
|
@@ -7354,7 +7381,8 @@ AS $function$
|
|
|
7354
7381
|
BEGIN
|
|
7355
7382
|
IF COALESCE(NEW.sale_price,0) > 0
|
|
7356
7383
|
AND lower(trim(COALESCE(NEW.unit,'stuks'))) IN ('stuks','stuk','')
|
|
7357
|
-
AND (NEW.sale_price IS DISTINCT FROM OLD.sale_price OR NEW.unit IS DISTINCT FROM OLD.unit)
|
|
7384
|
+
AND (NEW.sale_price IS DISTINCT FROM OLD.sale_price OR NEW.unit IS DISTINCT FROM OLD.unit)
|
|
7385
|
+
AND public.voorraad_floriday_volgt(NEW.id) THEN
|
|
7358
7386
|
WITH latest AS (
|
|
7359
7387
|
SELECT DISTINCT ON (target_year, target_week) id, target_year, target_week
|
|
7360
7388
|
FROM public.floriday_continuous_stock_queue
|
|
@@ -7368,12 +7396,10 @@ BEGIN
|
|
|
7368
7396
|
AND q.id <> l.id
|
|
7369
7397
|
AND q.target_year IS NOT DISTINCT FROM l.target_year
|
|
7370
7398
|
AND q.target_week IS NOT DISTINCT FROM l.target_week;
|
|
7371
|
-
|
|
7372
7399
|
UPDATE public.floriday_continuous_stock_queue q
|
|
7373
7400
|
SET status = 'pending', next_attempt_at = now(), skip_reason = NULL,
|
|
7374
7401
|
last_error = NULL, result_label = NULL, updated_at = now()
|
|
7375
7402
|
WHERE q.product_id = NEW.id AND q.status = 'skipped_no_price';
|
|
7376
|
-
|
|
7377
7403
|
PERFORM public.enqueue_structure_recompute(ARRAY[NEW.id], 'price_change', true);
|
|
7378
7404
|
END IF;
|
|
7379
7405
|
RETURN NEW;
|
|
@@ -8035,6 +8061,176 @@ REVOKE ALL ON FUNCTION voorraad_article_vbn(uuid) FROM PUBLIC;
|
|
|
8035
8061
|
REVOKE ALL ON FUNCTION voorraad_article_vbn(uuid) FROM anon;
|
|
8036
8062
|
GRANT EXECUTE ON FUNCTION voorraad_article_vbn(uuid) TO authenticated;
|
|
8037
8063
|
GRANT EXECUTE ON FUNCTION voorraad_article_vbn(uuid) TO service_role;
|
|
8064
|
+
CREATE OR REPLACE FUNCTION public.voorraad_artikel_archiveren(p_id uuid, p_archiveren boolean, p_bevestigd boolean DEFAULT false, p_ook_floriday boolean DEFAULT false)
|
|
8065
|
+
RETURNS jsonb
|
|
8066
|
+
LANGUAGE plpgsql
|
|
8067
|
+
SECURITY DEFINER
|
|
8068
|
+
SET search_path TO 'public'
|
|
8069
|
+
AS $function$
|
|
8070
|
+
DECLARE v_d jsonb; v_res numeric; v_open int; v_fl text; v_was boolean;
|
|
8071
|
+
BEGIN
|
|
8072
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_artikel_archiveren');
|
|
8073
|
+
IF NOT public.voorraad_can_write() THEN
|
|
8074
|
+
RAISE EXCEPTION 'Je hebt geen schrijfrechten op de voorraad.' USING ERRCODE = '42501'; END IF;
|
|
8075
|
+
SELECT NULLIF(btrim(COALESCE(floriday_trade_item_id,'')),''), gearchiveerd_floriday_nul INTO v_fl, v_was
|
|
8076
|
+
FROM public.products WHERE id = p_id FOR UPDATE;
|
|
8077
|
+
IF NOT FOUND THEN RAISE EXCEPTION 'Artikel niet gevonden.' USING ERRCODE = 'P0002'; END IF;
|
|
8078
|
+
IF p_archiveren THEN
|
|
8079
|
+
IF p_ook_floriday AND v_fl IS NULL THEN
|
|
8080
|
+
RAISE EXCEPTION 'Dit artikel is niet aan Floriday gekoppeld; kies "Alleen hier".' USING ERRCODE = '22023'; END IF;
|
|
8081
|
+
v_d := public.voorraad_artikel_detail(p_id);
|
|
8082
|
+
v_res := COALESCE((v_d->>'gereserveerd')::numeric, 0); v_open := COALESCE((v_d->>'open_orders')::int, 0);
|
|
8083
|
+
IF (v_res > 0 OR v_open > 0) AND NOT COALESCE(p_bevestigd,false) THEN
|
|
8084
|
+
RETURN jsonb_build_object('ok', false, 'waarschuwing', true, 'gereserveerd', v_res, 'open_orders', v_open);
|
|
8085
|
+
END IF;
|
|
8086
|
+
UPDATE public.products SET gearchiveerd_at = COALESCE(gearchiveerd_at, now()), gearchiveerd_door = auth.uid(),
|
|
8087
|
+
gearchiveerd_floriday_nul = COALESCE(p_ook_floriday, false) WHERE id = p_id;
|
|
8088
|
+
ELSE
|
|
8089
|
+
UPDATE public.products SET gearchiveerd_at = NULL, gearchiveerd_door = NULL, gearchiveerd_floriday_nul = false WHERE id = p_id;
|
|
8090
|
+
END IF;
|
|
8091
|
+
-- Floriday-voorraad opnieuw laten berekenen via de gewone wachtrij (schrijfstop en ERP-leidend-controle blijven gelden).
|
|
8092
|
+
IF v_fl IS NOT NULL AND (COALESCE(p_ook_floriday,false) OR COALESCE(v_was,false)) THEN
|
|
8093
|
+
BEGIN PERFORM public.enqueue_structure_recompute(ARRAY[p_id], 'ARCHIVED', true);
|
|
8094
|
+
EXCEPTION WHEN others THEN NULL; END;
|
|
8095
|
+
END IF;
|
|
8096
|
+
RETURN jsonb_build_object('ok', true, 'ook_floriday', COALESCE(p_ook_floriday,false) AND p_archiveren);
|
|
8097
|
+
END $function$
|
|
8098
|
+
;
|
|
8099
|
+
REVOKE ALL ON FUNCTION voorraad_artikel_archiveren(uuid,boolean,boolean,boolean) FROM PUBLIC;
|
|
8100
|
+
REVOKE ALL ON FUNCTION voorraad_artikel_archiveren(uuid,boolean,boolean,boolean) FROM anon;
|
|
8101
|
+
GRANT EXECUTE ON FUNCTION voorraad_artikel_archiveren(uuid,boolean,boolean,boolean) TO authenticated;
|
|
8102
|
+
GRANT EXECUTE ON FUNCTION voorraad_artikel_archiveren(uuid,boolean,boolean,boolean) TO service_role;
|
|
8103
|
+
CREATE OR REPLACE FUNCTION public.voorraad_artikel_detail(p_id uuid)
|
|
8104
|
+
RETURNS jsonb
|
|
8105
|
+
LANGUAGE plpgsql
|
|
8106
|
+
STABLE SECURITY DEFINER
|
|
8107
|
+
SET search_path TO 'public'
|
|
8108
|
+
AS $function$
|
|
8109
|
+
DECLARE
|
|
8110
|
+
p public.products%ROWTYPE; v_conn uuid; v_ctx uuid; v_key text; s public.trade_item_stock%ROWTYPE;
|
|
8111
|
+
v_soort text; v_vrij numeric; v_open int; v_erp boolean; v_tel timestamptz; v_pak boolean; v_pak_ok boolean;
|
|
8112
|
+
BEGIN
|
|
8113
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_artikel_detail');
|
|
8114
|
+
SELECT * INTO p FROM public.products WHERE id = p_id;
|
|
8115
|
+
IF NOT FOUND THEN RETURN jsonb_build_object('gevonden', false); END IF;
|
|
8116
|
+
BEGIN SELECT x.connection_id INTO v_conn FROM public.get_active_floriday_context() x LIMIT 1;
|
|
8117
|
+
EXCEPTION WHEN others THEN v_conn := NULL; END;
|
|
8118
|
+
BEGIN SELECT c.connection_id INTO v_ctx FROM public.get_stock_context() c LIMIT 1;
|
|
8119
|
+
EXCEPTION WHEN others THEN v_ctx := NULL; END;
|
|
8120
|
+
|
|
8121
|
+
SELECT x.* INTO s FROM public.trade_item_stock x
|
|
8122
|
+
WHERE x.archived_at IS NULL AND x.trade_item_key IN (
|
|
8123
|
+
NULLIF(btrim(COALESCE(p.trade_item_key,'')),''), NULLIF(btrim(COALESCE(p.floriday_trade_item_id,'')),''), 'product:' || p.id::text)
|
|
8124
|
+
ORDER BY CASE x.trade_item_key WHEN NULLIF(btrim(COALESCE(p.trade_item_key,'')),'') THEN 1
|
|
8125
|
+
WHEN NULLIF(btrim(COALESCE(p.floriday_trade_item_id,'')),'') THEN 2 ELSE 3 END,
|
|
8126
|
+
(x.connection_id IS NOT DISTINCT FROM v_ctx) DESC, x.updated_at DESC
|
|
8127
|
+
LIMIT 1;
|
|
8128
|
+
v_key := s.trade_item_key;
|
|
8129
|
+
|
|
8130
|
+
v_soort := CASE WHEN EXISTS (SELECT 1 FROM public.product_groups g WHERE g.head_product_id = p.id AND g.is_active) THEN 'GROUP'
|
|
8131
|
+
WHEN EXISTS (SELECT 1 FROM public.product_bom_items b WHERE b.parent_product_id = p.id) THEN 'SET' ELSE 'NORMAL' END;
|
|
8132
|
+
v_vrij := GREATEST(COALESCE(s.physical_stock,0) - COALESCE(s.reserved_stock,0), 0);
|
|
8133
|
+
IF v_soort <> 'NORMAL' AND v_ctx IS NOT NULL THEN
|
|
8134
|
+
BEGIN v_vrij := COALESCE((public.calculate_structure_available(v_ctx, p.id)->>'available')::numeric, v_vrij);
|
|
8135
|
+
EXCEPTION WHEN others THEN NULL; END;
|
|
8136
|
+
END IF;
|
|
8137
|
+
|
|
8138
|
+
SELECT count(*) INTO v_open FROM public.order_items oi JOIN public.orders o ON o.id = oi.order_id
|
|
8139
|
+
WHERE oi.product_id = p.id AND oi.quarantined_at IS NULL
|
|
8140
|
+
AND NOT public.voorraad_order_geannuleerd(o.status, o.cancelled_at, o.deleted_at)
|
|
8141
|
+
AND lower(COALESCE(o.status,'')) NOT IN ('verzonden','gereed voor facturatie');
|
|
8142
|
+
|
|
8143
|
+
IF NULLIF(btrim(COALESCE(p.floriday_trade_item_id,'')),'') IS NOT NULL THEN
|
|
8144
|
+
SELECT bool_or(f.erp_leading) INTO v_erp FROM public.floriday_inventory_settings f
|
|
8145
|
+
WHERE f.product_id = p.id;
|
|
8146
|
+
END IF;
|
|
8147
|
+
SELECT max(t.telmoment) INTO v_tel FROM public.voorraad_telmoment t;
|
|
8148
|
+
v_pak := EXISTS (SELECT 1 FROM public.product_packings k WHERE k.product_id = p.id AND k.is_primary);
|
|
8149
|
+
v_pak_ok := COALESCE((p.custom_fields#>>'{voorraad_packing_link,ok}')::boolean, true);
|
|
8150
|
+
|
|
8151
|
+
RETURN jsonb_build_object(
|
|
8152
|
+
'gevonden', true, 'id', p.id,
|
|
8153
|
+
'velden', jsonb_build_object('product', p.product, 'article_number', p.article_number, 'sale_price', p.sale_price,
|
|
8154
|
+
'unit', p.unit, 'barcode', p.barcode),
|
|
8155
|
+
'naam', COALESCE(NULLIF(btrim(p.product),''), NULLIF(p.custom_fields#>>'{floriday_payload,name}',''), '(naamloos)'),
|
|
8156
|
+
'artikelnummer', COALESCE(NULLIF(btrim(p.article_number),''), NULLIF(p.custom_fields#>>'{floriday_payload,articleCode}','')),
|
|
8157
|
+
'foto', COALESCE(NULLIF(p.image_url,''), NULLIF(p.custom_fields#>>'{floriday_payload,images,0,url}',''), NULLIF(p.custom_fields#>>'{floriday_payload,images,0,previewUrl}','')),
|
|
8158
|
+
'floriday_id', NULLIF(btrim(COALESCE(p.floriday_trade_item_id,'')),''),
|
|
8159
|
+
'heeft_koppeling', v_conn IS NOT NULL,
|
|
8160
|
+
'soort', v_soort,
|
|
8161
|
+
'is_onderdeel', EXISTS (SELECT 1 FROM public.product_bom_items b WHERE b.component_product_id = p.id),
|
|
8162
|
+
'voorraad_sleutel', v_key,
|
|
8163
|
+
'liggend', COALESCE(s.physical_stock,0), 'gereserveerd', COALESCE(s.reserved_stock,0),
|
|
8164
|
+
'inkomend', COALESCE(s.incoming_stock,0), 'minimum', COALESCE(s.minimum_stock,0), 'vrij', v_vrij,
|
|
8165
|
+
'notitie', s.notes, 'open_orders', v_open,
|
|
8166
|
+
'floriday_stuurt', COALESCE(v_erp, false),
|
|
8167
|
+
'telmoment', v_tel,
|
|
8168
|
+
'verpakking_ok', (v_soort = 'GROUP' OR (v_pak AND v_pak_ok)),
|
|
8169
|
+
'gearchiveerd_at', p.gearchiveerd_at, 'orders_gearchiveerd', CASE WHEN p.gearchiveerd_at IS NULL THEN 0 ELSE COALESCE((public.voorraad_orders_gearchiveerd(p.id)->0->>'regels')::int, 0) END,
|
|
8170
|
+
'bijgewerkt', now());
|
|
8171
|
+
END $function$
|
|
8172
|
+
;
|
|
8173
|
+
REVOKE ALL ON FUNCTION voorraad_artikel_detail(uuid) FROM PUBLIC;
|
|
8174
|
+
REVOKE ALL ON FUNCTION voorraad_artikel_detail(uuid) FROM anon;
|
|
8175
|
+
GRANT EXECUTE ON FUNCTION voorraad_artikel_detail(uuid) TO authenticated;
|
|
8176
|
+
GRANT EXECUTE ON FUNCTION voorraad_artikel_detail(uuid) TO service_role;
|
|
8177
|
+
CREATE OR REPLACE FUNCTION public.voorraad_artikel_opslaan(p_id uuid, p_oud jsonb, p_nieuw jsonb)
|
|
8178
|
+
RETURNS jsonb
|
|
8179
|
+
LANGUAGE plpgsql
|
|
8180
|
+
SECURITY DEFINER
|
|
8181
|
+
SET search_path TO 'public'
|
|
8182
|
+
AS $function$
|
|
8183
|
+
DECLARE
|
|
8184
|
+
v_cur jsonb; k text; v_conf jsonb := '[]'::jsonb; v_set jsonb := '{}'::jsonb;
|
|
8185
|
+
v_toegestaan text[] := ARRAY['product','article_number','sale_price','unit','barcode'];
|
|
8186
|
+
BEGIN
|
|
8187
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_artikel_opslaan');
|
|
8188
|
+
IF NOT public.voorraad_can_write() THEN
|
|
8189
|
+
RAISE EXCEPTION 'Je hebt geen schrijfrechten op de voorraad.' USING ERRCODE = '42501'; END IF;
|
|
8190
|
+
IF jsonb_typeof(p_nieuw) IS DISTINCT FROM 'object' OR jsonb_typeof(p_oud) IS DISTINCT FROM 'object' THEN
|
|
8191
|
+
RAISE EXCEPTION 'Ongeldige invoer voor opslaan.' USING ERRCODE = '22023'; END IF;
|
|
8192
|
+
|
|
8193
|
+
SELECT jsonb_build_object('product', product, 'article_number', article_number, 'sale_price', sale_price,
|
|
8194
|
+
'unit', unit, 'barcode', barcode)
|
|
8195
|
+
INTO v_cur FROM public.products WHERE id = p_id FOR UPDATE;
|
|
8196
|
+
IF v_cur IS NULL THEN RAISE EXCEPTION 'Artikel niet gevonden.' USING ERRCODE = 'P0002'; END IF;
|
|
8197
|
+
|
|
8198
|
+
FOR k IN SELECT jsonb_object_keys(p_nieuw) LOOP
|
|
8199
|
+
IF NOT k = ANY(v_toegestaan) THEN
|
|
8200
|
+
RAISE EXCEPTION 'Veld "%" kan hier niet worden opgeslagen.', k USING ERRCODE = '22023'; END IF;
|
|
8201
|
+
IF NOT (p_oud ? k) THEN
|
|
8202
|
+
RAISE EXCEPTION 'Stand bij openen ontbreekt voor veld "%".', k USING ERRCODE = '22023'; END IF;
|
|
8203
|
+
-- Alleen velden die de gebruiker echt wijzigde.
|
|
8204
|
+
CONTINUE WHEN (p_nieuw->k) = (p_oud->k);
|
|
8205
|
+
IF (v_cur->k) IS DISTINCT FROM (p_oud->k) AND (v_cur->k) IS DISTINCT FROM (p_nieuw->k) THEN
|
|
8206
|
+
v_conf := v_conf || jsonb_build_object('veld', k, 'bij_openen', p_oud->k, 'jouw', p_nieuw->k, 'hun', v_cur->k);
|
|
8207
|
+
ELSE
|
|
8208
|
+
v_set := v_set || jsonb_build_object(k, p_nieuw->k);
|
|
8209
|
+
END IF;
|
|
8210
|
+
END LOOP;
|
|
8211
|
+
|
|
8212
|
+
IF jsonb_array_length(v_conf) > 0 THEN
|
|
8213
|
+
RETURN jsonb_build_object('ok', false, 'conflicten', v_conf);
|
|
8214
|
+
END IF;
|
|
8215
|
+
IF v_set ? 'sale_price' AND jsonb_typeof(v_set->'sale_price') = 'number' AND (v_set->>'sale_price')::numeric < 0 THEN
|
|
8216
|
+
RAISE EXCEPTION 'Verkoopprijs kan niet negatief zijn.' USING ERRCODE = '22023'; END IF;
|
|
8217
|
+
|
|
8218
|
+
IF v_set <> '{}'::jsonb THEN
|
|
8219
|
+
UPDATE public.products SET
|
|
8220
|
+
product = CASE WHEN v_set ? 'product' THEN NULLIF(btrim(v_set->>'product'),'') ELSE product END,
|
|
8221
|
+
article_number = CASE WHEN v_set ? 'article_number' THEN NULLIF(btrim(v_set->>'article_number'),'') ELSE article_number END,
|
|
8222
|
+
sale_price = CASE WHEN v_set ? 'sale_price' THEN (v_set->>'sale_price')::numeric ELSE sale_price END,
|
|
8223
|
+
unit = CASE WHEN v_set ? 'unit' THEN NULLIF(btrim(v_set->>'unit'),'') ELSE unit END,
|
|
8224
|
+
barcode = CASE WHEN v_set ? 'barcode' THEN NULLIF(btrim(v_set->>'barcode'),'') ELSE barcode END
|
|
8225
|
+
WHERE id = p_id;
|
|
8226
|
+
END IF;
|
|
8227
|
+
RETURN jsonb_build_object('ok', true, 'opgeslagen', v_set);
|
|
8228
|
+
END $function$
|
|
8229
|
+
;
|
|
8230
|
+
REVOKE ALL ON FUNCTION voorraad_artikel_opslaan(uuid,jsonb,jsonb) FROM PUBLIC;
|
|
8231
|
+
REVOKE ALL ON FUNCTION voorraad_artikel_opslaan(uuid,jsonb,jsonb) FROM anon;
|
|
8232
|
+
GRANT EXECUTE ON FUNCTION voorraad_artikel_opslaan(uuid,jsonb,jsonb) TO authenticated;
|
|
8233
|
+
GRANT EXECUTE ON FUNCTION voorraad_artikel_opslaan(uuid,jsonb,jsonb) TO service_role;
|
|
8038
8234
|
CREATE OR REPLACE FUNCTION public.voorraad_artikel_prijs(p_id text)
|
|
8039
8235
|
RETURNS TABLE(product_id uuid, sale_price numeric, unit text)
|
|
8040
8236
|
LANGUAGE plpgsql
|
|
@@ -9203,6 +9399,43 @@ REVOKE ALL ON FUNCTION voorraad_dubbele_voorraadregels() FROM PUBLIC;
|
|
|
9203
9399
|
REVOKE ALL ON FUNCTION voorraad_dubbele_voorraadregels() FROM anon;
|
|
9204
9400
|
GRANT EXECUTE ON FUNCTION voorraad_dubbele_voorraadregels() TO authenticated;
|
|
9205
9401
|
GRANT EXECUTE ON FUNCTION voorraad_dubbele_voorraadregels() TO service_role;
|
|
9402
|
+
CREATE OR REPLACE FUNCTION public.voorraad_eigen_velden_opslaan(p_id uuid, p_oud jsonb, p_nieuw jsonb)
|
|
9403
|
+
RETURNS jsonb
|
|
9404
|
+
LANGUAGE plpgsql
|
|
9405
|
+
SECURITY DEFINER
|
|
9406
|
+
SET search_path TO 'public'
|
|
9407
|
+
AS $function$
|
|
9408
|
+
DECLARE v_cur jsonb; k text; v_conf jsonb := '[]'::jsonb; v_set jsonb := '{}'::jsonb;
|
|
9409
|
+
BEGIN
|
|
9410
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_eigen_velden_opslaan');
|
|
9411
|
+
IF NOT public.voorraad_can_write() THEN
|
|
9412
|
+
RAISE EXCEPTION 'Je hebt geen schrijfrechten op de voorraad.' USING ERRCODE = '42501'; END IF;
|
|
9413
|
+
IF jsonb_typeof(p_nieuw) IS DISTINCT FROM 'object' OR jsonb_typeof(p_oud) IS DISTINCT FROM 'object' THEN
|
|
9414
|
+
RAISE EXCEPTION 'Ongeldige invoer voor opslaan.' USING ERRCODE = '22023'; END IF;
|
|
9415
|
+
SELECT COALESCE(custom_fields, '{}'::jsonb) INTO v_cur FROM public.products WHERE id = p_id FOR UPDATE;
|
|
9416
|
+
IF NOT FOUND THEN RAISE EXCEPTION 'Artikel niet gevonden.' USING ERRCODE = 'P0002'; END IF;
|
|
9417
|
+
FOR k IN SELECT jsonb_object_keys(p_nieuw) LOOP
|
|
9418
|
+
IF NOT EXISTS (SELECT 1 FROM public.voorraad_custom_fields f WHERE f.field_key = k) THEN
|
|
9419
|
+
RAISE EXCEPTION 'Veld "%" is geen eigen veld.', k USING ERRCODE = '22023'; END IF;
|
|
9420
|
+
CONTINUE WHEN COALESCE(p_nieuw->k, 'null'::jsonb) = COALESCE(p_oud->k, 'null'::jsonb);
|
|
9421
|
+
IF COALESCE(v_cur->k,'null'::jsonb) IS DISTINCT FROM COALESCE(p_oud->k,'null'::jsonb)
|
|
9422
|
+
AND COALESCE(v_cur->k,'null'::jsonb) IS DISTINCT FROM COALESCE(p_nieuw->k,'null'::jsonb) THEN
|
|
9423
|
+
v_conf := v_conf || jsonb_build_object('veld', k, 'bij_openen', p_oud->k, 'jouw', p_nieuw->k, 'hun', v_cur->k);
|
|
9424
|
+
ELSE
|
|
9425
|
+
v_set := v_set || jsonb_build_object(k, p_nieuw->k);
|
|
9426
|
+
END IF;
|
|
9427
|
+
END LOOP;
|
|
9428
|
+
IF jsonb_array_length(v_conf) > 0 THEN RETURN jsonb_build_object('ok', false, 'conflicten', v_conf); END IF;
|
|
9429
|
+
IF v_set <> '{}'::jsonb THEN
|
|
9430
|
+
UPDATE public.products SET custom_fields = COALESCE(custom_fields,'{}'::jsonb) || v_set, updated_at = now() WHERE id = p_id;
|
|
9431
|
+
END IF;
|
|
9432
|
+
RETURN jsonb_build_object('ok', true, 'opgeslagen', v_set);
|
|
9433
|
+
END $function$
|
|
9434
|
+
;
|
|
9435
|
+
REVOKE ALL ON FUNCTION voorraad_eigen_velden_opslaan(uuid,jsonb,jsonb) FROM PUBLIC;
|
|
9436
|
+
REVOKE ALL ON FUNCTION voorraad_eigen_velden_opslaan(uuid,jsonb,jsonb) FROM anon;
|
|
9437
|
+
GRANT EXECUTE ON FUNCTION voorraad_eigen_velden_opslaan(uuid,jsonb,jsonb) TO authenticated;
|
|
9438
|
+
GRANT EXECUTE ON FUNCTION voorraad_eigen_velden_opslaan(uuid,jsonb,jsonb) TO service_role;
|
|
9206
9439
|
CREATE OR REPLACE FUNCTION public.voorraad_ensure_defaults()
|
|
9207
9440
|
RETURNS jsonb
|
|
9208
9441
|
LANGUAGE plpgsql
|
|
@@ -9602,6 +9835,22 @@ $function$
|
|
|
9602
9835
|
REVOKE ALL ON FUNCTION voorraad_floriday_leads_key(text) FROM PUBLIC;
|
|
9603
9836
|
REVOKE ALL ON FUNCTION voorraad_floriday_leads_key(text) FROM anon;
|
|
9604
9837
|
GRANT EXECUTE ON FUNCTION voorraad_floriday_leads_key(text) TO service_role;
|
|
9838
|
+
CREATE OR REPLACE FUNCTION public.voorraad_floriday_volgt(p_product_id uuid)
|
|
9839
|
+
RETURNS boolean
|
|
9840
|
+
LANGUAGE plpgsql
|
|
9841
|
+
STABLE SECURITY DEFINER
|
|
9842
|
+
SET search_path TO 'public'
|
|
9843
|
+
AS $function$
|
|
9844
|
+
BEGIN
|
|
9845
|
+
PERFORM public.voorraad_vereis('server', 'voorraad_floriday_volgt');
|
|
9846
|
+
RETURN EXISTS (SELECT 1 FROM public.floriday_inventory_settings s
|
|
9847
|
+
WHERE s.product_id = p_product_id AND s.erp_leading IS TRUE
|
|
9848
|
+
AND COALESCE(s.stock_mode,'') <> 'DISABLED');
|
|
9849
|
+
END $function$
|
|
9850
|
+
;
|
|
9851
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_volgt(uuid) FROM PUBLIC;
|
|
9852
|
+
REVOKE ALL ON FUNCTION voorraad_floriday_volgt(uuid) FROM anon;
|
|
9853
|
+
GRANT EXECUTE ON FUNCTION voorraad_floriday_volgt(uuid) TO service_role;
|
|
9605
9854
|
CREATE OR REPLACE FUNCTION public.voorraad_fust_bijhouden(p_fust_type_id uuid)
|
|
9606
9855
|
RETURNS boolean
|
|
9607
9856
|
LANGUAGE sql
|
|
@@ -9989,7 +10238,7 @@ CREATE OR REPLACE FUNCTION public.voorraad_install_check()
|
|
|
9989
10238
|
STABLE SECURITY DEFINER
|
|
9990
10239
|
SET search_path TO 'public'
|
|
9991
10240
|
AS $function$
|
|
9992
|
-
DECLARE v_f text[] := ARRAY['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'];
|
|
10241
|
+
DECLARE v_f text[] := ARRAY['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'];
|
|
9993
10242
|
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'];
|
|
9994
10243
|
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'];
|
|
9995
10244
|
v_open text[] := ARRAY['voorraad_is_server','voorraad_vereis'];
|
|
@@ -10034,6 +10283,22 @@ REVOKE ALL ON FUNCTION voorraad_install_check() FROM PUBLIC;
|
|
|
10034
10283
|
REVOKE ALL ON FUNCTION voorraad_install_check() FROM anon;
|
|
10035
10284
|
GRANT EXECUTE ON FUNCTION voorraad_install_check() TO authenticated;
|
|
10036
10285
|
GRANT EXECUTE ON FUNCTION voorraad_install_check() TO service_role;
|
|
10286
|
+
CREATE OR REPLACE FUNCTION public.voorraad_instellingen_lezen()
|
|
10287
|
+
RETURNS jsonb
|
|
10288
|
+
LANGUAGE plpgsql
|
|
10289
|
+
STABLE SECURITY DEFINER
|
|
10290
|
+
SET search_path TO 'public'
|
|
10291
|
+
AS $function$
|
|
10292
|
+
BEGIN
|
|
10293
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_instellingen_lezen');
|
|
10294
|
+
RETURN jsonb_build_object('standaard_sturing',
|
|
10295
|
+
COALESCE((SELECT standaard_sturing_nieuwe_floriday FROM public.voorraad_instellingen WHERE id), 'lokaal'));
|
|
10296
|
+
END $function$
|
|
10297
|
+
;
|
|
10298
|
+
REVOKE ALL ON FUNCTION voorraad_instellingen_lezen() FROM PUBLIC;
|
|
10299
|
+
REVOKE ALL ON FUNCTION voorraad_instellingen_lezen() FROM anon;
|
|
10300
|
+
GRANT EXECUTE ON FUNCTION voorraad_instellingen_lezen() TO authenticated;
|
|
10301
|
+
GRANT EXECUTE ON FUNCTION voorraad_instellingen_lezen() TO service_role;
|
|
10037
10302
|
CREATE OR REPLACE FUNCTION public.voorraad_instellingen_opslaan(p_standaard_sturing text)
|
|
10038
10303
|
RETURNS jsonb
|
|
10039
10304
|
LANGUAGE plpgsql
|
|
@@ -10120,6 +10385,160 @@ REVOKE ALL ON FUNCTION voorraad_lever_datum(text) FROM PUBLIC;
|
|
|
10120
10385
|
REVOKE ALL ON FUNCTION voorraad_lever_datum(text) FROM anon;
|
|
10121
10386
|
GRANT EXECUTE ON FUNCTION voorraad_lever_datum(text) TO authenticated;
|
|
10122
10387
|
GRANT EXECUTE ON FUNCTION voorraad_lever_datum(text) TO service_role;
|
|
10388
|
+
CREATE OR REPLACE FUNCTION public.voorraad_lijst(p_zoek text DEFAULT NULL::text, p_filter text DEFAULT 'alles'::text, p_sort text DEFAULT 'naam'::text, p_oplopend boolean DEFAULT true, p_pagina integer DEFAULT 1, p_grootte integer DEFAULT 25)
|
|
10389
|
+
RETURNS jsonb
|
|
10390
|
+
LANGUAGE plpgsql
|
|
10391
|
+
STABLE SECURITY DEFINER
|
|
10392
|
+
SET search_path TO 'public'
|
|
10393
|
+
AS $function$
|
|
10394
|
+
DECLARE
|
|
10395
|
+
v_conn uuid; v_ctx uuid; v_kop boolean; v_gr int; v_off int; v_q text;
|
|
10396
|
+
v_tel jsonb; v_totaal int; v_rijen jsonb; v_meld jsonb; v_twijfel int; v_twijfel_rijen jsonb := '[]'::jsonb;
|
|
10397
|
+
BEGIN
|
|
10398
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_lijst');
|
|
10399
|
+
IF COALESCE(p_filter,'alles') NOT IN ('alles','onder_minimum','verpakking','niet_gekoppeld','prijs','twijfel','gearchiveerd') THEN
|
|
10400
|
+
RAISE EXCEPTION 'Onbekend filter "%"', p_filter USING ERRCODE = '22023';
|
|
10401
|
+
END IF;
|
|
10402
|
+
IF COALESCE(p_sort,'naam') NOT IN ('naam','artikelnummer','liggend','gereserveerd','vrij','inkomend','prijs') THEN
|
|
10403
|
+
RAISE EXCEPTION 'Onbekende sortering "%"', p_sort USING ERRCODE = '22023';
|
|
10404
|
+
END IF;
|
|
10405
|
+
v_gr := LEAST(GREATEST(COALESCE(p_grootte,25),1),500);
|
|
10406
|
+
v_off := (GREATEST(COALESCE(p_pagina,1),1) - 1) * v_gr;
|
|
10407
|
+
v_q := NULLIF(btrim(COALESCE(p_zoek,'')),'');
|
|
10408
|
+
BEGIN SELECT x.connection_id INTO v_conn FROM public.get_active_floriday_context() x LIMIT 1;
|
|
10409
|
+
EXCEPTION WHEN others THEN v_conn := NULL; END;
|
|
10410
|
+
v_kop := v_conn IS NOT NULL;
|
|
10411
|
+
BEGIN SELECT c.connection_id INTO v_ctx FROM public.get_stock_context() c LIMIT 1;
|
|
10412
|
+
EXCEPTION WHEN others THEN v_ctx := NULL; END;
|
|
10413
|
+
|
|
10414
|
+
WITH st AS (
|
|
10415
|
+
SELECT DISTINCT ON (x.trade_item_key) x.trade_item_key, x.physical_stock, x.reserved_stock, x.minimum_stock, x.incoming_stock
|
|
10416
|
+
FROM public.trade_item_stock x WHERE x.archived_at IS NULL
|
|
10417
|
+
ORDER BY x.trade_item_key, (x.connection_id IS NOT DISTINCT FROM v_ctx) DESC, x.updated_at DESC
|
|
10418
|
+
), basis AS (
|
|
10419
|
+
SELECT p.id,
|
|
10420
|
+
COALESCE(NULLIF(btrim(p.product),''), NULLIF(p.custom_fields#>>'{floriday_payload,name}',''), '(naamloos)') AS naam,
|
|
10421
|
+
COALESCE(NULLIF(btrim(p.article_number),''), NULLIF(p.custom_fields#>>'{floriday_payload,articleCode}','')) AS artikelnummer,
|
|
10422
|
+
NULLIF(btrim(COALESCE(p.floriday_trade_item_id,'')),'') AS floriday_id,
|
|
10423
|
+
p.sale_price AS prijs, p.unit AS eenheid, p.gearchiveerd_at, p.barcode,
|
|
10424
|
+
-- Voorraadkolommen zijn NOT NULL: COALESCE kiest dus de eerste bestaande rij (s1, dan s2, dan s3).
|
|
10425
|
+
COALESCE(s1.physical_stock, s2.physical_stock, s3.physical_stock, 0) AS liggend,
|
|
10426
|
+
COALESCE(s1.reserved_stock, s2.reserved_stock, s3.reserved_stock, 0) AS gereserveerd,
|
|
10427
|
+
COALESCE(s1.minimum_stock, s2.minimum_stock, s3.minimum_stock, 0) AS minimum,
|
|
10428
|
+
COALESCE(s1.incoming_stock, s2.incoming_stock, s3.incoming_stock, 0) AS inkomend,
|
|
10429
|
+
COALESCE(s1.trade_item_key, s2.trade_item_key, s3.trade_item_key) AS voorraad_sleutel,
|
|
10430
|
+
CASE WHEN EXISTS (SELECT 1 FROM public.product_groups g WHERE g.head_product_id = p.id AND g.is_active) THEN 'GROUP'
|
|
10431
|
+
WHEN EXISTS (SELECT 1 FROM public.product_bom_items b WHERE b.parent_product_id = p.id) THEN 'SET'
|
|
10432
|
+
ELSE 'NORMAL' END AS soort,
|
|
10433
|
+
EXISTS (SELECT 1 FROM public.product_bom_items b WHERE b.component_product_id = p.id) AS is_onderdeel,
|
|
10434
|
+
EXISTS (SELECT 1 FROM public.product_packings k WHERE k.product_id = p.id AND k.is_primary) AS heeft_verpakking,
|
|
10435
|
+
COALESCE((p.custom_fields#>>'{voorraad_packing_link,ok}')::boolean, true) AS verpakking_ok
|
|
10436
|
+
FROM public.products p
|
|
10437
|
+
-- Zelfde volgorde als voorraad_canoniek_sleutel: trade_item_key, dan Floriday-id, dan product:<id>.
|
|
10438
|
+
LEFT JOIN st s1 ON s1.trade_item_key = NULLIF(btrim(COALESCE(p.trade_item_key,'')),'')
|
|
10439
|
+
LEFT JOIN st s2 ON s2.trade_item_key = NULLIF(btrim(COALESCE(p.floriday_trade_item_id,'')),'')
|
|
10440
|
+
LEFT JOIN st s3 ON s3.trade_item_key = 'product:' || p.id::text
|
|
10441
|
+
-- Spiegels (id = Floriday-id van een ander artikel) tellen niet mee.
|
|
10442
|
+
WHERE NOT EXISTS (SELECT 1 FROM public.products q
|
|
10443
|
+
WHERE q.id <> p.id AND NULLIF(btrim(COALESCE(q.floriday_trade_item_id,'')),'') IS NOT NULL
|
|
10444
|
+
AND lower(btrim(q.floriday_trade_item_id)) = lower(p.id::text))
|
|
10445
|
+
), gemarkeerd AS (
|
|
10446
|
+
SELECT b.*,
|
|
10447
|
+
GREATEST(b.liggend - b.gereserveerd, 0) AS vrij,
|
|
10448
|
+
(b.minimum > 0 AND (b.liggend - b.gereserveerd) < b.minimum) AS f_onder_minimum,
|
|
10449
|
+
(b.soort <> 'GROUP' AND (NOT b.heeft_verpakking OR NOT b.verpakking_ok)) AS f_verpakking,
|
|
10450
|
+
(v_kop AND b.floriday_id IS NULL) AS f_niet_gekoppeld,
|
|
10451
|
+
(lower(btrim(COALESCE(b.eenheid,''))) <> 'stuks' OR b.prijs IS NULL OR b.prijs <= 0) AS f_prijs
|
|
10452
|
+
FROM basis b
|
|
10453
|
+
WHERE v_q IS NULL
|
|
10454
|
+
OR b.naam ILIKE '%' || v_q || '%' OR COALESCE(b.artikelnummer,'') ILIKE '%' || v_q || '%'
|
|
10455
|
+
OR COALESCE(b.barcode,'') ILIKE '%' || v_q || '%' OR COALESCE(b.floriday_id,'') ILIKE v_q || '%'
|
|
10456
|
+
), tel AS (
|
|
10457
|
+
SELECT jsonb_build_object(
|
|
10458
|
+
'alles', count(*) FILTER (WHERE gearchiveerd_at IS NULL),
|
|
10459
|
+
'onder_minimum', count(*) FILTER (WHERE gearchiveerd_at IS NULL AND f_onder_minimum),
|
|
10460
|
+
'verpakking', count(*) FILTER (WHERE gearchiveerd_at IS NULL AND f_verpakking),
|
|
10461
|
+
'niet_gekoppeld', count(*) FILTER (WHERE gearchiveerd_at IS NULL AND f_niet_gekoppeld),
|
|
10462
|
+
'prijs', count(*) FILTER (WHERE gearchiveerd_at IS NULL AND f_prijs),
|
|
10463
|
+
'gearchiveerd', count(*) FILTER (WHERE gearchiveerd_at IS NOT NULL),
|
|
10464
|
+
'onderdelen_zonder_prijs', count(*) FILTER (WHERE gearchiveerd_at IS NULL AND is_onderdeel AND f_prijs)) AS t
|
|
10465
|
+
FROM gemarkeerd
|
|
10466
|
+
), gefilterd AS (
|
|
10467
|
+
SELECT * FROM gemarkeerd g
|
|
10468
|
+
WHERE CASE COALESCE(p_filter,'alles')
|
|
10469
|
+
WHEN 'gearchiveerd' THEN g.gearchiveerd_at IS NOT NULL
|
|
10470
|
+
WHEN 'twijfel' THEN false
|
|
10471
|
+
ELSE g.gearchiveerd_at IS NULL AND CASE p_filter
|
|
10472
|
+
WHEN 'onder_minimum' THEN g.f_onder_minimum
|
|
10473
|
+
WHEN 'verpakking' THEN g.f_verpakking
|
|
10474
|
+
WHEN 'niet_gekoppeld' THEN g.f_niet_gekoppeld
|
|
10475
|
+
WHEN 'prijs' THEN g.f_prijs
|
|
10476
|
+
ELSE true END
|
|
10477
|
+
END
|
|
10478
|
+
), pagina AS (
|
|
10479
|
+
SELECT * FROM gefilterd
|
|
10480
|
+
ORDER BY
|
|
10481
|
+
CASE WHEN p_oplopend AND p_sort = 'naam' THEN lower(naam) END ASC,
|
|
10482
|
+
CASE WHEN NOT p_oplopend AND p_sort = 'naam' THEN lower(naam) END DESC,
|
|
10483
|
+
CASE WHEN p_oplopend AND p_sort = 'artikelnummer' THEN lower(artikelnummer) END ASC NULLS LAST,
|
|
10484
|
+
CASE WHEN NOT p_oplopend AND p_sort = 'artikelnummer' THEN lower(artikelnummer) END DESC NULLS LAST,
|
|
10485
|
+
CASE WHEN p_sort NOT IN ('naam','artikelnummer') THEN
|
|
10486
|
+
(CASE p_sort WHEN 'liggend' THEN liggend WHEN 'gereserveerd' THEN gereserveerd WHEN 'vrij' THEN vrij
|
|
10487
|
+
WHEN 'inkomend' THEN inkomend ELSE prijs END)::numeric * CASE WHEN p_oplopend THEN 1 ELSE -1 END
|
|
10488
|
+
END ASC NULLS LAST,
|
|
10489
|
+
lower(naam), id
|
|
10490
|
+
LIMIT v_gr OFFSET v_off
|
|
10491
|
+
)
|
|
10492
|
+
SELECT (SELECT t FROM tel), (SELECT count(*) FROM gefilterd),
|
|
10493
|
+
(SELECT COALESCE(jsonb_agg(jsonb_build_object(
|
|
10494
|
+
'id', pg.id, 'naam', pg.naam, 'artikelnummer', pg.artikelnummer,
|
|
10495
|
+
'foto', COALESCE(NULLIF(p.image_url,''), NULLIF(p.custom_fields#>>'{floriday_payload,images,0,url}',''), NULLIF(p.custom_fields#>>'{floriday_payload,images,0,previewUrl}','')),
|
|
10496
|
+
'floriday_id', pg.floriday_id,
|
|
10497
|
+
'prijs', pg.prijs, 'eenheid', pg.eenheid, 'soort', pg.soort, 'is_onderdeel', pg.is_onderdeel,
|
|
10498
|
+
'liggend', pg.liggend, 'gereserveerd', pg.gereserveerd, 'minimum', pg.minimum, 'inkomend', pg.inkomend, 'vrij', pg.vrij,
|
|
10499
|
+
'voorraad_sleutel', pg.voorraad_sleutel, 'gearchiveerd_at', pg.gearchiveerd_at,
|
|
10500
|
+
'onder_minimum', pg.f_onder_minimum,
|
|
10501
|
+
'status', CASE WHEN pg.gearchiveerd_at IS NOT NULL THEN 'gearchiveerd'
|
|
10502
|
+
WHEN pg.f_verpakking THEN 'verpakking' WHEN pg.f_niet_gekoppeld THEN 'niet_gekoppeld'
|
|
10503
|
+
WHEN pg.f_prijs THEN 'prijs' ELSE 'ok' END)
|
|
10504
|
+
ORDER BY pg.rn), '[]'::jsonb)
|
|
10505
|
+
FROM (SELECT pagina.*, row_number() OVER () AS rn FROM pagina) pg JOIN public.products p ON p.id = pg.id)
|
|
10506
|
+
INTO v_tel, v_totaal, v_rijen;
|
|
10507
|
+
|
|
10508
|
+
-- Samenstellingen en productgroepen: vrij beschikbaar uit de gedeelde rekenfunctie (alleen voor deze pagina).
|
|
10509
|
+
IF v_ctx IS NOT NULL THEN
|
|
10510
|
+
SELECT COALESCE(jsonb_agg(CASE WHEN r->>'soort' IN ('SET','GROUP') THEN
|
|
10511
|
+
r || jsonb_build_object('vrij', COALESCE((public.calculate_structure_available(v_ctx, (r->>'id')::uuid)->>'available')::numeric, 0))
|
|
10512
|
+
ELSE r END ORDER BY o), '[]'::jsonb)
|
|
10513
|
+
INTO v_rijen FROM jsonb_array_elements(v_rijen) WITH ORDINALITY AS e(r, o);
|
|
10514
|
+
END IF;
|
|
10515
|
+
|
|
10516
|
+
SELECT count(*) INTO v_twijfel FROM public.voorraad_koppel_twijfel WHERE opgelost_at IS NULL;
|
|
10517
|
+
IF p_filter = 'twijfel' THEN
|
|
10518
|
+
v_totaal := v_twijfel;
|
|
10519
|
+
SELECT COALESCE(jsonb_agg(jsonb_build_object('floriday_id', t.floriday_id, 'naam', t.naam, 'reden', t.reden,
|
|
10520
|
+
'kandidaten', COALESCE(jsonb_array_length(CASE WHEN jsonb_typeof(t.kandidaten)='array' THEN t.kandidaten END),0),
|
|
10521
|
+
'laatst_gezien', t.laatst_gezien) ORDER BY t.laatst_gezien DESC), '[]'::jsonb)
|
|
10522
|
+
INTO v_twijfel_rijen
|
|
10523
|
+
FROM (SELECT * FROM public.voorraad_koppel_twijfel WHERE opgelost_at IS NULL
|
|
10524
|
+
ORDER BY laatst_gezien DESC LIMIT v_gr OFFSET v_off) t;
|
|
10525
|
+
END IF;
|
|
10526
|
+
|
|
10527
|
+
v_meld := jsonb_build_object(
|
|
10528
|
+
'telmoment_ontbreekt', NOT EXISTS (SELECT 1 FROM public.voorraad_telmoment),
|
|
10529
|
+
'onderdelen_zonder_prijs', COALESCE((v_tel->>'onderdelen_zonder_prijs')::int, 0),
|
|
10530
|
+
'orders_gearchiveerd', public.voorraad_orders_gearchiveerd(NULL));
|
|
10531
|
+
|
|
10532
|
+
RETURN jsonb_build_object('tellers', v_tel || jsonb_build_object('twijfel', v_twijfel),
|
|
10533
|
+
'totaal', v_totaal, 'rijen', v_rijen, 'twijfel_rijen', v_twijfel_rijen,
|
|
10534
|
+
'meldingen', v_meld, 'heeft_koppeling', v_kop, 'pagina', GREATEST(COALESCE(p_pagina,1),1), 'grootte', v_gr,
|
|
10535
|
+
'bijgewerkt', now());
|
|
10536
|
+
END $function$
|
|
10537
|
+
;
|
|
10538
|
+
REVOKE ALL ON FUNCTION voorraad_lijst(text,text,text,boolean,integer,integer) FROM PUBLIC;
|
|
10539
|
+
REVOKE ALL ON FUNCTION voorraad_lijst(text,text,text,boolean,integer,integer) FROM anon;
|
|
10540
|
+
GRANT EXECUTE ON FUNCTION voorraad_lijst(text,text,text,boolean,integer,integer) TO authenticated;
|
|
10541
|
+
GRANT EXECUTE ON FUNCTION voorraad_lijst(text,text,text,boolean,integer,integer) TO service_role;
|
|
10123
10542
|
CREATE OR REPLACE FUNCTION public.voorraad_load_carriers()
|
|
10124
10543
|
RETURNS TABLE(code text, naam text, volgorde integer)
|
|
10125
10544
|
LANGUAGE plpgsql
|
|
@@ -10283,6 +10702,33 @@ REVOKE ALL ON FUNCTION voorraad_orderregel_trade_item_bron(uuid,text) FROM PUBLI
|
|
|
10283
10702
|
REVOKE ALL ON FUNCTION voorraad_orderregel_trade_item_bron(uuid,text) FROM anon;
|
|
10284
10703
|
GRANT EXECUTE ON FUNCTION voorraad_orderregel_trade_item_bron(uuid,text) TO authenticated;
|
|
10285
10704
|
GRANT EXECUTE ON FUNCTION voorraad_orderregel_trade_item_bron(uuid,text) TO service_role;
|
|
10705
|
+
CREATE OR REPLACE FUNCTION public.voorraad_orders_gearchiveerd(p_product_id uuid DEFAULT NULL::uuid)
|
|
10706
|
+
RETURNS jsonb
|
|
10707
|
+
LANGUAGE plpgsql
|
|
10708
|
+
STABLE SECURITY DEFINER
|
|
10709
|
+
SET search_path TO 'public'
|
|
10710
|
+
AS $function$
|
|
10711
|
+
BEGIN
|
|
10712
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_orders_gearchiveerd');
|
|
10713
|
+
RETURN COALESCE((
|
|
10714
|
+
SELECT jsonb_agg(jsonb_build_object('id', x.id, 'naam', x.naam, 'regels', x.regels, 'laatste', x.laatste) ORDER BY x.laatste DESC)
|
|
10715
|
+
FROM (
|
|
10716
|
+
SELECT p.id, COALESCE(NULLIF(btrim(p.product),''), '(naamloos)') AS naam, count(*) AS regels, max(oi.created_at) AS laatste
|
|
10717
|
+
FROM public.products p
|
|
10718
|
+
JOIN public.order_items oi ON oi.product_id = p.id AND oi.created_at >= p.gearchiveerd_at AND oi.quarantined_at IS NULL
|
|
10719
|
+
JOIN public.orders o ON o.id = oi.order_id
|
|
10720
|
+
WHERE p.gearchiveerd_at IS NOT NULL
|
|
10721
|
+
AND (p_product_id IS NULL OR p.id = p_product_id)
|
|
10722
|
+
AND NOT public.voorraad_order_geannuleerd(o.status, o.cancelled_at, o.deleted_at)
|
|
10723
|
+
AND lower(COALESCE(o.status,'')) NOT IN ('verzonden','gereed voor facturatie')
|
|
10724
|
+
GROUP BY p.id
|
|
10725
|
+
LIMIT 20) x), '[]'::jsonb);
|
|
10726
|
+
END $function$
|
|
10727
|
+
;
|
|
10728
|
+
REVOKE ALL ON FUNCTION voorraad_orders_gearchiveerd(uuid) FROM PUBLIC;
|
|
10729
|
+
REVOKE ALL ON FUNCTION voorraad_orders_gearchiveerd(uuid) FROM anon;
|
|
10730
|
+
GRANT EXECUTE ON FUNCTION voorraad_orders_gearchiveerd(uuid) TO authenticated;
|
|
10731
|
+
GRANT EXECUTE ON FUNCTION voorraad_orders_gearchiveerd(uuid) TO service_role;
|
|
10286
10732
|
CREATE OR REPLACE FUNCTION public.voorraad_overzicht_orderregel_koppeling(p_voorbeelden integer DEFAULT 5)
|
|
10287
10733
|
RETURNS jsonb
|
|
10288
10734
|
LANGUAGE plpgsql
|
|
@@ -10764,6 +11210,165 @@ GRANT EXECUTE ON FUNCTION voorraad_touch_updated_at() TO service_role;
|
|
|
10764
11210
|
REVOKE EXECUTE ON FUNCTION voorraad_touch_updated_at() FROM anon;
|
|
10765
11211
|
GRANT EXECUTE ON FUNCTION voorraad_touch_updated_at() TO authenticated;
|
|
10766
11212
|
GRANT EXECUTE ON FUNCTION voorraad_touch_updated_at() TO service_role;
|
|
11213
|
+
CREATE OR REPLACE FUNCTION public.voorraad_traysticker_opslaan(p_product_id uuid, p_oud_pad text, p_nieuw jsonb)
|
|
11214
|
+
RETURNS jsonb
|
|
11215
|
+
LANGUAGE plpgsql
|
|
11216
|
+
SECURITY DEFINER
|
|
11217
|
+
SET search_path TO 'public'
|
|
11218
|
+
AS $function$
|
|
11219
|
+
DECLARE v_cur text; v_bestaat boolean;
|
|
11220
|
+
BEGIN
|
|
11221
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_traysticker_opslaan');
|
|
11222
|
+
IF NOT public.voorraad_can_write() THEN
|
|
11223
|
+
RAISE EXCEPTION 'Je hebt geen schrijfrechten op de voorraad.' USING ERRCODE = '42501'; END IF;
|
|
11224
|
+
PERFORM 1 FROM public.products WHERE id = p_product_id FOR UPDATE;
|
|
11225
|
+
IF NOT FOUND THEN RAISE EXCEPTION 'Artikel niet gevonden.' USING ERRCODE = 'P0002'; END IF;
|
|
11226
|
+
SELECT true, bestandspad INTO v_bestaat, v_cur FROM public.product_tray_stickers WHERE product_id = p_product_id;
|
|
11227
|
+
IF v_cur IS DISTINCT FROM p_oud_pad THEN
|
|
11228
|
+
RETURN jsonb_build_object('ok', false, 'conflicten', jsonb_build_array(jsonb_build_object(
|
|
11229
|
+
'veld', 'traysticker', 'bij_openen', p_oud_pad, 'hun', v_cur)));
|
|
11230
|
+
END IF;
|
|
11231
|
+
IF p_nieuw IS NULL THEN
|
|
11232
|
+
DELETE FROM public.product_tray_stickers WHERE product_id = p_product_id;
|
|
11233
|
+
ELSE
|
|
11234
|
+
IF NULLIF(btrim(COALESCE(p_nieuw->>'bestand_url','')),'') IS NULL THEN
|
|
11235
|
+
RAISE EXCEPTION 'Geen bestand opgegeven.' USING ERRCODE = '22023'; END IF;
|
|
11236
|
+
INSERT INTO public.product_tray_stickers(product_id, bestand_url, bestandspad, bestandsnaam, bestandsgrootte)
|
|
11237
|
+
VALUES (p_product_id, p_nieuw->>'bestand_url', p_nieuw->>'bestandspad', p_nieuw->>'bestandsnaam', (p_nieuw->>'bestandsgrootte')::int)
|
|
11238
|
+
ON CONFLICT (product_id) DO UPDATE SET bestand_url = EXCLUDED.bestand_url, bestandspad = EXCLUDED.bestandspad,
|
|
11239
|
+
bestandsnaam = EXCLUDED.bestandsnaam, bestandsgrootte = EXCLUDED.bestandsgrootte, updated_at = now();
|
|
11240
|
+
END IF;
|
|
11241
|
+
RETURN jsonb_build_object('ok', true, 'oud_pad', v_cur);
|
|
11242
|
+
END $function$
|
|
11243
|
+
;
|
|
11244
|
+
REVOKE ALL ON FUNCTION voorraad_traysticker_opslaan(uuid,text,jsonb) FROM PUBLIC;
|
|
11245
|
+
REVOKE ALL ON FUNCTION voorraad_traysticker_opslaan(uuid,text,jsonb) FROM anon;
|
|
11246
|
+
GRANT EXECUTE ON FUNCTION voorraad_traysticker_opslaan(uuid,text,jsonb) TO authenticated;
|
|
11247
|
+
GRANT EXECUTE ON FUNCTION voorraad_traysticker_opslaan(uuid,text,jsonb) TO service_role;
|
|
11248
|
+
CREATE OR REPLACE FUNCTION public.voorraad_twijfel_kiezen(p_floriday_id text, p_product_id uuid)
|
|
11249
|
+
RETURNS jsonb
|
|
11250
|
+
LANGUAGE plpgsql
|
|
11251
|
+
SECURITY DEFINER
|
|
11252
|
+
SET search_path TO 'public'
|
|
11253
|
+
AS $function$
|
|
11254
|
+
DECLARE t public.voorraad_koppel_twijfel%ROWTYPE; p public.products%ROWTYPE; v_eigen text; v_fl_stock numeric; v_eigen_stock numeric;
|
|
11255
|
+
BEGIN
|
|
11256
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_twijfel_kiezen');
|
|
11257
|
+
IF NOT public.voorraad_can_write() THEN
|
|
11258
|
+
RAISE EXCEPTION 'Je hebt geen schrijfrechten op de voorraad.' USING ERRCODE = '42501'; END IF;
|
|
11259
|
+
SELECT * INTO t FROM public.voorraad_koppel_twijfel WHERE floriday_id = p_floriday_id FOR UPDATE;
|
|
11260
|
+
IF NOT FOUND OR t.opgelost_at IS NOT NULL THEN
|
|
11261
|
+
RAISE EXCEPTION 'Dit twijfelgeval is al opgelost of bestaat niet meer.' USING ERRCODE = 'P0002'; END IF;
|
|
11262
|
+
SELECT * INTO p FROM public.products WHERE id = p_product_id FOR UPDATE;
|
|
11263
|
+
IF NOT FOUND THEN RAISE EXCEPTION 'Artikel niet gevonden.' USING ERRCODE = 'P0002'; END IF;
|
|
11264
|
+
IF NULLIF(btrim(COALESCE(p.floriday_trade_item_id,'')),'') IS NOT NULL AND lower(btrim(p.floriday_trade_item_id)) <> lower(p_floriday_id) THEN
|
|
11265
|
+
RAISE EXCEPTION 'Dit artikel is al aan een ander Floriday-product gekoppeld.' USING ERRCODE = '23505'; END IF;
|
|
11266
|
+
IF EXISTS (SELECT 1 FROM public.products q WHERE q.id <> p.id AND lower(btrim(COALESCE(q.floriday_trade_item_id,''))) = lower(p_floriday_id)) THEN
|
|
11267
|
+
RAISE EXCEPTION 'Een ander artikel is al aan dit Floriday-product gekoppeld.' USING ERRCODE = '23505'; END IF;
|
|
11268
|
+
-- Twee eigen voorraadregels met voorraad: eerst samenvoegen (nooit stil optellen of weggooien).
|
|
11269
|
+
v_eigen := public.voorraad_canoniek_sleutel(p.id);
|
|
11270
|
+
SELECT COALESCE(sum(physical_stock),0) INTO v_fl_stock FROM public.trade_item_stock WHERE trade_item_key = p_floriday_id AND archived_at IS NULL;
|
|
11271
|
+
SELECT COALESCE(sum(physical_stock),0) INTO v_eigen_stock FROM public.trade_item_stock WHERE trade_item_key = v_eigen AND archived_at IS NULL;
|
|
11272
|
+
IF v_eigen IS DISTINCT FROM p_floriday_id AND v_fl_stock > 0 AND v_eigen_stock > 0 THEN
|
|
11273
|
+
RAISE EXCEPTION 'Het artikel en het Floriday-product hebben elk een eigen voorraad (% en %). Voeg die eerst samen.', v_eigen_stock, v_fl_stock USING ERRCODE = '23505'; END IF;
|
|
11274
|
+
|
|
11275
|
+
UPDATE public.products SET floriday_trade_item_id = p_floriday_id, updated_at = now() WHERE id = p.id;
|
|
11276
|
+
INSERT INTO public.voorraad_koppel_log(run_id, soort, floriday_id, product_id, oud, nieuw)
|
|
11277
|
+
VALUES (gen_random_uuid(), 'zelf_gekozen', p_floriday_id, p.id,
|
|
11278
|
+
jsonb_build_object('floriday_trade_item_id', p.floriday_trade_item_id),
|
|
11279
|
+
jsonb_build_object('floriday_trade_item_id', p_floriday_id, 'door', auth.uid(), 'reden', t.reden));
|
|
11280
|
+
UPDATE public.voorraad_koppel_twijfel SET opgelost_at = now() WHERE floriday_id = p_floriday_id;
|
|
11281
|
+
RETURN jsonb_build_object('ok', true, 'product_id', p.id);
|
|
11282
|
+
END $function$
|
|
11283
|
+
;
|
|
11284
|
+
REVOKE ALL ON FUNCTION voorraad_twijfel_kiezen(text,uuid) FROM PUBLIC;
|
|
11285
|
+
REVOKE ALL ON FUNCTION voorraad_twijfel_kiezen(text,uuid) FROM anon;
|
|
11286
|
+
GRANT EXECUTE ON FUNCTION voorraad_twijfel_kiezen(text,uuid) TO authenticated;
|
|
11287
|
+
GRANT EXECUTE ON FUNCTION voorraad_twijfel_kiezen(text,uuid) TO service_role;
|
|
11288
|
+
CREATE OR REPLACE FUNCTION public.voorraad_twijfel_lijst(p_product_id uuid DEFAULT NULL::uuid, p_floriday_id text DEFAULT NULL::text)
|
|
11289
|
+
RETURNS jsonb
|
|
11290
|
+
LANGUAGE plpgsql
|
|
11291
|
+
STABLE SECURITY DEFINER
|
|
11292
|
+
SET search_path TO 'public'
|
|
11293
|
+
AS $function$
|
|
11294
|
+
BEGIN
|
|
11295
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_twijfel_lijst');
|
|
11296
|
+
RETURN COALESCE((
|
|
11297
|
+
SELECT jsonb_agg(jsonb_build_object(
|
|
11298
|
+
'floriday_id', t.floriday_id, 'naam', t.naam, 'reden', t.reden, 'laatst_gezien', t.laatst_gezien,
|
|
11299
|
+
'kandidaten', COALESCE((
|
|
11300
|
+
SELECT jsonb_agg(jsonb_build_object('id', p.id,
|
|
11301
|
+
'naam', COALESCE(NULLIF(btrim(p.product),''), '(naamloos)'),
|
|
11302
|
+
'artikelnummer', p.article_number, 'barcode', p.barcode,
|
|
11303
|
+
'floriday_id', NULLIF(btrim(COALESCE(p.floriday_trade_item_id,'')),''),
|
|
11304
|
+
'gearchiveerd', p.gearchiveerd_at IS NOT NULL) ORDER BY p.product)
|
|
11305
|
+
FROM public.products p
|
|
11306
|
+
WHERE jsonb_typeof(t.kandidaten) = 'array' AND t.kandidaten ? p.id::text), '[]'::jsonb))
|
|
11307
|
+
ORDER BY t.laatst_gezien DESC)
|
|
11308
|
+
FROM public.voorraad_koppel_twijfel t
|
|
11309
|
+
WHERE t.opgelost_at IS NULL
|
|
11310
|
+
AND (p_floriday_id IS NULL OR t.floriday_id = p_floriday_id)
|
|
11311
|
+
AND (p_product_id IS NULL OR (jsonb_typeof(t.kandidaten) = 'array' AND t.kandidaten ? p_product_id::text))
|
|
11312
|
+
LIMIT 50), '[]'::jsonb);
|
|
11313
|
+
END $function$
|
|
11314
|
+
;
|
|
11315
|
+
REVOKE ALL ON FUNCTION voorraad_twijfel_lijst(uuid,text) FROM PUBLIC;
|
|
11316
|
+
REVOKE ALL ON FUNCTION voorraad_twijfel_lijst(uuid,text) FROM anon;
|
|
11317
|
+
GRANT EXECUTE ON FUNCTION voorraad_twijfel_lijst(uuid,text) TO authenticated;
|
|
11318
|
+
GRANT EXECUTE ON FUNCTION voorraad_twijfel_lijst(uuid,text) TO service_role;
|
|
11319
|
+
CREATE OR REPLACE FUNCTION public.voorraad_twijfel_nieuw_artikel(p_floriday_id text)
|
|
11320
|
+
RETURNS jsonb
|
|
11321
|
+
LANGUAGE plpgsql
|
|
11322
|
+
SECURITY DEFINER
|
|
11323
|
+
SET search_path TO 'public'
|
|
11324
|
+
AS $function$
|
|
11325
|
+
DECLARE t public.voorraad_koppel_twijfel%ROWTYPE; c record; v_name text; v_gtin text; v_code text; v_photo text;
|
|
11326
|
+
v_new uuid; v_sturing text;
|
|
11327
|
+
BEGIN
|
|
11328
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_twijfel_nieuw_artikel');
|
|
11329
|
+
IF NOT public.voorraad_can_write() THEN
|
|
11330
|
+
RAISE EXCEPTION 'Je hebt geen schrijfrechten op de voorraad.' USING ERRCODE = '42501'; END IF;
|
|
11331
|
+
SELECT * INTO t FROM public.voorraad_koppel_twijfel WHERE floriday_id = p_floriday_id FOR UPDATE;
|
|
11332
|
+
IF NOT FOUND OR t.opgelost_at IS NOT NULL THEN
|
|
11333
|
+
RAISE EXCEPTION 'Dit twijfelgeval is al opgelost of bestaat niet meer.' USING ERRCODE = 'P0002'; END IF;
|
|
11334
|
+
IF EXISTS (SELECT 1 FROM public.products q WHERE lower(btrim(COALESCE(q.floriday_trade_item_id,''))) = lower(p_floriday_id)) THEN
|
|
11335
|
+
RAISE EXCEPTION 'Een artikel is al aan dit Floriday-product gekoppeld.' USING ERRCODE = '23505'; END IF;
|
|
11336
|
+
SELECT x.floriday_id, x.data INTO c FROM public.floriday_trade_items_cache x
|
|
11337
|
+
WHERE x.floriday_id = p_floriday_id
|
|
11338
|
+
AND (t.connection_id IS NULL OR x.connection_id = t.connection_id) LIMIT 1;
|
|
11339
|
+
IF NOT FOUND THEN
|
|
11340
|
+
RAISE EXCEPTION 'Het Floriday-artikel staat niet (meer) in de Floriday-gegevens.' USING ERRCODE = 'P0002'; END IF;
|
|
11341
|
+
v_name := NULLIF(btrim(COALESCE(CASE WHEN jsonb_typeof(c.data->'tradeItemName') = 'string' THEN c.data->>'tradeItemName' END,
|
|
11342
|
+
c.data->'tradeItemName'->>'nl', c.data->'tradeItemName'->>'en', t.naam)), '');
|
|
11343
|
+
IF v_name IS NULL THEN RAISE EXCEPTION 'Het Floriday-artikel heeft geen naam; kies een bestaand artikel.' USING ERRCODE = '22023'; END IF;
|
|
11344
|
+
v_gtin := NULLIF(btrim(COALESCE(c.data->>'articleGtin', c.data->>'gtin')), '');
|
|
11345
|
+
v_code := NULLIF(btrim(COALESCE(c.data->>'supplierArticleCode', c.data->>'articleCode')), '');
|
|
11346
|
+
SELECT e->>'url' INTO v_photo FROM jsonb_array_elements(CASE WHEN jsonb_typeof(c.data->'photos') = 'array' THEN c.data->'photos' ELSE '[]'::jsonb END) e
|
|
11347
|
+
ORDER BY COALESCE((e->>'primary')::boolean, false) DESC LIMIT 1;
|
|
11348
|
+
SELECT COALESCE(standaard_sturing_nieuwe_floriday, 'lokaal') INTO v_sturing FROM public.voorraad_instellingen WHERE id;
|
|
11349
|
+
v_sturing := COALESCE(v_sturing, 'lokaal');
|
|
11350
|
+
PERFORM set_config('voorraad.floriday_sync', 'on', true);
|
|
11351
|
+
INSERT INTO public.products(product, batch, location, barcode, article_number, image_url, floriday_trade_item_id, trade_item_key, custom_fields)
|
|
11352
|
+
VALUES (v_name, '', '', v_gtin, v_code, v_photo, c.floriday_id,
|
|
11353
|
+
COALESCE((SELECT s.trade_item_key FROM public.trade_item_stock s WHERE lower(s.trade_item_key) = lower(c.floriday_id) AND s.archived_at IS NULL ORDER BY s.created_at LIMIT 1), c.floriday_id),
|
|
11354
|
+
jsonb_build_object('voorraad_auto_aangemaakt', true, 'voorraad_floriday_versie', c.data->>'tradeItemVersion',
|
|
11355
|
+
'voorraad_auto_aangemaakt_at', now(), 'voorraad_uit_twijfel', true))
|
|
11356
|
+
RETURNING id INTO v_new;
|
|
11357
|
+
IF v_sturing = 'lokaal' THEN
|
|
11358
|
+
UPDATE public.floriday_inventory_settings SET erp_leading = NULL, stock_mode = 'DISABLED', updated_at = now()
|
|
11359
|
+
WHERE product_id = v_new;
|
|
11360
|
+
END IF;
|
|
11361
|
+
INSERT INTO public.voorraad_koppel_log(run_id, soort, floriday_id, product_id, oud, nieuw)
|
|
11362
|
+
VALUES (gen_random_uuid(), 'twijfel_nieuw_artikel', c.floriday_id, v_new, jsonb_build_object('reden', t.reden),
|
|
11363
|
+
jsonb_build_object('naam', v_name, 'gtin', v_gtin, 'artikelcode', v_code, 'sturing', v_sturing, 'door', auth.uid()));
|
|
11364
|
+
UPDATE public.voorraad_koppel_twijfel SET opgelost_at = now() WHERE floriday_id = p_floriday_id;
|
|
11365
|
+
RETURN jsonb_build_object('ok', true, 'product_id', v_new);
|
|
11366
|
+
END $function$
|
|
11367
|
+
;
|
|
11368
|
+
REVOKE ALL ON FUNCTION voorraad_twijfel_nieuw_artikel(text) FROM PUBLIC;
|
|
11369
|
+
REVOKE ALL ON FUNCTION voorraad_twijfel_nieuw_artikel(text) FROM anon;
|
|
11370
|
+
GRANT EXECUTE ON FUNCTION voorraad_twijfel_nieuw_artikel(text) TO authenticated;
|
|
11371
|
+
GRANT EXECUTE ON FUNCTION voorraad_twijfel_nieuw_artikel(text) TO service_role;
|
|
10767
11372
|
CREATE OR REPLACE FUNCTION public.voorraad_vereis(p_niveau text, p_functie text)
|
|
10768
11373
|
RETURNS void
|
|
10769
11374
|
LANGUAGE plpgsql
|
|
@@ -10790,6 +11395,113 @@ GRANT EXECUTE ON FUNCTION voorraad_vereis(text,text) TO service_role;
|
|
|
10790
11395
|
GRANT EXECUTE ON FUNCTION voorraad_vereis(text,text) TO anon;
|
|
10791
11396
|
GRANT EXECUTE ON FUNCTION voorraad_vereis(text,text) TO authenticated;
|
|
10792
11397
|
GRANT EXECUTE ON FUNCTION voorraad_vereis(text,text) TO service_role;
|
|
11398
|
+
CREATE OR REPLACE FUNCTION public.voorraad_voorraad_corrigeren(p_product_id uuid, p_delta integer, p_reden text)
|
|
11399
|
+
RETURNS jsonb
|
|
11400
|
+
LANGUAGE plpgsql
|
|
11401
|
+
SECURITY DEFINER
|
|
11402
|
+
SET search_path TO 'public'
|
|
11403
|
+
AS $function$
|
|
11404
|
+
DECLARE v_ctx record; v_fl text; v_tk text; v_voor integer; v_na integer; r record;
|
|
11405
|
+
BEGIN
|
|
11406
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_voorraad_corrigeren');
|
|
11407
|
+
IF NOT public.voorraad_can_write() THEN
|
|
11408
|
+
RAISE EXCEPTION 'Je hebt geen schrijfrechten op de voorraad.' USING ERRCODE = '42501'; END IF;
|
|
11409
|
+
IF p_delta IS NULL OR p_delta = 0 THEN
|
|
11410
|
+
RAISE EXCEPTION 'Vul een aantal in dat niet 0 is.' USING ERRCODE = '22023'; END IF;
|
|
11411
|
+
IF COALESCE(btrim(p_reden),'') = '' THEN
|
|
11412
|
+
RAISE EXCEPTION 'Vul een reden in.' USING ERRCODE = '22023'; END IF;
|
|
11413
|
+
SELECT NULLIF(btrim(COALESCE(p.floriday_trade_item_id,'')),''), NULLIF(btrim(COALESCE(p.trade_item_key,'')),'')
|
|
11414
|
+
INTO v_fl, v_tk FROM public.products p WHERE p.id = p_product_id;
|
|
11415
|
+
IF NOT FOUND THEN RAISE EXCEPTION 'Artikel niet gevonden.' USING ERRCODE = 'P0002'; END IF;
|
|
11416
|
+
SELECT * INTO v_ctx FROM public.get_stock_context(true);
|
|
11417
|
+
IF v_ctx.connection_id IS NULL THEN RAISE EXCEPTION 'Geen voorraadcontext beschikbaar' USING ERRCODE = 'VR004'; END IF;
|
|
11418
|
+
-- Eén correctie tegelijk per artikel; bestaande rij vastzetten zodat een tussentijdse orderafboeking meetelt.
|
|
11419
|
+
PERFORM pg_advisory_xact_lock(hashtext('voorraad_corrigeren:' || p_product_id::text));
|
|
11420
|
+
SELECT s.physical_stock INTO v_voor FROM public.trade_item_stock s
|
|
11421
|
+
WHERE s.connection_id = v_ctx.connection_id
|
|
11422
|
+
AND s.trade_item_key IN (COALESCE(v_tk, v_fl, 'product:' || p_product_id::text), v_fl, v_tk, 'product:' || p_product_id::text, p_product_id::text)
|
|
11423
|
+
ORDER BY CASE WHEN s.trade_item_key = COALESCE(v_tk, v_fl, 'product:' || p_product_id::text) THEN 0 ELSE 1 END, s.updated_at DESC NULLS LAST
|
|
11424
|
+
LIMIT 1 FOR UPDATE;
|
|
11425
|
+
v_voor := COALESCE(v_voor, 0);
|
|
11426
|
+
v_na := v_voor + p_delta;
|
|
11427
|
+
IF v_na < 0 THEN
|
|
11428
|
+
RAISE EXCEPTION 'Je kunt niet meer weghalen (%) dan er ligt (%).', -p_delta, v_voor USING ERRCODE = '22023'; END IF;
|
|
11429
|
+
PERFORM set_config('stock.change_note', left('Aangepast ' || CASE WHEN p_delta > 0 THEN '+' ELSE '' END || p_delta || ': ' || btrim(p_reden), 500), true);
|
|
11430
|
+
PERFORM set_config('stock.keep_notes', '1', true);
|
|
11431
|
+
SELECT * INTO r FROM public.set_product_stock(p_product_id => p_product_id, p_physical_stock => v_na,
|
|
11432
|
+
p_minimum_stock => NULL, p_incoming_stock => NULL, p_notes => NULL, p_change_source => 'MANUAL_STOCK');
|
|
11433
|
+
RETURN jsonb_build_object('opgeslagen', true, 'physical_before', v_voor, 'physical_after', r.physical_stock,
|
|
11434
|
+
'trade_item_key', r.trade_item_key, 'reserved_stock', r.reserved_stock);
|
|
11435
|
+
END $function$
|
|
11436
|
+
;
|
|
11437
|
+
REVOKE ALL ON FUNCTION voorraad_voorraad_corrigeren(uuid,integer,text) FROM PUBLIC;
|
|
11438
|
+
REVOKE ALL ON FUNCTION voorraad_voorraad_corrigeren(uuid,integer,text) FROM anon;
|
|
11439
|
+
GRANT EXECUTE ON FUNCTION voorraad_voorraad_corrigeren(uuid,integer,text) TO authenticated;
|
|
11440
|
+
GRANT EXECUTE ON FUNCTION voorraad_voorraad_corrigeren(uuid,integer,text) TO service_role;
|
|
11441
|
+
CREATE OR REPLACE FUNCTION public.voorraad_voorraad_instellingen_opslaan(p_product_id uuid, p_oud jsonb, p_nieuw jsonb)
|
|
11442
|
+
RETURNS jsonb
|
|
11443
|
+
LANGUAGE plpgsql
|
|
11444
|
+
SECURITY DEFINER
|
|
11445
|
+
SET search_path TO 'public'
|
|
11446
|
+
AS $function$
|
|
11447
|
+
DECLARE
|
|
11448
|
+
v_key text; s public.trade_item_stock%ROWTYPE; v_cur jsonb; k text;
|
|
11449
|
+
v_conf jsonb := '[]'::jsonb; v_set jsonb := '{}'::jsonb; v_ctx uuid;
|
|
11450
|
+
BEGIN
|
|
11451
|
+
PERFORM public.voorraad_vereis('ingelogd', 'voorraad_voorraad_instellingen_opslaan');
|
|
11452
|
+
IF NOT public.voorraad_can_write() THEN
|
|
11453
|
+
RAISE EXCEPTION 'Je hebt geen schrijfrechten op de voorraad.' USING ERRCODE = '42501'; END IF;
|
|
11454
|
+
IF jsonb_typeof(p_nieuw) IS DISTINCT FROM 'object' OR jsonb_typeof(p_oud) IS DISTINCT FROM 'object' THEN
|
|
11455
|
+
RAISE EXCEPTION 'Ongeldige invoer voor opslaan.' USING ERRCODE = '22023'; END IF;
|
|
11456
|
+
PERFORM 1 FROM public.products WHERE id = p_product_id FOR UPDATE;
|
|
11457
|
+
IF NOT FOUND THEN RAISE EXCEPTION 'Artikel niet gevonden.' USING ERRCODE = 'P0002'; END IF;
|
|
11458
|
+
|
|
11459
|
+
v_key := public.voorraad_artikel_detail(p_product_id)->>'voorraad_sleutel';
|
|
11460
|
+
IF v_key IS NULL THEN
|
|
11461
|
+
-- Nog geen voorraadregel: aanmaken met 0 liggend via de gewone opslagroute.
|
|
11462
|
+
PERFORM public.set_product_stock(p_product_id => p_product_id, p_physical_stock => 0, p_change_source => 'MANUAL_STOCK');
|
|
11463
|
+
v_key := public.voorraad_artikel_detail(p_product_id)->>'voorraad_sleutel';
|
|
11464
|
+
END IF;
|
|
11465
|
+
BEGIN SELECT c.connection_id INTO v_ctx FROM public.get_stock_context() c LIMIT 1;
|
|
11466
|
+
EXCEPTION WHEN others THEN v_ctx := NULL; END;
|
|
11467
|
+
SELECT * INTO s FROM public.trade_item_stock x WHERE x.trade_item_key = v_key AND x.archived_at IS NULL
|
|
11468
|
+
ORDER BY (x.connection_id IS NOT DISTINCT FROM v_ctx) DESC, x.updated_at DESC LIMIT 1 FOR UPDATE;
|
|
11469
|
+
IF NOT FOUND THEN RAISE EXCEPTION 'Geen voorraadregel gevonden voor dit artikel.' USING ERRCODE = 'P0002'; END IF;
|
|
11470
|
+
|
|
11471
|
+
v_cur := jsonb_build_object('minimum_stock', s.minimum_stock, 'incoming_stock', s.incoming_stock, 'notes', s.notes);
|
|
11472
|
+
FOR k IN SELECT jsonb_object_keys(p_nieuw) LOOP
|
|
11473
|
+
IF k NOT IN ('minimum_stock','incoming_stock','notes') THEN
|
|
11474
|
+
RAISE EXCEPTION 'Veld "%" kan hier niet worden opgeslagen.', k USING ERRCODE = '22023'; END IF;
|
|
11475
|
+
IF NOT (p_oud ? k) THEN
|
|
11476
|
+
RAISE EXCEPTION 'Stand bij openen ontbreekt voor veld "%".', k USING ERRCODE = '22023'; END IF;
|
|
11477
|
+
CONTINUE WHEN (p_nieuw->k) = (p_oud->k);
|
|
11478
|
+
IF (v_cur->k) IS DISTINCT FROM (p_oud->k) AND (v_cur->k) IS DISTINCT FROM (p_nieuw->k) THEN
|
|
11479
|
+
v_conf := v_conf || jsonb_build_object('veld', k, 'bij_openen', p_oud->k, 'jouw', p_nieuw->k, 'hun', v_cur->k);
|
|
11480
|
+
ELSE
|
|
11481
|
+
v_set := v_set || jsonb_build_object(k, p_nieuw->k);
|
|
11482
|
+
END IF;
|
|
11483
|
+
END LOOP;
|
|
11484
|
+
IF jsonb_array_length(v_conf) > 0 THEN RETURN jsonb_build_object('ok', false, 'conflicten', v_conf); END IF;
|
|
11485
|
+
IF (v_set ? 'minimum_stock' AND COALESCE((v_set->>'minimum_stock')::numeric, 0) < 0)
|
|
11486
|
+
OR (v_set ? 'incoming_stock' AND COALESCE((v_set->>'incoming_stock')::numeric, 0) < 0) THEN
|
|
11487
|
+
RAISE EXCEPTION 'Voorraadaantallen mogen niet negatief zijn' USING ERRCODE = '22023'; END IF;
|
|
11488
|
+
|
|
11489
|
+
IF v_set <> '{}'::jsonb THEN
|
|
11490
|
+
PERFORM set_config('stock.change_source', 'MANUAL_STOCK', true);
|
|
11491
|
+
UPDATE public.trade_item_stock SET
|
|
11492
|
+
minimum_stock = CASE WHEN v_set ? 'minimum_stock' THEN COALESCE((v_set->>'minimum_stock')::numeric, 0) ELSE minimum_stock END,
|
|
11493
|
+
incoming_stock = CASE WHEN v_set ? 'incoming_stock' THEN COALESCE((v_set->>'incoming_stock')::numeric, 0) ELSE incoming_stock END,
|
|
11494
|
+
notes = CASE WHEN v_set ? 'notes' THEN NULLIF(btrim(COALESCE(v_set->>'notes','')), '') ELSE notes END,
|
|
11495
|
+
change_source = 'MANUAL_STOCK', updated_at = now()
|
|
11496
|
+
WHERE id = s.id;
|
|
11497
|
+
END IF;
|
|
11498
|
+
RETURN jsonb_build_object('ok', true, 'opgeslagen', v_set);
|
|
11499
|
+
END $function$
|
|
11500
|
+
;
|
|
11501
|
+
REVOKE ALL ON FUNCTION voorraad_voorraad_instellingen_opslaan(uuid,jsonb,jsonb) FROM PUBLIC;
|
|
11502
|
+
REVOKE ALL ON FUNCTION voorraad_voorraad_instellingen_opslaan(uuid,jsonb,jsonb) FROM anon;
|
|
11503
|
+
GRANT EXECUTE ON FUNCTION voorraad_voorraad_instellingen_opslaan(uuid,jsonb,jsonb) TO authenticated;
|
|
11504
|
+
GRANT EXECUTE ON FUNCTION voorraad_voorraad_instellingen_opslaan(uuid,jsonb,jsonb) TO service_role;
|
|
10793
11505
|
CREATE OR REPLACE FUNCTION public.voorraad_voorraad_opslaan(p_product_id uuid, p_connection_id uuid, p_trade_item_key text, p_physical_stock numeric, p_minimum_stock numeric, p_incoming_stock numeric, p_wijziging_notitie text DEFAULT NULL::text, p_artikel_notitie text DEFAULT NULL::text, p_artikel_notitie_wijzigen boolean DEFAULT false)
|
|
10794
11506
|
RETURNS jsonb
|
|
10795
11507
|
LANGUAGE plpgsql
|
|
@@ -11070,6 +11782,7 @@ CREATE INDEX IF NOT EXISTS idx_voorraad_buffer_state_closed_at ON public.voorraa
|
|
|
11070
11782
|
CREATE INDEX IF NOT EXISTS idx_voorraad_event_log_processed_at ON public.voorraad_logistics_event_log USING btree (processed_at DESC);
|
|
11071
11783
|
CREATE INDEX IF NOT EXISTS idx_voorraad_publish_attempts_user_created ON public.voorraad_publish_attempts USING btree (user_id, created_at DESC);
|
|
11072
11784
|
CREATE INDEX IF NOT EXISTS inventory_stock_snapshots_time_idx ON public.inventory_stock_snapshots USING btree (connection_id, snapshot_at DESC);
|
|
11785
|
+
CREATE INDEX IF NOT EXISTS product_packings_primary_idx ON public.product_packings USING btree (product_id) WHERE is_primary;
|
|
11073
11786
|
CREATE INDEX IF NOT EXISTS product_packings_product_idx ON public.product_packings USING btree (product_id);
|
|
11074
11787
|
CREATE INDEX IF NOT EXISTS stock_import_rows_chunk_idx ON public.stock_import_rows USING btree (run_id, chunk_no);
|
|
11075
11788
|
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);
|