@flowselections/logistiek-engine 1.0.236 → 1.0.237
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/db/schema/logistiek-engine.sql +791 -0
- package/dist-lib/components/StandaardgegevensCard.d.ts.map +1 -1
- package/dist-lib/components/StandaardgegevensCard.js +24 -2
- package/dist-lib/components/rule-engine/RuleFieldInput.d.ts.map +1 -1
- package/dist-lib/components/rule-engine/RuleFieldInput.js +6 -2
- package/dist-lib/hooks/usePickstations.d.ts +3 -0
- package/dist-lib/hooks/usePickstations.d.ts.map +1 -1
- package/dist-lib/hooks/usePickstations.js +19 -3
- package/dist-lib/integrations/supabase/types.d.ts +1091 -0
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/logisticsPlanner.d.ts.map +1 -1
- package/dist-lib/lib/logisticsPlanner.js +1 -11
- package/dist-lib/lib/moduleVersion.d.ts +1 -1
- package/dist-lib/lib/moduleVersion.js +1 -1
- package/dist-lib/lib/ruleEngineSchema.js +5 -5
- package/package.json +1 -1
|
@@ -39825,3 +39825,794 @@ RETURNS TABLE(punt text, ok boolean, uitleg text) LANGUAGE sql STABLE SET search
|
|
|
39825
39825
|
$$;
|
|
39826
39826
|
REVOKE ALL ON FUNCTION public.logistics_install_check_231() FROM PUBLIC, anon, authenticated;
|
|
39827
39827
|
GRANT EXECUTE ON FUNCTION public.logistics_install_check_231() TO service_role;
|
|
39828
|
+
|
|
39829
|
+
-- ===== 1.0.232 productiebon uit productieorders =====
|
|
39830
|
+
CREATE TABLE IF NOT EXISTS public.logistics_productiebon_log (
|
|
39831
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
39832
|
+
productie_order_id uuid,
|
|
39833
|
+
actie text NOT NULL,
|
|
39834
|
+
status text NOT NULL,
|
|
39835
|
+
melding text,
|
|
39836
|
+
created_at timestamptz NOT NULL DEFAULT now()
|
|
39837
|
+
);
|
|
39838
|
+
CREATE INDEX IF NOT EXISTS logistics_productiebon_log_created_idx ON public.logistics_productiebon_log (created_at DESC);
|
|
39839
|
+
GRANT SELECT ON public.logistics_productiebon_log TO authenticated;
|
|
39840
|
+
GRANT ALL ON public.logistics_productiebon_log TO service_role;
|
|
39841
|
+
ALTER TABLE public.logistics_productiebon_log ENABLE ROW LEVEL SECURITY;
|
|
39842
|
+
DO $p$ BEGIN
|
|
39843
|
+
IF NOT EXISTS (SELECT 1 FROM pg_policies WHERE schemaname='public' AND tablename='logistics_productiebon_log' AND policyname='productiebon_log_lezen') THEN
|
|
39844
|
+
CREATE POLICY productiebon_log_lezen ON public.logistics_productiebon_log FOR SELECT TO authenticated USING (auth.uid() IS NOT NULL);
|
|
39845
|
+
END IF;
|
|
39846
|
+
END $p$;
|
|
39847
|
+
|
|
39848
|
+
CREATE OR REPLACE FUNCTION public.logistics_productiebon_log_schrijf(p_id uuid, p_actie text, p_status text, p_melding text)
|
|
39849
|
+
RETURNS void LANGUAGE plpgsql SECURITY DEFINER SET search_path TO 'public'
|
|
39850
|
+
AS $function$
|
|
39851
|
+
BEGIN
|
|
39852
|
+
INSERT INTO public.logistics_productiebon_log (productie_order_id, actie, status, melding) VALUES (p_id, p_actie, p_status, p_melding);
|
|
39853
|
+
DELETE FROM public.logistics_productiebon_log WHERE id IN (
|
|
39854
|
+
SELECT id FROM public.logistics_productiebon_log WHERE created_at < now() - interval '90 days' ORDER BY created_at LIMIT 500);
|
|
39855
|
+
END $function$;
|
|
39856
|
+
|
|
39857
|
+
CREATE OR REPLACE FUNCTION public.logistics_productiebon_sync(p_productie_order_id uuid)
|
|
39858
|
+
RETURNS jsonb LANGUAGE plpgsql SECURITY DEFINER SET search_path TO 'public'
|
|
39859
|
+
AS $function$
|
|
39860
|
+
DECLARE
|
|
39861
|
+
po record; s jsonb; v_release text; v_approval boolean; v_station uuid; v_screen uuid;
|
|
39862
|
+
v_type uuid; v_queued uuid; v_new uuid; v_cancel uuid; v_done uuid; v_row record; v_lines integer; v_payload jsonb; v_n integer;
|
|
39863
|
+
BEGIN
|
|
39864
|
+
SELECT * INTO po FROM public.productie_orders WHERE id = p_productie_order_id;
|
|
39865
|
+
IF NOT FOUND THEN RETURN jsonb_build_object('actie','geen','reden','productieorder niet gevonden'); END IF;
|
|
39866
|
+
SELECT id INTO v_type FROM public.pick_document_types WHERE code = 'productiebon' LIMIT 1;
|
|
39867
|
+
IF v_type IS NULL THEN
|
|
39868
|
+
PERFORM public.logistics_productiebon_log_schrijf(po.id, 'sync', 'fout', 'Documentsoort productiebon ontbreekt in de pickschermen.');
|
|
39869
|
+
RETURN jsonb_build_object('actie','fout','reden','documentsoort productiebon ontbreekt');
|
|
39870
|
+
END IF;
|
|
39871
|
+
SELECT id INTO v_queued FROM public.pick_document_statuses WHERE code = 'queued' LIMIT 1;
|
|
39872
|
+
SELECT id INTO v_new FROM public.pick_document_statuses WHERE code = 'new' LIMIT 1;
|
|
39873
|
+
SELECT id INTO v_cancel FROM public.pick_document_statuses WHERE code = 'cancelled' LIMIT 1;
|
|
39874
|
+
SELECT id INTO v_done FROM public.pick_document_statuses WHERE code = 'done' LIMIT 1;
|
|
39875
|
+
SELECT q.* INTO v_row FROM public.pick_queue q
|
|
39876
|
+
WHERE q.document_type_id = v_type AND q.payload->>'productie_order_id' = po.id::text
|
|
39877
|
+
ORDER BY q.created_at DESC LIMIT 1;
|
|
39878
|
+
|
|
39879
|
+
IF po.status = 'geannuleerd' THEN
|
|
39880
|
+
UPDATE public.pick_queue q SET cancelled_at = now(), status_id = coalesce(v_cancel, q.status_id), updated_at = now(),
|
|
39881
|
+
payload = coalesce(q.payload,'{}'::jsonb) || jsonb_build_object('cancelReason','Productieorder geannuleerd')
|
|
39882
|
+
WHERE q.document_type_id = v_type AND q.payload->>'productie_order_id' = po.id::text
|
|
39883
|
+
AND q.cancelled_at IS NULL AND q.completed_at IS NULL;
|
|
39884
|
+
GET DIAGNOSTICS v_n = ROW_COUNT;
|
|
39885
|
+
PERFORM public.logistics_productiebon_log_schrijf(po.id, 'annuleren', 'ok', v_n || ' regel(s) uit de wachtrij');
|
|
39886
|
+
RETURN jsonb_build_object('actie','geannuleerd','regels',v_n);
|
|
39887
|
+
ELSIF po.status = 'verwerkt' THEN
|
|
39888
|
+
UPDATE public.pick_queue q SET completed_at = now(), status_id = coalesce(v_done, q.status_id), updated_at = now()
|
|
39889
|
+
WHERE q.document_type_id = v_type AND q.payload->>'productie_order_id' = po.id::text
|
|
39890
|
+
AND q.cancelled_at IS NULL AND q.completed_at IS NULL;
|
|
39891
|
+
GET DIAGNOSTICS v_n = ROW_COUNT;
|
|
39892
|
+
PERFORM public.logistics_productiebon_log_schrijf(po.id, 'afronden', 'ok', v_n || ' regel(s) afgerond');
|
|
39893
|
+
RETURN jsonb_build_object('actie','afgerond','regels',v_n);
|
|
39894
|
+
ELSIF po.status <> 'open' THEN
|
|
39895
|
+
RETURN jsonb_build_object('actie','geen','reden','status ' || coalesce(po.status,'leeg') || ' verandert de wachtrij niet');
|
|
39896
|
+
END IF;
|
|
39897
|
+
|
|
39898
|
+
SELECT settings INTO s FROM public.logistics_rule_configs
|
|
39899
|
+
ORDER BY is_active DESC, (status = 'actief') DESC, updated_at DESC LIMIT 1;
|
|
39900
|
+
v_release := coalesce(public.logistics_rule_text(s, 'pickstations', 'production_note_release', 'on_stock_upgrade'), 'on_stock_upgrade');
|
|
39901
|
+
v_approval := v_release = 'manual_approval_after_upgrade';
|
|
39902
|
+
v_station := public.logistics_try_uuid(s->'pickstations'->'fields'->>'production_note_station');
|
|
39903
|
+
SELECT count(*)::int INTO v_lines FROM public.productie_order_onderdelen o WHERE o.productie_order_id = po.id;
|
|
39904
|
+
v_payload := jsonb_build_object('source','logistiek-engine','documentType','productiebon',
|
|
39905
|
+
'productie_order_id', po.id, 'productieOrderNummer', po.nummer, 'productId', po.product_id,
|
|
39906
|
+
'tradeItemKey', po.trade_item_key, 'aantal', po.aantal, 'opmerking', po.opmerking,
|
|
39907
|
+
'onderdelen', v_lines);
|
|
39908
|
+
|
|
39909
|
+
IF v_row.id IS NOT NULL THEN
|
|
39910
|
+
IF v_row.cancelled_at IS NULL AND v_row.completed_at IS NULL THEN
|
|
39911
|
+
UPDATE public.pick_queue q SET document_number = po.nummer, line_count = v_lines,
|
|
39912
|
+
payload = coalesce(q.payload,'{}'::jsonb) || v_payload, updated_at = now()
|
|
39913
|
+
WHERE q.id = v_row.id
|
|
39914
|
+
AND (q.document_number, q.line_count, coalesce(q.payload,'{}'::jsonb))
|
|
39915
|
+
IS DISTINCT FROM (po.nummer, v_lines, coalesce(q.payload,'{}'::jsonb) || v_payload);
|
|
39916
|
+
END IF;
|
|
39917
|
+
RETURN jsonb_build_object('actie','bestaat','queueId',v_row.id);
|
|
39918
|
+
END IF;
|
|
39919
|
+
|
|
39920
|
+
IF v_station IS NULL OR NOT EXISTS (SELECT 1 FROM public.pick_stations WHERE id = v_station) THEN
|
|
39921
|
+
PERFORM public.logistics_productiebon_log_schrijf(po.id, 'aanmaken', 'overgeslagen',
|
|
39922
|
+
'Geen pickstation ingesteld bij Productiebon (Werkwijze, stap Pickstations).');
|
|
39923
|
+
RETURN jsonb_build_object('actie','overgeslagen','reden','geen pickstation ingesteld');
|
|
39924
|
+
END IF;
|
|
39925
|
+
SELECT sc.id INTO v_screen FROM public.pick_station_screens sc
|
|
39926
|
+
WHERE sc.station_id = v_station
|
|
39927
|
+
ORDER BY (EXISTS (SELECT 1 FROM public.pick_screen_document_types d WHERE d.screen_id = sc.id AND d.document_type_id = v_type)) DESC, sc.created_at
|
|
39928
|
+
LIMIT 1;
|
|
39929
|
+
|
|
39930
|
+
INSERT INTO public.pick_queue (station_id, screen_id, document_type_id, status_id, document_number, order_number, reference,
|
|
39931
|
+
customer_name, line_count, cart_count, priority, is_urgent, announced_at, due_at, payload)
|
|
39932
|
+
VALUES (v_station, v_screen, v_type, CASE WHEN v_approval THEN coalesce(v_new, v_queued) ELSE v_queued END,
|
|
39933
|
+
po.nummer, NULL, po.id::text, NULL, v_lines, 0, 50, false, now(), NULL,
|
|
39934
|
+
v_payload || jsonb_build_object('requiresApproval', v_approval, 'approvedAt', NULL, 'approvedBy', NULL));
|
|
39935
|
+
PERFORM public.logistics_productiebon_log_schrijf(po.id, 'aanmaken', 'ok',
|
|
39936
|
+
CASE WHEN v_approval THEN 'In wachtrij, wacht op goedkeuring' ELSE 'In wachtrij' END);
|
|
39937
|
+
RETURN jsonb_build_object('actie','aangemaakt','wachtOpGoedkeuring',v_approval);
|
|
39938
|
+
END $function$;
|
|
39939
|
+
|
|
39940
|
+
CREATE OR REPLACE FUNCTION public.logistics_productie_orders_trg()
|
|
39941
|
+
RETURNS trigger LANGUAGE plpgsql SECURITY DEFINER SET search_path TO 'public'
|
|
39942
|
+
AS $function$
|
|
39943
|
+
BEGIN
|
|
39944
|
+
BEGIN
|
|
39945
|
+
PERFORM public.logistics_productiebon_sync(NEW.id);
|
|
39946
|
+
EXCEPTION WHEN OTHERS THEN
|
|
39947
|
+
BEGIN
|
|
39948
|
+
PERFORM public.logistics_productiebon_log_schrijf(NEW.id, 'trigger', 'fout', SQLSTATE || ': ' || SQLERRM);
|
|
39949
|
+
EXCEPTION WHEN OTHERS THEN
|
|
39950
|
+
RAISE WARNING 'logistiek-engine productiebon: % (log mislukt: %)', NEW.id, SQLERRM;
|
|
39951
|
+
END;
|
|
39952
|
+
END;
|
|
39953
|
+
RETURN NULL;
|
|
39954
|
+
END $function$;
|
|
39955
|
+
|
|
39956
|
+
CREATE OR REPLACE FUNCTION public.logistics_productiebon_goedkeuren(p_queue_id uuid)
|
|
39957
|
+
RETURNS jsonb LANGUAGE plpgsql SECURITY DEFINER SET search_path TO 'public'
|
|
39958
|
+
AS $function$
|
|
39959
|
+
DECLARE v_queued uuid; v_po text; v_n integer;
|
|
39960
|
+
BEGIN
|
|
39961
|
+
PERFORM public.logistics_acc_guard('ingelogd', 'logistics_productiebon_goedkeuren');
|
|
39962
|
+
SELECT id INTO v_queued FROM public.pick_document_statuses WHERE code = 'queued' LIMIT 1;
|
|
39963
|
+
UPDATE public.pick_queue q
|
|
39964
|
+
SET status_id = coalesce(v_queued, q.status_id), updated_at = now(),
|
|
39965
|
+
payload = q.payload || jsonb_build_object('approvedAt', now(), 'approvedBy', auth.uid())
|
|
39966
|
+
WHERE q.id = p_queue_id AND q.payload ? 'productie_order_id'
|
|
39967
|
+
AND coalesce((q.payload->>'requiresApproval')::boolean, false)
|
|
39968
|
+
AND q.payload->>'approvedAt' IS NULL AND q.cancelled_at IS NULL AND q.completed_at IS NULL
|
|
39969
|
+
RETURNING q.payload->>'productie_order_id' INTO v_po;
|
|
39970
|
+
GET DIAGNOSTICS v_n = ROW_COUNT;
|
|
39971
|
+
IF v_n = 0 THEN
|
|
39972
|
+
RETURN jsonb_build_object('ok', false, 'melding', 'Deze productiebon wacht niet (meer) op goedkeuring.');
|
|
39973
|
+
END IF;
|
|
39974
|
+
PERFORM public.logistics_productiebon_log_schrijf(v_po::uuid, 'goedkeuren', 'ok', 'Goedgekeurd');
|
|
39975
|
+
RETURN jsonb_build_object('ok', true, 'melding', 'Productiebon goedgekeurd.');
|
|
39976
|
+
END $function$;
|
|
39977
|
+
|
|
39978
|
+
CREATE OR REPLACE FUNCTION public.logistics_productiebon_status()
|
|
39979
|
+
RETURNS jsonb LANGUAGE plpgsql STABLE SECURITY DEFINER SET search_path TO 'public'
|
|
39980
|
+
AS $function$
|
|
39981
|
+
DECLARE v_type uuid; r jsonb;
|
|
39982
|
+
BEGIN
|
|
39983
|
+
PERFORM public.logistics_acc_guard('ingelogd', 'logistics_productiebon_status');
|
|
39984
|
+
IF to_regclass('public.pick_queue') IS NULL OR to_regclass('public.pick_document_types') IS NULL THEN
|
|
39985
|
+
RETURN jsonb_build_object('beschikbaar', false);
|
|
39986
|
+
END IF;
|
|
39987
|
+
SELECT id INTO v_type FROM public.pick_document_types WHERE code = 'productiebon' LIMIT 1;
|
|
39988
|
+
SELECT jsonb_build_object('beschikbaar', true,
|
|
39989
|
+
'inWachtrij', count(*) FILTER (WHERE q.cancelled_at IS NULL AND q.completed_at IS NULL
|
|
39990
|
+
AND NOT (coalesce((q.payload->>'requiresApproval')::boolean,false) AND q.payload->>'approvedAt' IS NULL)),
|
|
39991
|
+
'wachtOpGoedkeuring', count(*) FILTER (WHERE q.cancelled_at IS NULL AND q.completed_at IS NULL
|
|
39992
|
+
AND coalesce((q.payload->>'requiresApproval')::boolean,false) AND q.payload->>'approvedAt' IS NULL))
|
|
39993
|
+
INTO r FROM public.pick_queue q WHERE q.document_type_id = v_type AND q.payload ? 'productie_order_id';
|
|
39994
|
+
RETURN r || jsonb_build_object('fouten', coalesce((SELECT jsonb_agg(jsonb_build_object('op', l.created_at, 'status', l.status, 'melding', l.melding) ORDER BY l.created_at DESC)
|
|
39995
|
+
FROM (SELECT * FROM public.logistics_productiebon_log WHERE status IN ('fout','overgeslagen') AND created_at > now() - interval '7 days'
|
|
39996
|
+
ORDER BY created_at DESC LIMIT 5) l), '[]'::jsonb));
|
|
39997
|
+
END $function$;
|
|
39998
|
+
|
|
39999
|
+
CREATE OR REPLACE FUNCTION public.logistics_install_check_productiebon()
|
|
40000
|
+
RETURNS TABLE(onderdeel text, ok boolean, toelichting text) LANGUAGE plpgsql STABLE SECURITY DEFINER SET search_path TO 'public'
|
|
40001
|
+
AS $function$
|
|
40002
|
+
DECLARE f text;
|
|
40003
|
+
BEGIN
|
|
40004
|
+
FOREACH f IN ARRAY ARRAY['logistics_productiebon_sync(uuid)','logistics_productiebon_goedkeuren(uuid)',
|
|
40005
|
+
'logistics_productiebon_status()','logistics_productie_orders_trg()'] LOOP
|
|
40006
|
+
onderdeel := 'functie ' || f; ok := to_regprocedure('public.' || f) IS NOT NULL;
|
|
40007
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt: werk de Engine bij via Supabase bijwerken' END; RETURN NEXT;
|
|
40008
|
+
END LOOP;
|
|
40009
|
+
onderdeel := 'tabel logistics_productiebon_log'; ok := to_regclass('public.logistics_productiebon_log') IS NOT NULL;
|
|
40010
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt' END; RETURN NEXT;
|
|
40011
|
+
onderdeel := 'trigger trg_logistics_productie_orders_productiebon';
|
|
40012
|
+
IF to_regclass('public.productie_orders') IS NULL THEN ok := true; toelichting := 'niet nodig: Voorraad-productieorders ontbreken';
|
|
40013
|
+
ELSE ok := EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'trg_logistics_productie_orders_productiebon' AND tgrelid = 'public.productie_orders'::regclass);
|
|
40014
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt: werk de Engine bij via Supabase bijwerken' END; END IF;
|
|
40015
|
+
RETURN NEXT;
|
|
40016
|
+
END $function$;
|
|
40017
|
+
|
|
40018
|
+
CREATE OR REPLACE FUNCTION public.logistics_pick_queue_close(p_ids uuid[], p_mode text, p_reason text)
|
|
40019
|
+
RETURNS integer
|
|
40020
|
+
LANGUAGE plpgsql
|
|
40021
|
+
SECURITY DEFINER
|
|
40022
|
+
SET search_path TO 'public'
|
|
40023
|
+
AS $function$
|
|
40024
|
+
DECLARE v_n integer := 0; r record;
|
|
40025
|
+
BEGIN
|
|
40026
|
+
PERFORM public.logistics_acc_guard('ingelogd', 'logistics_pick_queue_close');
|
|
40027
|
+
IF p_ids IS NULL OR cardinality(p_ids) = 0 THEN RETURN 0; END IF;
|
|
40028
|
+
FOR r IN
|
|
40029
|
+
UPDATE public.pick_queue q
|
|
40030
|
+
SET cancelled_at = CASE WHEN p_mode = 'cancel' THEN now() ELSE q.cancelled_at END,
|
|
40031
|
+
completed_at = CASE WHEN p_mode = 'complete' THEN now() ELSE q.completed_at END,
|
|
40032
|
+
updated_at = now()
|
|
40033
|
+
WHERE q.id = ANY(p_ids) AND q.cancelled_at IS NULL AND q.completed_at IS NULL
|
|
40034
|
+
-- Productiebonnen volgen alleen hun productieorder, niet de order-opruiming.
|
|
40035
|
+
AND NOT (coalesce(q.payload, '{}'::jsonb) ? 'productie_order_id')
|
|
40036
|
+
RETURNING q.id, q.order_number, q.document_number, coalesce(q.payload->>'cartId', CASE WHEN q.payload ? 'cartRowFor' THEN q.reference END) AS cart_id
|
|
40037
|
+
LOOP
|
|
40038
|
+
v_n := v_n + 1;
|
|
40039
|
+
BEGIN
|
|
40040
|
+
INSERT INTO public.logistics_trace_events(order_ref, cart_ref, slip_ref, phase, step, status, actor, reason, db_table, db_record, db_action)
|
|
40041
|
+
VALUES (r.order_number, r.cart_id, r.document_number, 'pick', 'pickregel_afgesloten', 'ok', 'logistiek-engine',
|
|
40042
|
+
p_reason, 'pick_queue', r.id::text, CASE WHEN p_mode = 'cancel' THEN 'cancelled_at' ELSE 'completed_at' END);
|
|
40043
|
+
EXCEPTION WHEN OTHERS THEN NULL; -- tijdlijn mag het afsluiten nooit blokkeren
|
|
40044
|
+
END;
|
|
40045
|
+
END LOOP;
|
|
40046
|
+
RETURN v_n;
|
|
40047
|
+
END $function$;
|
|
40048
|
+
|
|
40049
|
+
REVOKE ALL ON FUNCTION public.logistics_productiebon_log_schrijf(uuid,text,text,text) FROM PUBLIC, anon, authenticated;
|
|
40050
|
+
REVOKE ALL ON FUNCTION public.logistics_productiebon_sync(uuid) FROM PUBLIC, anon, authenticated;
|
|
40051
|
+
REVOKE ALL ON FUNCTION public.logistics_productie_orders_trg() FROM PUBLIC, anon, authenticated;
|
|
40052
|
+
REVOKE ALL ON FUNCTION public.logistics_productiebon_goedkeuren(uuid) FROM PUBLIC, anon;
|
|
40053
|
+
REVOKE ALL ON FUNCTION public.logistics_productiebon_status() FROM PUBLIC, anon;
|
|
40054
|
+
REVOKE ALL ON FUNCTION public.logistics_install_check_productiebon() FROM PUBLIC, anon;
|
|
40055
|
+
GRANT EXECUTE ON FUNCTION public.logistics_productiebon_log_schrijf(uuid,text,text,text) TO service_role;
|
|
40056
|
+
GRANT EXECUTE ON FUNCTION public.logistics_productiebon_sync(uuid) TO service_role;
|
|
40057
|
+
GRANT EXECUTE ON FUNCTION public.logistics_productiebon_goedkeuren(uuid) TO authenticated, service_role;
|
|
40058
|
+
GRANT EXECUTE ON FUNCTION public.logistics_productiebon_status() TO authenticated, service_role;
|
|
40059
|
+
GRANT EXECUTE ON FUNCTION public.logistics_install_check_productiebon() TO authenticated, service_role;
|
|
40060
|
+
|
|
40061
|
+
-- Voorwaardelijke stap: alleen als Voorraad-productieorders bestaan.
|
|
40062
|
+
DO $t$ BEGIN
|
|
40063
|
+
IF to_regclass('public.productie_orders') IS NOT NULL
|
|
40064
|
+
AND NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'trg_logistics_productie_orders_productiebon' AND tgrelid = 'public.productie_orders'::regclass) THEN
|
|
40065
|
+
CREATE TRIGGER trg_logistics_productie_orders_productiebon
|
|
40066
|
+
AFTER INSERT OR UPDATE OF status ON public.productie_orders
|
|
40067
|
+
FOR EACH ROW EXECUTE FUNCTION public.logistics_productie_orders_trg();
|
|
40068
|
+
END IF;
|
|
40069
|
+
EXCEPTION WHEN OTHERS THEN
|
|
40070
|
+
RAISE NOTICE 'logistiek-engine: trigger productiebon niet aangemaakt: %', SQLERRM;
|
|
40071
|
+
END $t$;
|
|
40072
|
+
|
|
40073
|
+
CREATE OR REPLACE FUNCTION public.logistics_install_check()
|
|
40074
|
+
RETURNS TABLE(onderdeel text, ok boolean, toelichting text)
|
|
40075
|
+
LANGUAGE plpgsql
|
|
40076
|
+
SECURITY DEFINER
|
|
40077
|
+
SET search_path TO 'public'
|
|
40078
|
+
AS $function$
|
|
40079
|
+
DECLARE c text; f text; t text; v_fav text; n bigint; s record;
|
|
40080
|
+
BEGIN
|
|
40081
|
+
PERFORM public.logistics_acc_guard('ingelogd', 'logistics_install_check');
|
|
40082
|
+
-- Alleen bestaan controleren: herberekenen nooit tijdens installatie uitvoeren.
|
|
40083
|
+
FOREACH f IN ARRAY ARRAY['logistics_pickup_at(text,date)',
|
|
40084
|
+
'logistics_pickup_ts(text,date)', 'logistics_pickup_herbereken()'] LOOP
|
|
40085
|
+
onderdeel := 'functie ' || f;
|
|
40086
|
+
ok := to_regprocedure('public.' || f) IS NOT NULL;
|
|
40087
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt: werk de Engine bij via Supabase bijwerken' END;
|
|
40088
|
+
RETURN NEXT;
|
|
40089
|
+
END LOOP;
|
|
40090
|
+
FOREACH f IN ARRAY ARRAY[
|
|
40091
|
+
'f:logistics_try_uuid','f:logistics_tz','f:logistics_is_beheer','f:logistics_buffer_payload','f:logistics_apply_order_buffer',
|
|
40092
|
+
'f:logistics_apply_buffer_decision','f:logistics_rebuffer_pending','f:logistics_departure_calc','f:logistics_own_transport_departure',
|
|
40093
|
+
'f:logistics_order_departure','f:logistics_brief_transport','f:logistics_order_frozen','f:logistics_order_is_frozen',
|
|
40094
|
+
'f:logistics_order_finalize_run','f:run_logistics_tasks_dispatch','f:enqueue_cart_replan_if_unlocked','f:logistics_tick',
|
|
40095
|
+
't:logistics_tick_runs',
|
|
40096
|
+
'f:logistics_belading_bevestig','f:logistics_cart_seq_dubbel','f:logistics_plan_retry_later','f:logistics_own_traysticker_sync',
|
|
40097
|
+
't:logistics_belading_bevestigingen',
|
|
40098
|
+
'f:logistics_sticker_copies','f:logistics_sticker_etiket_status','f:logistics_sticker_order_counts','f:logistics_sticker_sync',
|
|
40099
|
+
'c:logistics_sticker_prints.kopieen_bron',
|
|
40100
|
+
'f:logistics_carrier_settings_ensure','t:logistics_carrier_settings','t:logistics_carrier_recalc_queue','t:logistics_carrier_events',
|
|
40101
|
+
'f:logistics_carrier_status','f:logistics_carrier_set_backfill','f:logistics_carrier_preview_existing','c:control_get_todays_carts.carrier_name',
|
|
40102
|
+
'f:logistics_plan_fail_log'] LOOP
|
|
40103
|
+
onderdeel := 'Engine: ' || substr(f, 3);
|
|
40104
|
+
ok := CASE left(f, 1)
|
|
40105
|
+
WHEN 'f' THEN EXISTS (SELECT 1 FROM pg_proc p WHERE p.pronamespace = 'public'::regnamespace AND p.proname = substr(f, 3))
|
|
40106
|
+
WHEN 't' THEN to_regclass('public.' || substr(f, 3)) IS NOT NULL
|
|
40107
|
+
ELSE CASE WHEN split_part(substr(f, 3), '.', 1) = 'control_get_todays_carts'
|
|
40108
|
+
THEN coalesce(pg_get_function_result(to_regprocedure('public.control_get_todays_carts()')), '') LIKE '%carrier_name%'
|
|
40109
|
+
ELSE EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='public'
|
|
40110
|
+
AND table_name = split_part(substr(f, 3), '.', 1) AND column_name = split_part(substr(f, 3), '.', 2)) END
|
|
40111
|
+
END;
|
|
40112
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt: Engine-migratie (1.0.182 t/m 1.0.188) in dev uitvoeren en via schemasync verspreiden' END;
|
|
40113
|
+
RETURN NEXT;
|
|
40114
|
+
END LOOP;
|
|
40115
|
+
FOREACH c IN ARRAY ARRAY['carrier_id','carrier_source','carrier_reason','carrier_resolved_at','carrier_set_by','carrier_set_at'] LOOP
|
|
40116
|
+
onderdeel := 'orders.' || c;
|
|
40117
|
+
ok := EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='public' AND table_name='orders' AND column_name=c);
|
|
40118
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt: Engine-migratie' END; RETURN NEXT;
|
|
40119
|
+
END LOOP;
|
|
40120
|
+
FOREACH f IN ARRAY ARRAY['logistics_resolve_carrier(uuid)','logistics_resolve_carrier_many(uuid[])',
|
|
40121
|
+
'logistics_resolve_carrier_for_location(uuid,uuid)','logistics_resolve_carrier_for_location_many(uuid[],uuid)',
|
|
40122
|
+
'logistics_resolve_carrier_for_location_many(jsonb)',
|
|
40123
|
+
'logistics_set_order_carrier(uuid,uuid)','logistics_carrier_recalc_run(integer)'] LOOP
|
|
40124
|
+
onderdeel := 'functie ' || f; ok := to_regprocedure('public.' || f) IS NOT NULL;
|
|
40125
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt: Engine-migratie' END; RETURN NEXT;
|
|
40126
|
+
END LOOP;
|
|
40127
|
+
FOREACH t IN ARRAY ARRAY['orders:trg_logistics_orders_carrier_fill','orders:trg_logistics_orders_carrier_changed',
|
|
40128
|
+
'carriers:trg_logistics_carriers_enqueue','customer_delivery_locations:trg_logistics_locations_enqueue'] LOOP
|
|
40129
|
+
onderdeel := 'trigger ' || split_part(t, ':', 2);
|
|
40130
|
+
ok := EXISTS (SELECT 1 FROM pg_trigger g WHERE g.tgname = split_part(t, ':', 2)
|
|
40131
|
+
AND g.tgrelid = to_regclass('public.' || split_part(t, ':', 1)));
|
|
40132
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt: Engine-migratie' END; RETURN NEXT;
|
|
40133
|
+
END LOOP;
|
|
40134
|
+
onderdeel := 'minuutronde rekent vervoerders';
|
|
40135
|
+
ok := EXISTS (SELECT 1 FROM pg_proc WHERE proname = 'logistics_tick' AND prosrc LIKE '%logistics_carrier_recalc_run%');
|
|
40136
|
+
toelichting := CASE WHEN ok THEN 'ja' ELSE 'nee' END; RETURN NEXT;
|
|
40137
|
+
FOREACH c IN ARRAY ARRAY['carrier_kind','is_favorite','archived_at','delivery_location_glns'] LOOP
|
|
40138
|
+
onderdeel := 'Afhandeling: carriers.' || c;
|
|
40139
|
+
ok := EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='public' AND table_name='carriers' AND column_name=c);
|
|
40140
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt: Afhandeling' END; RETURN NEXT;
|
|
40141
|
+
END LOOP;
|
|
40142
|
+
FOREACH f IN ARRAY ARRAY['afh_favorite_carrier','afh_city_code','afh_normalize_country','afh_normalize_nl_province'] LOOP
|
|
40143
|
+
onderdeel := 'Afhandeling: ' || f || '()';
|
|
40144
|
+
ok := EXISTS (SELECT 1 FROM pg_proc p WHERE p.pronamespace = 'public'::regnamespace AND p.proname = f);
|
|
40145
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt: Afhandeling' END; RETURN NEXT;
|
|
40146
|
+
END LOOP;
|
|
40147
|
+
onderdeel := 'Favoriete vervoerder ingesteld en bruikbaar';
|
|
40148
|
+
IF to_regprocedure('public.afh_favorite_carrier()') IS NULL THEN ok := false; toelichting := 'functie ontbreekt';
|
|
40149
|
+
ELSE
|
|
40150
|
+
BEGIN v_fav := public.logistics_carrier_favorite_id()::text; EXCEPTION WHEN OTHERS THEN v_fav := NULL; END;
|
|
40151
|
+
ok := public.logistics_try_uuid(v_fav) IS NOT NULL AND public.logistics_carrier_skip_reason(public.logistics_try_uuid(v_fav)) IS NULL;
|
|
40152
|
+
toelichting := CASE WHEN ok THEN 'ja' WHEN v_fav IS NULL THEN 'geen favoriet ingesteld (Afhandeling → Vervoerders)'
|
|
40153
|
+
ELSE public.logistics_carrier_skip_reason(public.logistics_try_uuid(v_fav)) END;
|
|
40154
|
+
END IF;
|
|
40155
|
+
RETURN NEXT;
|
|
40156
|
+
onderdeel := 'Klanten: customers.default_carrier_id';
|
|
40157
|
+
ok := EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='public' AND table_name='customers' AND column_name='default_carrier_id');
|
|
40158
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt: Klanten' END; RETURN NEXT;
|
|
40159
|
+
IF to_regclass('public.logistics_carrier_settings') IS NOT NULL AND to_regclass('public.orders') IS NOT NULL
|
|
40160
|
+
AND EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='public' AND table_name='orders' AND column_name='carrier_source') THEN
|
|
40161
|
+
SELECT * INTO s FROM public.logistics_carrier_settings_ensure();
|
|
40162
|
+
EXECUTE $q$SELECT count(*) FROM public.orders o
|
|
40163
|
+
WHERE o.deleted_at IS NULL AND o.cancelled_at IS NULL
|
|
40164
|
+
AND coalesce(o.delivery_date, '') ~ '^\d{4}-\d{2}-\d{2}' AND left(o.delivery_date, 10)::date >= current_date
|
|
40165
|
+
AND (o.carrier_source = 'geen' OR (o.carrier_source IS NULL AND o.created_at >= $1))$q$ INTO n USING s.installed_at;
|
|
40166
|
+
onderdeel := 'Open orders zonder vervoerder'; ok := n = 0; toelichting := n || ' order(s)'; RETURN NEXT;
|
|
40167
|
+
onderdeel := 'Schakelaar bestaande orders'; ok := true;
|
|
40168
|
+
toelichting := CASE WHEN coalesce(s.backfill_existing, false) THEN 'aan' ELSE 'uit (bestaande orders wachten op akkoord)' END; RETURN NEXT;
|
|
40169
|
+
END IF;
|
|
40170
|
+
SELECT count(*) INTO n FROM public.logistics_trace_events e
|
|
40171
|
+
WHERE e.actor IN ('trg_logistics_plan_order_items', 'trg_logistics_plan_orders')
|
|
40172
|
+
AND e.status = 'mislukt' AND e.created_at > now() - interval '24 hours';
|
|
40173
|
+
onderdeel := 'Mislukte herplanning (laatste 24 uur)'; ok := n = 0;
|
|
40174
|
+
toelichting := CASE WHEN n = 0 THEN 'geen' ELSE n || ' keer; laatste: ' || coalesce((SELECT coalesce(e.order_ref, '?') || ': ' || coalesce(e.error, '') FROM public.logistics_trace_events e
|
|
40175
|
+
WHERE e.actor IN ('trg_logistics_plan_order_items', 'trg_logistics_plan_orders') AND e.status = 'mislukt'
|
|
40176
|
+
ORDER BY e.created_at DESC LIMIT 1), '') END;
|
|
40177
|
+
RETURN NEXT;
|
|
40178
|
+
RETURN QUERY SELECT * FROM public.logistics_install_check_194();
|
|
40179
|
+
RETURN QUERY SELECT * FROM public.logistics_install_check_196();
|
|
40180
|
+
RETURN QUERY SELECT * FROM public.logistics_install_check_197();
|
|
40181
|
+
RETURN QUERY SELECT * FROM public.logistics_install_check_198();
|
|
40182
|
+
RETURN QUERY SELECT * FROM public.logistics_access_check();
|
|
40183
|
+
RETURN QUERY SELECT * FROM public.logistics_overload_check();
|
|
40184
|
+
RETURN QUERY SELECT * FROM public.logistics_check_190();
|
|
40185
|
+
RETURN QUERY SELECT * FROM public.logistics_install_check_productiebon();
|
|
40186
|
+
END $function$;
|
|
40187
|
+
-- Productiebon goedkeuren vanaf pickstation (v2)
|
|
40188
|
+
CREATE OR REPLACE FUNCTION public.logistics_productiebon_goedkeuren_v2(p_queue_id uuid, p_bron jsonb DEFAULT NULL)
|
|
40189
|
+
RETURNS jsonb LANGUAGE plpgsql SECURITY DEFINER SET search_path TO 'public'
|
|
40190
|
+
AS $function$
|
|
40191
|
+
DECLARE v_queued uuid; v_po text; v_n integer; v_station uuid; v_via jsonb; v_uid uuid := auth.uid();
|
|
40192
|
+
BEGIN
|
|
40193
|
+
-- Direct via de API: alleen ingelogd. Geneste aanroep (bv. pickstation-wrapper na pick_device_check) mag.
|
|
40194
|
+
PERFORM public.logistics_acc_guard('ingelogd', 'logistics_productiebon_goedkeuren_v2');
|
|
40195
|
+
v_station := public.logistics_try_uuid(p_bron->>'stationId');
|
|
40196
|
+
IF v_uid IS NULL AND v_station IS NULL THEN
|
|
40197
|
+
RETURN jsonb_build_object('ok', false, 'melding', 'Goedkeuren kan alleen door een ingelogde gebruiker of een gekoppeld pickstation.');
|
|
40198
|
+
END IF;
|
|
40199
|
+
v_via := jsonb_build_object(
|
|
40200
|
+
'soort', CASE WHEN v_station IS NOT NULL THEN 'pickstation' ELSE 'gebruiker' END,
|
|
40201
|
+
'stationId', v_station, 'stationSlug', p_bron->>'stationSlug', 'deviceId', p_bron->>'deviceId');
|
|
40202
|
+
SELECT id INTO v_queued FROM public.pick_document_statuses WHERE code = 'queued' LIMIT 1;
|
|
40203
|
+
UPDATE public.pick_queue q
|
|
40204
|
+
SET status_id = coalesce(v_queued, q.status_id), updated_at = now(),
|
|
40205
|
+
payload = q.payload || jsonb_build_object('approvedAt', now(), 'approvedBy', v_uid, 'approvedVia', v_via)
|
|
40206
|
+
WHERE q.id = p_queue_id AND q.payload ? 'productie_order_id'
|
|
40207
|
+
AND (v_station IS NULL OR q.station_id = v_station)
|
|
40208
|
+
AND coalesce((q.payload->>'requiresApproval')::boolean, false)
|
|
40209
|
+
AND q.payload->>'approvedAt' IS NULL AND q.cancelled_at IS NULL AND q.completed_at IS NULL
|
|
40210
|
+
RETURNING q.payload->>'productie_order_id' INTO v_po;
|
|
40211
|
+
GET DIAGNOSTICS v_n = ROW_COUNT;
|
|
40212
|
+
IF v_n = 0 THEN
|
|
40213
|
+
RETURN jsonb_build_object('ok', false, 'melding', 'Deze productiebon wacht niet (meer) op goedkeuring op dit station.');
|
|
40214
|
+
END IF;
|
|
40215
|
+
PERFORM public.logistics_productiebon_log_schrijf(v_po::uuid, 'goedkeuren', 'ok',
|
|
40216
|
+
'Goedgekeurd via ' || (v_via->>'soort') || coalesce(' ' || (p_bron->>'stationSlug'), '') || coalesce(' apparaat ' || (p_bron->>'deviceId'), ''));
|
|
40217
|
+
RETURN jsonb_build_object('ok', true, 'melding', 'Productiebon goedgekeurd.');
|
|
40218
|
+
END $function$;
|
|
40219
|
+
REVOKE ALL ON FUNCTION public.logistics_productiebon_goedkeuren_v2(uuid, jsonb) FROM PUBLIC, anon;
|
|
40220
|
+
GRANT EXECUTE ON FUNCTION public.logistics_productiebon_goedkeuren_v2(uuid, jsonb) TO authenticated, service_role;
|
|
40221
|
+
|
|
40222
|
+
CREATE OR REPLACE FUNCTION public.logistics_productiebon_goedkeuren(p_queue_id uuid)
|
|
40223
|
+
RETURNS jsonb LANGUAGE plpgsql SECURITY DEFINER SET search_path TO 'public'
|
|
40224
|
+
AS $function$
|
|
40225
|
+
BEGIN
|
|
40226
|
+
PERFORM public.logistics_acc_guard('ingelogd', 'logistics_productiebon_goedkeuren');
|
|
40227
|
+
RETURN public.logistics_productiebon_goedkeuren_v2(p_queue_id, NULL);
|
|
40228
|
+
END $function$;
|
|
40229
|
+
|
|
40230
|
+
CREATE OR REPLACE FUNCTION public.logistics_install_check_productiebon()
|
|
40231
|
+
RETURNS TABLE(onderdeel text, ok boolean, toelichting text) LANGUAGE plpgsql STABLE SECURITY DEFINER SET search_path TO 'public'
|
|
40232
|
+
AS $function$
|
|
40233
|
+
DECLARE f text;
|
|
40234
|
+
BEGIN
|
|
40235
|
+
FOREACH f IN ARRAY ARRAY['logistics_productiebon_sync(uuid)','logistics_productiebon_goedkeuren(uuid)',
|
|
40236
|
+
'logistics_productiebon_goedkeuren_v2(uuid,jsonb)',
|
|
40237
|
+
'logistics_productiebon_status()','logistics_productie_orders_trg()'] LOOP
|
|
40238
|
+
onderdeel := 'functie ' || f; ok := to_regprocedure('public.' || f) IS NOT NULL;
|
|
40239
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt: werk de Engine bij via Supabase bijwerken' END; RETURN NEXT;
|
|
40240
|
+
END LOOP;
|
|
40241
|
+
onderdeel := 'tabel logistics_productiebon_log'; ok := to_regclass('public.logistics_productiebon_log') IS NOT NULL;
|
|
40242
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt' END; RETURN NEXT;
|
|
40243
|
+
onderdeel := 'trigger trg_logistics_productie_orders_productiebon';
|
|
40244
|
+
IF to_regclass('public.productie_orders') IS NULL THEN ok := true; toelichting := 'niet nodig: Voorraad-productieorders ontbreken';
|
|
40245
|
+
ELSE ok := EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'trg_logistics_productie_orders_productiebon' AND tgrelid = 'public.productie_orders'::regclass);
|
|
40246
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt: werk de Engine bij via Supabase bijwerken' END; END IF;
|
|
40247
|
+
RETURN NEXT;
|
|
40248
|
+
END $function$;
|
|
40249
|
+
-- Productiebon-station leesfunctie (20261109101920.sql)
|
|
40250
|
+
CREATE OR REPLACE FUNCTION public.logistics_productiebon_station()
|
|
40251
|
+
RETURNS jsonb
|
|
40252
|
+
LANGUAGE plpgsql
|
|
40253
|
+
STABLE SECURITY DEFINER
|
|
40254
|
+
SET search_path TO 'public'
|
|
40255
|
+
AS $function$
|
|
40256
|
+
DECLARE v_station uuid; v_slug text;
|
|
40257
|
+
BEGIN
|
|
40258
|
+
-- Direct via de API: alleen ingelogd. Geneste aanroep (pickstation-wrapper) mag, net als _v2.
|
|
40259
|
+
PERFORM public.logistics_acc_guard('ingelogd', 'logistics_productiebon_station');
|
|
40260
|
+
IF to_regclass('public.pick_stations') IS NULL THEN RETURN '{}'::jsonb; END IF;
|
|
40261
|
+
SELECT public.logistics_try_uuid(settings->'pickstations'->'fields'->>'production_note_station') INTO v_station
|
|
40262
|
+
FROM public.logistics_rule_configs
|
|
40263
|
+
ORDER BY is_active DESC, (status = 'actief') DESC, updated_at DESC LIMIT 1;
|
|
40264
|
+
IF v_station IS NULL THEN RETURN '{}'::jsonb; END IF;
|
|
40265
|
+
SELECT s.slug INTO v_slug FROM public.pick_stations s WHERE s.id = v_station;
|
|
40266
|
+
IF NOT FOUND THEN RETURN '{}'::jsonb; END IF;
|
|
40267
|
+
RETURN jsonb_build_object('station_id', v_station, 'station_slug', v_slug);
|
|
40268
|
+
END $function$;
|
|
40269
|
+
|
|
40270
|
+
REVOKE ALL ON FUNCTION public.logistics_productiebon_station() FROM PUBLIC, anon;
|
|
40271
|
+
GRANT EXECUTE ON FUNCTION public.logistics_productiebon_station() TO authenticated, service_role;
|
|
40272
|
+
|
|
40273
|
+
CREATE OR REPLACE FUNCTION public.logistics_productiebon_status()
|
|
40274
|
+
RETURNS jsonb
|
|
40275
|
+
LANGUAGE plpgsql
|
|
40276
|
+
STABLE SECURITY DEFINER
|
|
40277
|
+
SET search_path TO 'public'
|
|
40278
|
+
AS $function$
|
|
40279
|
+
DECLARE v_type uuid; r jsonb; v_station jsonb;
|
|
40280
|
+
BEGIN
|
|
40281
|
+
PERFORM public.logistics_acc_guard('ingelogd', 'logistics_productiebon_status');
|
|
40282
|
+
IF to_regclass('public.pick_queue') IS NULL OR to_regclass('public.pick_document_types') IS NULL THEN
|
|
40283
|
+
RETURN jsonb_build_object('beschikbaar', false);
|
|
40284
|
+
END IF;
|
|
40285
|
+
v_station := public.logistics_productiebon_station();
|
|
40286
|
+
SELECT id INTO v_type FROM public.pick_document_types WHERE code = 'productiebon' LIMIT 1;
|
|
40287
|
+
SELECT jsonb_build_object('beschikbaar', true,
|
|
40288
|
+
'stationIngesteld', v_station ? 'station_id',
|
|
40289
|
+
'stationMelding', CASE WHEN v_station ? 'station_id' THEN NULL ELSE 'Kies een pickstation voor productiebonnen' END,
|
|
40290
|
+
'inWachtrij', count(*) FILTER (WHERE q.cancelled_at IS NULL AND q.completed_at IS NULL
|
|
40291
|
+
AND NOT (coalesce((q.payload->>'requiresApproval')::boolean,false) AND q.payload->>'approvedAt' IS NULL)),
|
|
40292
|
+
'wachtOpGoedkeuring', count(*) FILTER (WHERE q.cancelled_at IS NULL AND q.completed_at IS NULL
|
|
40293
|
+
AND coalesce((q.payload->>'requiresApproval')::boolean,false) AND q.payload->>'approvedAt' IS NULL))
|
|
40294
|
+
INTO r FROM public.pick_queue q WHERE q.document_type_id = v_type AND q.payload ? 'productie_order_id';
|
|
40295
|
+
RETURN r || jsonb_build_object('fouten', coalesce((SELECT jsonb_agg(jsonb_build_object('op', l.created_at, 'status', l.status, 'melding', l.melding) ORDER BY l.created_at DESC)
|
|
40296
|
+
FROM (SELECT * FROM public.logistics_productiebon_log WHERE status IN ('fout','overgeslagen') AND created_at > now() - interval '7 days'
|
|
40297
|
+
ORDER BY created_at DESC LIMIT 5) l), '[]'::jsonb));
|
|
40298
|
+
END $function$;
|
|
40299
|
+
|
|
40300
|
+
CREATE OR REPLACE FUNCTION public.logistics_install_check_productiebon()
|
|
40301
|
+
RETURNS TABLE(onderdeel text, ok boolean, toelichting text)
|
|
40302
|
+
LANGUAGE plpgsql
|
|
40303
|
+
STABLE SECURITY DEFINER
|
|
40304
|
+
SET search_path TO 'public'
|
|
40305
|
+
AS $function$
|
|
40306
|
+
DECLARE f text;
|
|
40307
|
+
BEGIN
|
|
40308
|
+
FOREACH f IN ARRAY ARRAY['logistics_productiebon_sync(uuid)','logistics_productiebon_goedkeuren(uuid)',
|
|
40309
|
+
'logistics_productiebon_goedkeuren_v2(uuid,jsonb)','logistics_productiebon_station()',
|
|
40310
|
+
'logistics_productiebon_status()','logistics_productie_orders_trg()'] LOOP
|
|
40311
|
+
onderdeel := 'functie ' || f; ok := to_regprocedure('public.' || f) IS NOT NULL;
|
|
40312
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt: werk de Engine bij via Supabase bijwerken' END; RETURN NEXT;
|
|
40313
|
+
END LOOP;
|
|
40314
|
+
onderdeel := 'tabel logistics_productiebon_log'; ok := to_regclass('public.logistics_productiebon_log') IS NOT NULL;
|
|
40315
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt' END; RETURN NEXT;
|
|
40316
|
+
onderdeel := 'trigger trg_logistics_productie_orders_productiebon';
|
|
40317
|
+
IF to_regclass('public.productie_orders') IS NULL THEN ok := true; toelichting := 'niet nodig: Voorraad-productieorders ontbreken';
|
|
40318
|
+
ELSE ok := EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'trg_logistics_productie_orders_productiebon' AND tgrelid = 'public.productie_orders'::regclass);
|
|
40319
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt: werk de Engine bij via Supabase bijwerken' END; END IF;
|
|
40320
|
+
RETURN NEXT;
|
|
40321
|
+
END $function$;
|
|
40322
|
+
|
|
40323
|
+
-- Standaardstations voor documenten (system_code)
|
|
40324
|
+
CREATE OR REPLACE FUNCTION public.logistics_station_voor_document(p_document text)
|
|
40325
|
+
RETURNS jsonb
|
|
40326
|
+
LANGUAGE plpgsql
|
|
40327
|
+
STABLE SECURITY DEFINER
|
|
40328
|
+
SET search_path TO 'public'
|
|
40329
|
+
AS $function$
|
|
40330
|
+
DECLARE
|
|
40331
|
+
v_doc text := lower(btrim(coalesce(p_document, '')));
|
|
40332
|
+
v_key text; v_code text; v_label text;
|
|
40333
|
+
v_gekozen uuid; v_weg boolean := false; r record; v_heeft_code boolean;
|
|
40334
|
+
BEGIN
|
|
40335
|
+
PERFORM public.logistics_acc_guard('ingelogd', 'logistics_station_voor_document');
|
|
40336
|
+
SELECT t.k, t.c, t.l INTO v_key, v_code, v_label FROM (VALUES
|
|
40337
|
+
('pakbon','packing_slip_station','orders','pakbonnen'),
|
|
40338
|
+
('pakbonnen','packing_slip_station','orders','pakbonnen'),
|
|
40339
|
+
('sticker','sticker_station','orders','stickers'),
|
|
40340
|
+
('stickers','sticker_station','orders','stickers'),
|
|
40341
|
+
('verzendbrief','shipping_note_station','orders','verzendbrieven'),
|
|
40342
|
+
('verzendbrieven','shipping_note_station','orders','verzendbrieven'),
|
|
40343
|
+
('veilingbrief','shipping_note_station','orders','verzendbrieven'),
|
|
40344
|
+
('transportbrief','shipping_note_station','orders','verzendbrieven'),
|
|
40345
|
+
('productiebon','production_note_station','productie','productiebonnen'),
|
|
40346
|
+
('productiebonnen','production_note_station','productie','productiebonnen'),
|
|
40347
|
+
('productielijst','production_note_station','productie','productiebonnen')
|
|
40348
|
+
) AS t(d, k, c, l) WHERE t.d = v_doc;
|
|
40349
|
+
IF v_key IS NULL THEN
|
|
40350
|
+
RETURN jsonb_build_object('bron','geen','melding','Onbekend document: ' || coalesce(p_document,''));
|
|
40351
|
+
END IF;
|
|
40352
|
+
IF to_regclass('public.pick_stations') IS NULL THEN
|
|
40353
|
+
RETURN jsonb_build_object('document', v_label, 'bron','geen','melding','Kies een pickstation voor ' || v_label);
|
|
40354
|
+
END IF;
|
|
40355
|
+
|
|
40356
|
+
SELECT public.logistics_try_uuid(settings->'pickstations'->'fields'->>v_key) INTO v_gekozen
|
|
40357
|
+
FROM public.logistics_rule_configs
|
|
40358
|
+
ORDER BY is_active DESC, (status = 'actief') DESC, updated_at DESC LIMIT 1;
|
|
40359
|
+
|
|
40360
|
+
IF v_gekozen IS NOT NULL THEN
|
|
40361
|
+
SELECT s.id, s.slug, s.name, s.active INTO r FROM public.pick_stations s WHERE s.id = v_gekozen;
|
|
40362
|
+
IF FOUND THEN
|
|
40363
|
+
RETURN jsonb_build_object('document', v_label, 'bron','gekozen', 'station_id', r.id,
|
|
40364
|
+
'station_slug', r.slug, 'station_naam', r.name, 'actief', coalesce(r.active, true));
|
|
40365
|
+
END IF;
|
|
40366
|
+
v_weg := true;
|
|
40367
|
+
END IF;
|
|
40368
|
+
|
|
40369
|
+
v_heeft_code := EXISTS (SELECT 1 FROM pg_attribute WHERE attrelid = 'public.pick_stations'::regclass
|
|
40370
|
+
AND attname = 'system_code' AND NOT attisdropped);
|
|
40371
|
+
IF v_heeft_code THEN
|
|
40372
|
+
EXECUTE 'SELECT s.id, s.slug, s.name, s.active FROM public.pick_stations s WHERE s.system_code = $1 LIMIT 1'
|
|
40373
|
+
INTO r USING v_code;
|
|
40374
|
+
IF r.id IS NOT NULL THEN
|
|
40375
|
+
RETURN jsonb_build_object('document', v_label, 'bron','standaard', 'system_code', v_code,
|
|
40376
|
+
'station_id', r.id, 'station_slug', r.slug, 'station_naam', r.name, 'actief', coalesce(r.active, true),
|
|
40377
|
+
'gekozenBestaatNiet', v_weg);
|
|
40378
|
+
END IF;
|
|
40379
|
+
END IF;
|
|
40380
|
+
RETURN jsonb_build_object('document', v_label, 'bron','geen', 'system_code', v_code,
|
|
40381
|
+
'gekozenBestaatNiet', v_weg, 'melding', 'Kies een pickstation voor ' || v_label);
|
|
40382
|
+
END $function$;
|
|
40383
|
+
|
|
40384
|
+
REVOKE ALL ON FUNCTION public.logistics_station_voor_document(text) FROM PUBLIC, anon;
|
|
40385
|
+
GRANT EXECUTE ON FUNCTION public.logistics_station_voor_document(text) TO authenticated, service_role;
|
|
40386
|
+
|
|
40387
|
+
CREATE OR REPLACE FUNCTION public.logistics_station_in_gebruik(p_station_id uuid)
|
|
40388
|
+
RETURNS jsonb
|
|
40389
|
+
LANGUAGE plpgsql
|
|
40390
|
+
STABLE SECURITY DEFINER
|
|
40391
|
+
SET search_path TO 'public'
|
|
40392
|
+
AS $function$
|
|
40393
|
+
DECLARE d text; v jsonb; res jsonb := '[]'::jsonb;
|
|
40394
|
+
BEGIN
|
|
40395
|
+
-- Direct via de API: alleen beheer. Geneste aanroep (trigger/wrapper van Pickschermen) mag.
|
|
40396
|
+
PERFORM public.logistics_acc_guard('beheer', 'logistics_station_in_gebruik');
|
|
40397
|
+
IF p_station_id IS NULL THEN RETURN res; END IF;
|
|
40398
|
+
FOREACH d IN ARRAY ARRAY['productiebon','pakbon','stickers','verzendbrief'] LOOP
|
|
40399
|
+
v := public.logistics_station_voor_document(d);
|
|
40400
|
+
IF v->>'station_id' = p_station_id::text THEN res := res || to_jsonb(v->>'document'); END IF;
|
|
40401
|
+
END LOOP;
|
|
40402
|
+
RETURN res;
|
|
40403
|
+
END $function$;
|
|
40404
|
+
|
|
40405
|
+
REVOKE ALL ON FUNCTION public.logistics_station_in_gebruik(uuid) FROM PUBLIC, anon;
|
|
40406
|
+
GRANT EXECUTE ON FUNCTION public.logistics_station_in_gebruik(uuid) TO authenticated, service_role;
|
|
40407
|
+
|
|
40408
|
+
CREATE OR REPLACE FUNCTION public.logistics_station_meldingen()
|
|
40409
|
+
RETURNS jsonb
|
|
40410
|
+
LANGUAGE plpgsql
|
|
40411
|
+
STABLE SECURITY DEFINER
|
|
40412
|
+
SET search_path TO 'public'
|
|
40413
|
+
AS $function$
|
|
40414
|
+
DECLARE d text; v jsonb; res jsonb := '[]'::jsonb;
|
|
40415
|
+
BEGIN
|
|
40416
|
+
PERFORM public.logistics_acc_guard('ingelogd', 'logistics_station_meldingen');
|
|
40417
|
+
FOREACH d IN ARRAY ARRAY['productiebon','pakbon','stickers','verzendbrief'] LOOP
|
|
40418
|
+
v := public.logistics_station_voor_document(d);
|
|
40419
|
+
IF coalesce((v->>'gekozenBestaatNiet')::boolean, false) THEN
|
|
40420
|
+
res := res || to_jsonb('Het gekozen station voor ' || (v->>'document') || ' bestaat niet meer; het standaardstation wordt gebruikt.');
|
|
40421
|
+
END IF;
|
|
40422
|
+
IF v->>'bron' = 'geen' THEN
|
|
40423
|
+
res := res || to_jsonb(v->>'melding');
|
|
40424
|
+
ELSIF NOT coalesce((v->>'actief')::boolean, true) THEN
|
|
40425
|
+
res := res || to_jsonb('Het station ' || coalesce(v->>'station_naam','') || ' staat uit, maar krijgt nog ' || (v->>'document') || '.');
|
|
40426
|
+
END IF;
|
|
40427
|
+
END LOOP;
|
|
40428
|
+
RETURN res;
|
|
40429
|
+
END $function$;
|
|
40430
|
+
|
|
40431
|
+
REVOKE ALL ON FUNCTION public.logistics_station_meldingen() FROM PUBLIC, anon;
|
|
40432
|
+
GRANT EXECUTE ON FUNCTION public.logistics_station_meldingen() TO authenticated, service_role;
|
|
40433
|
+
|
|
40434
|
+
CREATE OR REPLACE FUNCTION public.logistics_document_station(_document_code text)
|
|
40435
|
+
RETURNS uuid
|
|
40436
|
+
LANGUAGE plpgsql
|
|
40437
|
+
STABLE SECURITY DEFINER
|
|
40438
|
+
SET search_path TO 'public'
|
|
40439
|
+
AS $function$
|
|
40440
|
+
BEGIN
|
|
40441
|
+
PERFORM public.logistics_acc_guard('ingelogd', 'logistics_document_station');
|
|
40442
|
+
RETURN public.logistics_try_uuid(public.logistics_station_voor_document(_document_code)->>'station_id');
|
|
40443
|
+
EXCEPTION WHEN others THEN
|
|
40444
|
+
RETURN NULL;
|
|
40445
|
+
END;
|
|
40446
|
+
$function$;
|
|
40447
|
+
|
|
40448
|
+
CREATE OR REPLACE FUNCTION public.logistics_productiebon_station()
|
|
40449
|
+
RETURNS jsonb
|
|
40450
|
+
LANGUAGE plpgsql
|
|
40451
|
+
STABLE SECURITY DEFINER
|
|
40452
|
+
SET search_path TO 'public'
|
|
40453
|
+
AS $function$
|
|
40454
|
+
DECLARE v jsonb;
|
|
40455
|
+
BEGIN
|
|
40456
|
+
-- Direct via de API: alleen ingelogd. Geneste aanroep (pickstation-wrapper) mag, net als _v2.
|
|
40457
|
+
PERFORM public.logistics_acc_guard('ingelogd', 'logistics_productiebon_station');
|
|
40458
|
+
v := public.logistics_station_voor_document('productiebon');
|
|
40459
|
+
IF NOT (v ? 'station_id') THEN RETURN '{}'::jsonb; END IF;
|
|
40460
|
+
RETURN jsonb_build_object('station_id', (v->>'station_id')::uuid, 'station_slug', v->>'station_slug');
|
|
40461
|
+
END $function$;
|
|
40462
|
+
|
|
40463
|
+
-- Stickers en traystickers: lege of verdwenen stationkeuze -> standaardstation 'orders' (pakbon en stickers delen die standaard).
|
|
40464
|
+
CREATE OR REPLACE FUNCTION public.logistics_sticker_cart_plek(_cart uuid, _fallback text)
|
|
40465
|
+
RETURNS text
|
|
40466
|
+
LANGUAGE sql
|
|
40467
|
+
STABLE SECURITY DEFINER
|
|
40468
|
+
SET search_path TO 'public'
|
|
40469
|
+
AS $function$
|
|
40470
|
+
SELECT public.logistics_acc_guard('ingelogd', 'logistics_sticker_cart_plek');
|
|
40471
|
+
SELECT coalesce(
|
|
40472
|
+
(SELECT nullif(btrim(pj.payload->>'print_plek_id'),'') FROM public.print_jobs pj
|
|
40473
|
+
WHERE pj.payload->>'cart_id' = _cart::text AND pj.documenttype = 'pakbon'
|
|
40474
|
+
AND coalesce(pj.is_herprint,false) = false
|
|
40475
|
+
ORDER BY pj.created_at DESC LIMIT 1),
|
|
40476
|
+
(SELECT s.id::text FROM public.pick_stations s WHERE s.id = public.logistics_try_uuid(_fallback)),
|
|
40477
|
+
nullif(public.logistics_station_voor_document('stickers')->>'station_id', ''));
|
|
40478
|
+
$function$;
|
|
40479
|
+
|
|
40480
|
+
CREATE OR REPLACE FUNCTION public.logistics_productiebon_sync(p_productie_order_id uuid)
|
|
40481
|
+
RETURNS jsonb LANGUAGE plpgsql SECURITY DEFINER SET search_path TO 'public'
|
|
40482
|
+
AS $function$
|
|
40483
|
+
DECLARE
|
|
40484
|
+
po record; s jsonb; v_release text; v_approval boolean; v_station uuid; v_screen uuid;
|
|
40485
|
+
v_type uuid; v_queued uuid; v_new uuid; v_cancel uuid; v_done uuid; v_row record; v_lines integer; v_payload jsonb; v_n integer;
|
|
40486
|
+
BEGIN
|
|
40487
|
+
SELECT * INTO po FROM public.productie_orders WHERE id = p_productie_order_id;
|
|
40488
|
+
IF NOT FOUND THEN RETURN jsonb_build_object('actie','geen','reden','productieorder niet gevonden'); END IF;
|
|
40489
|
+
SELECT id INTO v_type FROM public.pick_document_types WHERE code = 'productiebon' LIMIT 1;
|
|
40490
|
+
IF v_type IS NULL THEN
|
|
40491
|
+
PERFORM public.logistics_productiebon_log_schrijf(po.id, 'sync', 'fout', 'Documentsoort productiebon ontbreekt in de pickschermen.');
|
|
40492
|
+
RETURN jsonb_build_object('actie','fout','reden','documentsoort productiebon ontbreekt');
|
|
40493
|
+
END IF;
|
|
40494
|
+
SELECT id INTO v_queued FROM public.pick_document_statuses WHERE code = 'queued' LIMIT 1;
|
|
40495
|
+
SELECT id INTO v_new FROM public.pick_document_statuses WHERE code = 'new' LIMIT 1;
|
|
40496
|
+
SELECT id INTO v_cancel FROM public.pick_document_statuses WHERE code = 'cancelled' LIMIT 1;
|
|
40497
|
+
SELECT id INTO v_done FROM public.pick_document_statuses WHERE code = 'done' LIMIT 1;
|
|
40498
|
+
SELECT q.* INTO v_row FROM public.pick_queue q
|
|
40499
|
+
WHERE q.document_type_id = v_type AND q.payload->>'productie_order_id' = po.id::text
|
|
40500
|
+
ORDER BY q.created_at DESC LIMIT 1;
|
|
40501
|
+
|
|
40502
|
+
IF po.status = 'geannuleerd' THEN
|
|
40503
|
+
UPDATE public.pick_queue q SET cancelled_at = now(), status_id = coalesce(v_cancel, q.status_id), updated_at = now(),
|
|
40504
|
+
payload = coalesce(q.payload,'{}'::jsonb) || jsonb_build_object('cancelReason','Productieorder geannuleerd')
|
|
40505
|
+
WHERE q.document_type_id = v_type AND q.payload->>'productie_order_id' = po.id::text
|
|
40506
|
+
AND q.cancelled_at IS NULL AND q.completed_at IS NULL;
|
|
40507
|
+
GET DIAGNOSTICS v_n = ROW_COUNT;
|
|
40508
|
+
PERFORM public.logistics_productiebon_log_schrijf(po.id, 'annuleren', 'ok', v_n || ' regel(s) uit de wachtrij');
|
|
40509
|
+
RETURN jsonb_build_object('actie','geannuleerd','regels',v_n);
|
|
40510
|
+
ELSIF po.status = 'verwerkt' THEN
|
|
40511
|
+
UPDATE public.pick_queue q SET completed_at = now(), status_id = coalesce(v_done, q.status_id), updated_at = now()
|
|
40512
|
+
WHERE q.document_type_id = v_type AND q.payload->>'productie_order_id' = po.id::text
|
|
40513
|
+
AND q.cancelled_at IS NULL AND q.completed_at IS NULL;
|
|
40514
|
+
GET DIAGNOSTICS v_n = ROW_COUNT;
|
|
40515
|
+
PERFORM public.logistics_productiebon_log_schrijf(po.id, 'afronden', 'ok', v_n || ' regel(s) afgerond');
|
|
40516
|
+
RETURN jsonb_build_object('actie','afgerond','regels',v_n);
|
|
40517
|
+
ELSIF po.status <> 'open' THEN
|
|
40518
|
+
RETURN jsonb_build_object('actie','geen','reden','status ' || coalesce(po.status,'leeg') || ' verandert de wachtrij niet');
|
|
40519
|
+
END IF;
|
|
40520
|
+
|
|
40521
|
+
SELECT settings INTO s FROM public.logistics_rule_configs
|
|
40522
|
+
ORDER BY is_active DESC, (status = 'actief') DESC, updated_at DESC LIMIT 1;
|
|
40523
|
+
v_release := coalesce(public.logistics_rule_text(s, 'pickstations', 'production_note_release', 'on_stock_upgrade'), 'on_stock_upgrade');
|
|
40524
|
+
v_approval := v_release = 'manual_approval_after_upgrade';
|
|
40525
|
+
v_station := public.logistics_try_uuid(public.logistics_station_voor_document('productiebon')->>'station_id');
|
|
40526
|
+
SELECT count(*)::int INTO v_lines FROM public.productie_order_onderdelen o WHERE o.productie_order_id = po.id;
|
|
40527
|
+
v_payload := jsonb_build_object('source','logistiek-engine','documentType','productiebon',
|
|
40528
|
+
'productie_order_id', po.id, 'productieOrderNummer', po.nummer, 'productId', po.product_id,
|
|
40529
|
+
'tradeItemKey', po.trade_item_key, 'aantal', po.aantal, 'opmerking', po.opmerking,
|
|
40530
|
+
'onderdelen', v_lines);
|
|
40531
|
+
|
|
40532
|
+
IF v_row.id IS NOT NULL THEN
|
|
40533
|
+
IF v_row.cancelled_at IS NULL AND v_row.completed_at IS NULL THEN
|
|
40534
|
+
UPDATE public.pick_queue q SET document_number = po.nummer, line_count = v_lines,
|
|
40535
|
+
payload = coalesce(q.payload,'{}'::jsonb) || v_payload, updated_at = now()
|
|
40536
|
+
WHERE q.id = v_row.id
|
|
40537
|
+
AND (q.document_number, q.line_count, coalesce(q.payload,'{}'::jsonb))
|
|
40538
|
+
IS DISTINCT FROM (po.nummer, v_lines, coalesce(q.payload,'{}'::jsonb) || v_payload);
|
|
40539
|
+
END IF;
|
|
40540
|
+
RETURN jsonb_build_object('actie','bestaat','queueId',v_row.id);
|
|
40541
|
+
END IF;
|
|
40542
|
+
|
|
40543
|
+
IF v_station IS NULL OR NOT EXISTS (SELECT 1 FROM public.pick_stations WHERE id = v_station) THEN
|
|
40544
|
+
PERFORM public.logistics_productiebon_log_schrijf(po.id, 'aanmaken', 'overgeslagen',
|
|
40545
|
+
'Kies een pickstation voor productiebonnen (Werkwijze, stap Pickstations).');
|
|
40546
|
+
RETURN jsonb_build_object('actie','overgeslagen','reden','geen pickstation ingesteld');
|
|
40547
|
+
END IF;
|
|
40548
|
+
SELECT sc.id INTO v_screen FROM public.pick_station_screens sc
|
|
40549
|
+
WHERE sc.station_id = v_station
|
|
40550
|
+
ORDER BY (EXISTS (SELECT 1 FROM public.pick_screen_document_types d WHERE d.screen_id = sc.id AND d.document_type_id = v_type)) DESC, sc.created_at
|
|
40551
|
+
LIMIT 1;
|
|
40552
|
+
|
|
40553
|
+
INSERT INTO public.pick_queue (station_id, screen_id, document_type_id, status_id, document_number, order_number, reference,
|
|
40554
|
+
customer_name, line_count, cart_count, priority, is_urgent, announced_at, due_at, payload)
|
|
40555
|
+
VALUES (v_station, v_screen, v_type, CASE WHEN v_approval THEN coalesce(v_new, v_queued) ELSE v_queued END,
|
|
40556
|
+
po.nummer, NULL, po.id::text, NULL, v_lines, 0, 50, false, now(), NULL,
|
|
40557
|
+
v_payload || jsonb_build_object('requiresApproval', v_approval, 'approvedAt', NULL, 'approvedBy', NULL));
|
|
40558
|
+
PERFORM public.logistics_productiebon_log_schrijf(po.id, 'aanmaken', 'ok',
|
|
40559
|
+
CASE WHEN v_approval THEN 'In wachtrij, wacht op goedkeuring' ELSE 'In wachtrij' END);
|
|
40560
|
+
RETURN jsonb_build_object('actie','aangemaakt','wachtOpGoedkeuring',v_approval);
|
|
40561
|
+
END $function$;
|
|
40562
|
+
|
|
40563
|
+
CREATE OR REPLACE FUNCTION public.logistics_productiebon_status()
|
|
40564
|
+
RETURNS jsonb
|
|
40565
|
+
LANGUAGE plpgsql
|
|
40566
|
+
STABLE SECURITY DEFINER
|
|
40567
|
+
SET search_path TO 'public'
|
|
40568
|
+
AS $function$
|
|
40569
|
+
DECLARE v_type uuid; r jsonb; v_station jsonb;
|
|
40570
|
+
BEGIN
|
|
40571
|
+
PERFORM public.logistics_acc_guard('ingelogd', 'logistics_productiebon_status');
|
|
40572
|
+
IF to_regclass('public.pick_queue') IS NULL OR to_regclass('public.pick_document_types') IS NULL THEN
|
|
40573
|
+
RETURN jsonb_build_object('beschikbaar', false);
|
|
40574
|
+
END IF;
|
|
40575
|
+
v_station := public.logistics_productiebon_station();
|
|
40576
|
+
SELECT id INTO v_type FROM public.pick_document_types WHERE code = 'productiebon' LIMIT 1;
|
|
40577
|
+
SELECT jsonb_build_object('beschikbaar', true,
|
|
40578
|
+
'stationIngesteld', v_station ? 'station_id',
|
|
40579
|
+
'stationMelding', CASE WHEN v_station ? 'station_id' THEN NULL ELSE 'Kies een pickstation voor productiebonnen' END,
|
|
40580
|
+
'inWachtrij', count(*) FILTER (WHERE q.cancelled_at IS NULL AND q.completed_at IS NULL
|
|
40581
|
+
AND NOT (coalesce((q.payload->>'requiresApproval')::boolean,false) AND q.payload->>'approvedAt' IS NULL)),
|
|
40582
|
+
'wachtOpGoedkeuring', count(*) FILTER (WHERE q.cancelled_at IS NULL AND q.completed_at IS NULL
|
|
40583
|
+
AND coalesce((q.payload->>'requiresApproval')::boolean,false) AND q.payload->>'approvedAt' IS NULL))
|
|
40584
|
+
INTO r FROM public.pick_queue q WHERE q.document_type_id = v_type AND q.payload ? 'productie_order_id';
|
|
40585
|
+
RETURN r || jsonb_build_object('stationMeldingen', public.logistics_station_meldingen(),
|
|
40586
|
+
'fouten', coalesce((SELECT jsonb_agg(jsonb_build_object('op', l.created_at, 'status', l.status, 'melding', l.melding) ORDER BY l.created_at DESC)
|
|
40587
|
+
FROM (SELECT * FROM public.logistics_productiebon_log WHERE status IN ('fout','overgeslagen') AND created_at > now() - interval '7 days'
|
|
40588
|
+
ORDER BY created_at DESC LIMIT 5) l), '[]'::jsonb));
|
|
40589
|
+
END $function$;
|
|
40590
|
+
|
|
40591
|
+
CREATE OR REPLACE FUNCTION public.logistics_install_check_productiebon()
|
|
40592
|
+
RETURNS TABLE(onderdeel text, ok boolean, toelichting text)
|
|
40593
|
+
LANGUAGE plpgsql
|
|
40594
|
+
STABLE SECURITY DEFINER
|
|
40595
|
+
SET search_path TO 'public'
|
|
40596
|
+
AS $function$
|
|
40597
|
+
DECLARE f text;
|
|
40598
|
+
BEGIN
|
|
40599
|
+
FOREACH f IN ARRAY ARRAY['logistics_productiebon_sync(uuid)','logistics_productiebon_goedkeuren(uuid)',
|
|
40600
|
+
'logistics_productiebon_goedkeuren_v2(uuid,jsonb)','logistics_productiebon_station()',
|
|
40601
|
+
'logistics_productiebon_status()','logistics_productie_orders_trg()',
|
|
40602
|
+
'logistics_station_voor_document(text)','logistics_station_in_gebruik(uuid)','logistics_station_meldingen()'] LOOP
|
|
40603
|
+
onderdeel := 'functie ' || f; ok := to_regprocedure('public.' || f) IS NOT NULL;
|
|
40604
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt: werk de Engine bij via Supabase bijwerken' END; RETURN NEXT;
|
|
40605
|
+
END LOOP;
|
|
40606
|
+
onderdeel := 'tabel logistics_productiebon_log'; ok := to_regclass('public.logistics_productiebon_log') IS NOT NULL;
|
|
40607
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt' END; RETURN NEXT;
|
|
40608
|
+
onderdeel := 'trigger trg_logistics_productie_orders_productiebon';
|
|
40609
|
+
IF to_regclass('public.productie_orders') IS NULL THEN ok := true; toelichting := 'niet nodig: Voorraad-productieorders ontbreken';
|
|
40610
|
+
ELSE ok := EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'trg_logistics_productie_orders_productiebon' AND tgrelid = 'public.productie_orders'::regclass);
|
|
40611
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt: werk de Engine bij via Supabase bijwerken' END; END IF;
|
|
40612
|
+
RETURN NEXT;
|
|
40613
|
+
onderdeel := 'kolom pick_stations.system_code';
|
|
40614
|
+
IF to_regclass('public.pick_stations') IS NULL THEN ok := true; toelichting := 'niet nodig: Pickschermen ontbreekt';
|
|
40615
|
+
ELSE ok := EXISTS (SELECT 1 FROM pg_attribute WHERE attrelid = 'public.pick_stations'::regclass AND attname = 'system_code' AND NOT attisdropped);
|
|
40616
|
+
toelichting := CASE WHEN ok THEN 'aanwezig' ELSE 'ontbreekt: werk Pickschermen bij; tot dan geen standaardstations' END; END IF;
|
|
40617
|
+
RETURN NEXT;
|
|
40618
|
+
END $function$;
|