@flowselections/logistiek-engine 1.0.175 → 1.0.177
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 +1262 -0
- package/dist-lib/components/BeheerPage.d.ts.map +1 -1
- package/dist-lib/components/BeheerPage.js +2 -1
- package/dist-lib/components/DocumentkeuzeCard.d.ts +2 -0
- package/dist-lib/components/DocumentkeuzeCard.d.ts.map +1 -0
- package/dist-lib/components/DocumentkeuzeCard.js +18 -0
- package/dist-lib/index.d.ts +1 -0
- package/dist-lib/index.d.ts.map +1 -1
- package/dist-lib/index.js +1 -0
- package/dist-lib/integrations/supabase/types.d.ts +239 -15
- package/dist-lib/integrations/supabase/types.d.ts.map +1 -1
- package/dist-lib/lib/controlScan.server.js +1 -1
- package/dist-lib/lib/layoutPrint.server.d.ts +10 -1
- package/dist-lib/lib/layoutPrint.server.d.ts.map +1 -1
- package/dist-lib/lib/layoutPrint.server.js +19 -1
- package/dist-lib/lib/modulePrompts.d.ts.map +1 -1
- package/dist-lib/lib/modulePrompts.js +157 -0
- package/dist-lib/lib/moduleVersion.d.ts +1 -1
- package/dist-lib/lib/moduleVersion.js +1 -1
- package/dist-lib/lib/ruleEngineSchema.d.ts.map +1 -1
- package/dist-lib/lib/ruleEngineSchema.js +4 -38
- package/dist-lib/lib/ruleEngineWizard.d.ts.map +1 -1
- package/dist-lib/lib/ruleEngineWizard.js +0 -2
- package/dist-lib/lib/shippingNoteQueue.server.js +1 -1
- package/dist-lib/lib/stickerQueue.server.d.ts +25 -0
- package/dist-lib/lib/stickerQueue.server.d.ts.map +1 -1
- package/dist-lib/lib/stickerQueue.server.js +62 -22
- package/dist-lib/lib/stickerRules.d.ts +17 -0
- package/dist-lib/lib/stickerRules.d.ts.map +1 -1
- package/dist-lib/lib/stickerRules.js +30 -0
- package/package.json +1 -1
|
@@ -28261,3 +28261,1265 @@ ON CONFLICT (key) DO NOTHING;
|
|
|
28261
28261
|
|
|
28262
28262
|
RESET check_function_bodies;
|
|
28263
28263
|
|
|
28264
|
+
|
|
28265
|
+
-- ===== 1.0.176 automatische documentkeuze (idempotent: CREATE OR REPLACE / IF NOT EXISTS) =====
|
|
28266
|
+
-- Logistiek Engine 1.0.176: automatische documentkeuze.
|
|
28267
|
+
-- De gebruiker kiest nergens meer een layout. Eén centrale beslisregel:
|
|
28268
|
+
-- logistics_document_for_order(order, documenttype). Bestaat Layouts'
|
|
28269
|
+
-- layout_voor_document, dan alleen die; anders de automatische standaardlayout.
|
|
28270
|
+
-- Oude werkwijze-keuzes (packing_slip_layout e.d.) blijven staan maar worden genegeerd.
|
|
28271
|
+
-- Geen omgevingswaarden, geen datacorrectie.
|
|
28272
|
+
|
|
28273
|
+
-- 1. Eigen stickers in dezelfde wachtrij als de Floriday-stickers.
|
|
28274
|
+
ALTER TABLE public.logistics_sticker_prints ADD COLUMN IF NOT EXISTS eigen_sticker_id uuid;
|
|
28275
|
+
ALTER TABLE public.logistics_sticker_prints DROP CONSTRAINT IF EXISTS logistics_sticker_prints_soort_check;
|
|
28276
|
+
ALTER TABLE public.logistics_sticker_prints ADD CONSTRAINT logistics_sticker_prints_soort_check
|
|
28277
|
+
CHECK (soort = ANY (ARRAY['sticker'::text, 'traysticker'::text, 'eigen_sticker'::text]));
|
|
28278
|
+
|
|
28279
|
+
-- 2. Automatische keuze zonder werkwijze-overrides.
|
|
28280
|
+
CREATE OR REPLACE FUNCTION public.logistics_document_layout_v2(_document_code text, _is_partial boolean DEFAULT false)
|
|
28281
|
+
RETURNS jsonb
|
|
28282
|
+
LANGUAGE plpgsql
|
|
28283
|
+
STABLE SECURITY DEFINER
|
|
28284
|
+
SET search_path TO 'public'
|
|
28285
|
+
AS $function$
|
|
28286
|
+
DECLARE
|
|
28287
|
+
v_types public.doc_layout_type[];
|
|
28288
|
+
v_layout public.document_layouts%ROWTYPE;
|
|
28289
|
+
BEGIN
|
|
28290
|
+
v_types := public.logistics_document_type_map(lower(btrim(coalesce(_document_code, ''))));
|
|
28291
|
+
IF array_length(v_types, 1) IS NULL THEN RETURN NULL; END IF;
|
|
28292
|
+
SELECT * INTO v_layout
|
|
28293
|
+
FROM public.document_layouts
|
|
28294
|
+
WHERE actief IS TRUE AND documenttype = ANY (v_types)
|
|
28295
|
+
ORDER BY array_position(v_types, documenttype),
|
|
28296
|
+
(coalesce(bron, 'eigen') = 'eigen') DESC,
|
|
28297
|
+
is_standaard DESC NULLS LAST, updated_at DESC
|
|
28298
|
+
LIMIT 1;
|
|
28299
|
+
IF v_layout.id IS NULL THEN RETURN NULL; END IF;
|
|
28300
|
+
RETURN jsonb_build_object(
|
|
28301
|
+
'layoutId', v_layout.id, 'layoutName', v_layout.naam, 'layoutVersion', v_layout.huidige_versie,
|
|
28302
|
+
'layoutDocumentType', v_layout.documenttype::text, 'layoutSettingKey', NULL,
|
|
28303
|
+
'layoutVariant', CASE WHEN COALESCE(_is_partial, false) THEN 'partial_order' ELSE 'full_cart' END,
|
|
28304
|
+
'layoutFallbackUsed', false,
|
|
28305
|
+
'layout_id', v_layout.id, 'layout_name', v_layout.naam, 'layout_version', v_layout.huidige_versie,
|
|
28306
|
+
'layout_document_type', v_layout.documenttype::text, 'layout_setting_key', NULL,
|
|
28307
|
+
'layout_variant', CASE WHEN COALESCE(_is_partial, false) THEN 'partial_order' ELSE 'full_cart' END,
|
|
28308
|
+
'layout_fallback_used', false);
|
|
28309
|
+
END;
|
|
28310
|
+
$function$;
|
|
28311
|
+
|
|
28312
|
+
-- 3. Is Layouts al bijgewerkt?
|
|
28313
|
+
CREATE OR REPLACE FUNCTION public.logistics_document_selection_status()
|
|
28314
|
+
RETURNS jsonb
|
|
28315
|
+
LANGUAGE sql
|
|
28316
|
+
STABLE SECURITY DEFINER
|
|
28317
|
+
SET search_path TO 'public'
|
|
28318
|
+
AS $function$
|
|
28319
|
+
SELECT CASE WHEN to_regprocedure('public.layout_voor_document(uuid,text)') IS NOT NULL
|
|
28320
|
+
THEN jsonb_build_object('layouts_bijgewerkt', true, 'melding', 'Het document wordt automatisch bepaald uit de order (Layouts).')
|
|
28321
|
+
ELSE jsonb_build_object('layouts_bijgewerkt', false, 'melding', 'Layouts is nog niet bijgewerkt – automatische keuze gebruikt')
|
|
28322
|
+
END;
|
|
28323
|
+
$function$;
|
|
28324
|
+
|
|
28325
|
+
-- 4. Centrale beslisregel.
|
|
28326
|
+
CREATE OR REPLACE FUNCTION public.logistics_document_for_order(p_order_id uuid, p_documenttype text)
|
|
28327
|
+
RETURNS jsonb
|
|
28328
|
+
LANGUAGE plpgsql
|
|
28329
|
+
STABLE SECURITY DEFINER
|
|
28330
|
+
SET search_path TO 'public'
|
|
28331
|
+
AS $function$
|
|
28332
|
+
DECLARE
|
|
28333
|
+
v_soort text := lower(btrim(coalesce(p_documenttype, '')));
|
|
28334
|
+
v_floriday boolean;
|
|
28335
|
+
v_bron text;
|
|
28336
|
+
v_type text;
|
|
28337
|
+
v_res jsonb;
|
|
28338
|
+
v_n int; v_std int; v_id uuid;
|
|
28339
|
+
v_l public.document_layouts%ROWTYPE;
|
|
28340
|
+
BEGIN
|
|
28341
|
+
IF v_soort = '' THEN
|
|
28342
|
+
RETURN jsonb_build_object('ok', false, 'layout_id', NULL, 'reden', 'Geen documentsoort opgegeven.');
|
|
28343
|
+
END IF;
|
|
28344
|
+
|
|
28345
|
+
IF to_regprocedure('public.layout_voor_document(uuid,text)') IS NOT NULL THEN
|
|
28346
|
+
EXECUTE 'SELECT to_jsonb(public.layout_voor_document($1, $2))' INTO v_res USING p_order_id, v_soort;
|
|
28347
|
+
IF jsonb_typeof(v_res) <> 'object' THEN
|
|
28348
|
+
RETURN jsonb_build_object('ok', false, 'layout_id', NULL, 'keuze', 'layouts',
|
|
28349
|
+
'reden', 'Layouts gaf geen bruikbaar antwoord voor ' || v_soort || '.');
|
|
28350
|
+
END IF;
|
|
28351
|
+
RETURN v_res || jsonb_build_object('keuze', 'layouts',
|
|
28352
|
+
'ok', coalesce((v_res->>'ok')::boolean, nullif(v_res->>'layout_id', '') IS NOT NULL));
|
|
28353
|
+
END IF;
|
|
28354
|
+
|
|
28355
|
+
-- Automatische keuze (Layouts nog niet bijgewerkt).
|
|
28356
|
+
SELECT o.order_source = 'floriday' INTO v_floriday FROM public.orders o WHERE o.id = p_order_id;
|
|
28357
|
+
IF v_floriday IS NULL THEN
|
|
28358
|
+
RETURN jsonb_build_object('ok', false, 'layout_id', NULL, 'keuze', 'automatisch', 'reden', 'Order niet gevonden.');
|
|
28359
|
+
END IF;
|
|
28360
|
+
|
|
28361
|
+
v_type := CASE
|
|
28362
|
+
WHEN v_soort IN ('eigen_sticker', 'sticker', 'etiket') THEN 'sticker'
|
|
28363
|
+
WHEN v_soort IN ('verzenddocument', 'verzendbrief', 'afleverbrief', 'afleverbon') THEN 'afleverbrief'
|
|
28364
|
+
WHEN v_soort IN ('veilingbrief', 'veilingbon') THEN 'veilingbrief'
|
|
28365
|
+
WHEN v_soort LIKE '%pakbon%' THEN 'pakbon'
|
|
28366
|
+
WHEN v_soort LIKE '%productie%' THEN 'productiebon'
|
|
28367
|
+
ELSE v_soort END;
|
|
28368
|
+
v_bron := CASE
|
|
28369
|
+
WHEN v_floriday AND v_soort <> 'eigen_sticker' AND v_type IN ('sticker', 'traysticker', 'afleverbrief', 'veilingbrief') THEN 'floriday'
|
|
28370
|
+
ELSE 'eigen' END;
|
|
28371
|
+
IF v_bron = 'eigen' AND v_type = 'veilingbrief' THEN
|
|
28372
|
+
RETURN jsonb_build_object('ok', false, 'layout_id', NULL, 'keuze', 'automatisch',
|
|
28373
|
+
'reden', 'Een veilingbrief hoort alleen bij een Floriday-order; voor een eigen order wordt de afleverbrief gebruikt.');
|
|
28374
|
+
END IF;
|
|
28375
|
+
|
|
28376
|
+
SELECT count(*), count(*) FILTER (WHERE is_standaard IS TRUE) INTO v_n, v_std
|
|
28377
|
+
FROM public.document_layouts
|
|
28378
|
+
WHERE actief IS TRUE AND coalesce(bron, 'eigen') = v_bron AND documenttype::text = v_type;
|
|
28379
|
+
IF v_n = 1 THEN
|
|
28380
|
+
SELECT * INTO v_l FROM public.document_layouts
|
|
28381
|
+
WHERE actief IS TRUE AND coalesce(bron, 'eigen') = v_bron AND documenttype::text = v_type;
|
|
28382
|
+
ELSIF v_n > 1 THEN
|
|
28383
|
+
SELECT * INTO v_l FROM public.document_layouts
|
|
28384
|
+
WHERE actief IS TRUE AND coalesce(bron, 'eigen') = v_bron AND documenttype::text = v_type
|
|
28385
|
+
ORDER BY is_standaard DESC NULLS LAST, updated_at DESC LIMIT 1;
|
|
28386
|
+
END IF;
|
|
28387
|
+
IF v_l.id IS NULL THEN
|
|
28388
|
+
RETURN jsonb_build_object('ok', false, 'layout_id', NULL, 'keuze', 'automatisch', 'bron', v_bron, 'documenttype', v_type,
|
|
28389
|
+
'reden', CASE WHEN v_bron = 'floriday'
|
|
28390
|
+
THEN 'Geen actieve ' || v_type || '-layout met bron Floriday. Activeer de Floriday-systeemlayout in Layouts en printers.'
|
|
28391
|
+
ELSE 'Maak of activeer een ' || v_type || 'layout in Layouts en printers.' END);
|
|
28392
|
+
END IF;
|
|
28393
|
+
RETURN jsonb_build_object('ok', true, 'layout_id', v_l.id, 'keuze', 'automatisch', 'bron', v_bron,
|
|
28394
|
+
'documenttype', v_type, 'breedte_mm', v_l.breedte_mm, 'hoogte_mm', v_l.hoogte_mm, 'reden', NULL);
|
|
28395
|
+
END;
|
|
28396
|
+
$function$;
|
|
28397
|
+
|
|
28398
|
+
-- 5. Eigen stickers (HO/MO/AO): één per klant+product, aantal = planten van regels met needs_sticker.
|
|
28399
|
+
CREATE OR REPLACE FUNCTION public.logistics_own_sticker_count(p_unit text, p_quantity numeric, p_ppc_regel numeric, p_ppc_product numeric)
|
|
28400
|
+
RETURNS integer LANGUAGE sql IMMUTABLE SET search_path = public AS $cnt$
|
|
28401
|
+
-- stuks/planten = aantal planten; fust = aantal x planten per fust (regel, anders product); onbekend = NULL (tegenhouden).
|
|
28402
|
+
SELECT CASE
|
|
28403
|
+
WHEN p_quantity IS NULL THEN NULL
|
|
28404
|
+
WHEN lower(coalesce(p_unit, '')) = 'fust' THEN
|
|
28405
|
+
CASE WHEN coalesce(nullif(p_ppc_regel, 0), nullif(p_ppc_product, 0)) IS NULL THEN NULL
|
|
28406
|
+
ELSE (p_quantity * coalesce(nullif(p_ppc_regel, 0), nullif(p_ppc_product, 0)))::int END
|
|
28407
|
+
ELSE p_quantity::int
|
|
28408
|
+
END
|
|
28409
|
+
$cnt$;
|
|
28410
|
+
|
|
28411
|
+
CREATE OR REPLACE FUNCTION public.logistics_own_sticker_sync(p_limit integer DEFAULT 200)
|
|
28412
|
+
RETURNS jsonb
|
|
28413
|
+
LANGUAGE plpgsql
|
|
28414
|
+
SECURITY DEFINER
|
|
28415
|
+
SET search_path TO 'public'
|
|
28416
|
+
AS $function$
|
|
28417
|
+
DECLARE
|
|
28418
|
+
r record;
|
|
28419
|
+
v_bron text;
|
|
28420
|
+
v_n int;
|
|
28421
|
+
v_sticker uuid;
|
|
28422
|
+
v_status text;
|
|
28423
|
+
v_reden text;
|
|
28424
|
+
v_bijgewerkt int := 0;
|
|
28425
|
+
v_vrij int := 0;
|
|
28426
|
+
v_uit int := 0;
|
|
28427
|
+
BEGIN
|
|
28428
|
+
FOR r IN
|
|
28429
|
+
SELECT o.id AS order_id, o.order_number, o.customer_id, oi.product_id,
|
|
28430
|
+
sum(public.logistics_own_sticker_count(oi.unit, oi.quantity, oi.plants_per_crate, prd.plants_per_crate))::int AS planten,
|
|
28431
|
+
bool_or(public.logistics_own_sticker_count(oi.unit, oi.quantity, oi.plants_per_crate, prd.plants_per_crate) IS NULL) AS onbekend
|
|
28432
|
+
FROM public.orders o
|
|
28433
|
+
JOIN public.order_items oi ON oi.order_id = o.id
|
|
28434
|
+
LEFT JOIN public.products prd ON prd.id = oi.product_id
|
|
28435
|
+
WHERE oi.needs_sticker IS TRUE
|
|
28436
|
+
AND oi.quarantined_at IS NULL
|
|
28437
|
+
AND oi.product_id IS NOT NULL
|
|
28438
|
+
AND coalesce(o.order_source, '') <> 'floriday'
|
|
28439
|
+
AND o.deleted_at IS NULL AND o.cancelled_at IS NULL
|
|
28440
|
+
AND coalesce(o.status, '') <> 'geannuleerd'
|
|
28441
|
+
AND o.delivery_date >= current_date - 1
|
|
28442
|
+
GROUP BY o.id, o.order_number, o.customer_id, oi.product_id
|
|
28443
|
+
LIMIT greatest(1, p_limit)
|
|
28444
|
+
LOOP
|
|
28445
|
+
v_bron := r.order_id::text || ':' || r.product_id::text;
|
|
28446
|
+
SELECT count(*), (array_agg(s.id))[1] INTO v_n, v_sticker
|
|
28447
|
+
FROM public.customer_product_stickers s
|
|
28448
|
+
JOIN public.customers c ON c.id = r.customer_id
|
|
28449
|
+
WHERE s.trade_item_key = r.product_id::text
|
|
28450
|
+
AND s.customer_key IN (c.id::text, 'tf:' || coalesce(c.twinfield_code, '-'), 'cn:' || coalesce(c.customer_number, '-'));
|
|
28451
|
+
v_status := 'wacht_op_moment'; v_reden := NULL;
|
|
28452
|
+
IF r.onbekend THEN
|
|
28453
|
+
v_status := 'geblokkeerd'; v_reden := 'Aantal stickers onbekend: regel in fust zonder planten per fust (niet op de regel en niet bij het product). Vul planten per fust in.';
|
|
28454
|
+
ELSIF coalesce(r.planten, 0) < 1 THEN
|
|
28455
|
+
v_status := 'geblokkeerd'; v_reden := 'Aantal planten is 0; geen sticker te printen.';
|
|
28456
|
+
ELSIF v_n = 0 THEN
|
|
28457
|
+
v_status := 'geblokkeerd'; v_reden := 'Geen eigen sticker gevonden voor deze klant en dit product. Voeg hem toe bij de klant.';
|
|
28458
|
+
ELSIF v_n > 1 THEN
|
|
28459
|
+
v_status := 'geblokkeerd'; v_reden := 'Meer dan één eigen sticker voor deze klant en dit product; er mag er maar één zijn.';
|
|
28460
|
+
END IF;
|
|
28461
|
+
|
|
28462
|
+
UPDATE public.logistics_sticker_prints
|
|
28463
|
+
SET kopieen = greatest(coalesce(r.planten, 0), 1),
|
|
28464
|
+
eigen_sticker_id = CASE WHEN v_n = 1 THEN v_sticker ELSE NULL END,
|
|
28465
|
+
status = CASE WHEN status = 'geblokkeerd' AND v_status = 'wacht_op_moment' THEN 'wacht_op_moment'
|
|
28466
|
+
WHEN status = 'niet_printen' THEN v_status
|
|
28467
|
+
WHEN status = 'wacht_op_moment' THEN v_status ELSE status END,
|
|
28468
|
+
reden = CASE WHEN status IN ('wacht_op_moment', 'geblokkeerd', 'niet_printen') THEN v_reden ELSE reden END,
|
|
28469
|
+
updated_at = now()
|
|
28470
|
+
WHERE soort = 'eigen_sticker' AND bron_id = v_bron
|
|
28471
|
+
AND status IN ('wacht_op_moment', 'geblokkeerd', 'niet_printen');
|
|
28472
|
+
IF NOT FOUND AND NOT EXISTS (SELECT 1 FROM public.logistics_sticker_prints WHERE soort = 'eigen_sticker' AND bron_id = v_bron) THEN
|
|
28473
|
+
INSERT INTO public.logistics_sticker_prints (soort, bron_id, order_id, order_number, kopieen, status, reden, eigen_sticker_id)
|
|
28474
|
+
VALUES ('eigen_sticker', v_bron, r.order_id, r.order_number, greatest(coalesce(r.planten, 0), 1), v_status, v_reden,
|
|
28475
|
+
CASE WHEN v_n = 1 THEN v_sticker ELSE NULL END);
|
|
28476
|
+
END IF;
|
|
28477
|
+
v_bijgewerkt := v_bijgewerkt + 1;
|
|
28478
|
+
END LOOP;
|
|
28479
|
+
|
|
28480
|
+
-- Vinkje uitgezet (of order vervallen) vóór het printen: niet printen.
|
|
28481
|
+
UPDATE public.logistics_sticker_prints p
|
|
28482
|
+
SET status = 'niet_printen', reden = 'Sticker uitgezet op de orderregel of order vervallen.', updated_at = now()
|
|
28483
|
+
WHERE p.soort = 'eigen_sticker' AND p.status IN ('wacht_op_moment', 'geblokkeerd', 'klaar')
|
|
28484
|
+
AND NOT EXISTS (
|
|
28485
|
+
SELECT 1 FROM public.order_items oi JOIN public.orders o ON o.id = oi.order_id
|
|
28486
|
+
WHERE oi.order_id = p.order_id AND p.bron_id = oi.order_id::text || ':' || oi.product_id::text
|
|
28487
|
+
AND oi.needs_sticker IS TRUE AND oi.quarantined_at IS NULL
|
|
28488
|
+
AND o.deleted_at IS NULL AND o.cancelled_at IS NULL AND coalesce(o.status, '') <> 'geannuleerd');
|
|
28489
|
+
GET DIAGNOSTICS v_uit = ROW_COUNT;
|
|
28490
|
+
|
|
28491
|
+
-- Vrijgeven met de pakbon: kar en printplek van de geprinte pakbonrij, formaat uit sticker of layout.
|
|
28492
|
+
WITH vrij AS (
|
|
28493
|
+
SELECT p.id,
|
|
28494
|
+
(SELECT public.logistics_try_uuid(q.payload->>'cartId')
|
|
28495
|
+
FROM public.pick_queue q
|
|
28496
|
+
WHERE q.cancelled_at IS NULL AND q.print_job_id IS NOT NULL
|
|
28497
|
+
AND (q.payload->>'orderId' = p.order_id::text OR q.payload->'orderIds' ? p.order_id::text)
|
|
28498
|
+
ORDER BY q.created_at LIMIT 1) AS kar,
|
|
28499
|
+
(SELECT k.print_plek_id::text
|
|
28500
|
+
FROM public.pick_queue q
|
|
28501
|
+
JOIN public.print_plek_koppelingen k ON k.bron IN ('pickstation', 'pick_station') AND k.bron_id = q.station_id::text
|
|
28502
|
+
WHERE q.cancelled_at IS NULL AND q.print_job_id IS NOT NULL
|
|
28503
|
+
AND (q.payload->>'orderId' = p.order_id::text OR q.payload->'orderIds' ? p.order_id::text)
|
|
28504
|
+
ORDER BY q.created_at, k.created_at LIMIT 1) AS plek,
|
|
28505
|
+
s.width_mm, s.height_mm,
|
|
28506
|
+
public.logistics_document_for_order(p.order_id, 'eigen_sticker') AS lay
|
|
28507
|
+
FROM public.logistics_sticker_prints p
|
|
28508
|
+
LEFT JOIN public.customer_product_stickers s ON s.id = p.eigen_sticker_id
|
|
28509
|
+
WHERE p.soort = 'eigen_sticker' AND p.status = 'wacht_op_moment'
|
|
28510
|
+
AND EXISTS (SELECT 1 FROM public.pick_queue q
|
|
28511
|
+
WHERE q.cancelled_at IS NULL AND q.print_job_id IS NOT NULL
|
|
28512
|
+
AND (q.payload->>'orderId' = p.order_id::text OR q.payload->'orderIds' ? p.order_id::text))
|
|
28513
|
+
)
|
|
28514
|
+
UPDATE public.logistics_sticker_prints p
|
|
28515
|
+
SET status = 'klaar', cart_id = vrij.kar, print_plek_id = vrij.plek,
|
|
28516
|
+
breedte_mm = coalesce(vrij.width_mm, (vrij.lay->>'breedte_mm')::numeric),
|
|
28517
|
+
hoogte_mm = coalesce(vrij.height_mm, (vrij.lay->>'hoogte_mm')::numeric),
|
|
28518
|
+
updated_at = now()
|
|
28519
|
+
FROM vrij
|
|
28520
|
+
WHERE p.id = vrij.id;
|
|
28521
|
+
GET DIAGNOSTICS v_vrij = ROW_COUNT;
|
|
28522
|
+
|
|
28523
|
+
RETURN jsonb_build_object('regels', v_bijgewerkt, 'vrijgegeven', v_vrij, 'niet_printen', v_uit);
|
|
28524
|
+
END;
|
|
28525
|
+
$function$;
|
|
28526
|
+
|
|
28527
|
+
-- 6. Pakbon van het pickstation: alleen de centrale beslisregel (geen layout uit payload of werkwijze).
|
|
28528
|
+
CREATE OR REPLACE FUNCTION public.pick_enqueue_print_job(_queue_item_id uuid, _printer_id uuid, _session_id text, _is_herprint boolean, _cart_id text)
|
|
28529
|
+
RETURNS uuid
|
|
28530
|
+
LANGUAGE plpgsql
|
|
28531
|
+
SECURITY DEFINER
|
|
28532
|
+
SET search_path TO 'public'
|
|
28533
|
+
AS $function$
|
|
28534
|
+
DECLARE
|
|
28535
|
+
item public.pick_queue;
|
|
28536
|
+
dt public.pick_document_types;
|
|
28537
|
+
doc_code text;
|
|
28538
|
+
target_printer uuid;
|
|
28539
|
+
target_layout uuid;
|
|
28540
|
+
target_plek uuid;
|
|
28541
|
+
layout_meta jsonb;
|
|
28542
|
+
layout_reden text;
|
|
28543
|
+
v_types public.doc_layout_type[];
|
|
28544
|
+
doc_type public.doc_layout_type := 'vrij';
|
|
28545
|
+
layout_type public.doc_layout_type;
|
|
28546
|
+
pdf_url text;
|
|
28547
|
+
pdf_b64 text;
|
|
28548
|
+
herkomst text;
|
|
28549
|
+
job_id uuid;
|
|
28550
|
+
cart_plan jsonb := NULL;
|
|
28551
|
+
selected_cart jsonb := NULL;
|
|
28552
|
+
v_cart_uuid uuid;
|
|
28553
|
+
v_barcode text;
|
|
28554
|
+
v_barcode_on boolean := public.logistics_pick_barcode_enabled();
|
|
28555
|
+
v_is_partial boolean := false;
|
|
28556
|
+
v_sleutel text;
|
|
28557
|
+
v_order uuid;
|
|
28558
|
+
BEGIN
|
|
28559
|
+
SELECT * INTO item FROM public.pick_queue WHERE id = _queue_item_id;
|
|
28560
|
+
IF NOT FOUND THEN RAISE EXCEPTION 'Dit document bestaat niet meer.'; END IF;
|
|
28561
|
+
|
|
28562
|
+
SELECT * INTO dt FROM public.pick_document_types WHERE id = item.document_type_id;
|
|
28563
|
+
|
|
28564
|
+
doc_code := lower(btrim(coalesce(
|
|
28565
|
+
nullif(item.payload->>'documentType', ''),
|
|
28566
|
+
nullif(dt.code, ''),
|
|
28567
|
+
''
|
|
28568
|
+
)));
|
|
28569
|
+
|
|
28570
|
+
v_types := public.logistics_document_type_map(doc_code);
|
|
28571
|
+
|
|
28572
|
+
IF _cart_id IS NOT NULL THEN
|
|
28573
|
+
cart_plan := public.pick_queue_cart_plan(_queue_item_id);
|
|
28574
|
+
SELECT c INTO selected_cart
|
|
28575
|
+
FROM jsonb_array_elements(COALESCE(cart_plan->'carts', '[]'::jsonb)) AS c
|
|
28576
|
+
WHERE c->>'cartId' = _cart_id
|
|
28577
|
+
LIMIT 1;
|
|
28578
|
+
|
|
28579
|
+
IF selected_cart IS NULL THEN
|
|
28580
|
+
RAISE EXCEPTION 'De gekozen kar bestaat niet meer in het actuele karplan.';
|
|
28581
|
+
END IF;
|
|
28582
|
+
|
|
28583
|
+
v_is_partial := NOT COALESCE((selected_cart->>'isFullCart')::boolean, false);
|
|
28584
|
+
|
|
28585
|
+
IF v_barcode_on THEN
|
|
28586
|
+
BEGIN
|
|
28587
|
+
v_cart_uuid := nullif(_cart_id, '')::uuid;
|
|
28588
|
+
EXCEPTION WHEN invalid_text_representation THEN
|
|
28589
|
+
v_cart_uuid := NULL;
|
|
28590
|
+
END;
|
|
28591
|
+
IF v_cart_uuid IS NOT NULL THEN
|
|
28592
|
+
v_barcode := public.logistics_ensure_cart_barcode(v_cart_uuid);
|
|
28593
|
+
selected_cart := selected_cart || jsonb_build_object('barcode', v_barcode);
|
|
28594
|
+
END IF;
|
|
28595
|
+
END IF;
|
|
28596
|
+
END IF;
|
|
28597
|
+
|
|
28598
|
+
-- 1.0.176: het document wordt automatisch bepaald uit de order.
|
|
28599
|
+
v_order := public.logistics_try_uuid(COALESCE(selected_cart->>'orderId', item.payload->>'orderId', item.payload->>'order_id'));
|
|
28600
|
+
IF doc_code <> '' AND v_order IS NOT NULL THEN
|
|
28601
|
+
layout_meta := public.logistics_document_for_order(v_order, doc_code);
|
|
28602
|
+
target_layout := public.logistics_try_uuid(layout_meta->>'layout_id');
|
|
28603
|
+
layout_reden := nullif(layout_meta->>'reden', '');
|
|
28604
|
+
ELSIF doc_code <> '' THEN
|
|
28605
|
+
layout_meta := public.logistics_document_layout_v2(doc_code, v_is_partial);
|
|
28606
|
+
target_layout := public.logistics_try_uuid(layout_meta->>'layout_id');
|
|
28607
|
+
END IF;
|
|
28608
|
+
|
|
28609
|
+
SELECT l.documenttype INTO layout_type
|
|
28610
|
+
FROM public.document_layouts l
|
|
28611
|
+
WHERE l.id = target_layout
|
|
28612
|
+
AND l.actief IS TRUE;
|
|
28613
|
+
|
|
28614
|
+
IF layout_type IS NULL THEN
|
|
28615
|
+
target_layout := NULL;
|
|
28616
|
+
END IF;
|
|
28617
|
+
|
|
28618
|
+
doc_type := COALESCE(layout_type, v_types[1], 'vrij');
|
|
28619
|
+
|
|
28620
|
+
IF item.station_id IS NOT NULL THEN
|
|
28621
|
+
SELECT k.print_plek_id INTO target_plek
|
|
28622
|
+
FROM public.print_plek_koppelingen k
|
|
28623
|
+
WHERE k.bron IN ('pickstation', 'pick_station')
|
|
28624
|
+
AND k.bron_id = item.station_id::text
|
|
28625
|
+
ORDER BY k.created_at
|
|
28626
|
+
LIMIT 1;
|
|
28627
|
+
END IF;
|
|
28628
|
+
|
|
28629
|
+
SELECT p.id INTO target_printer
|
|
28630
|
+
FROM public.printers p
|
|
28631
|
+
WHERE p.id = _printer_id
|
|
28632
|
+
AND p.actief
|
|
28633
|
+
AND nullif(p.extern_printer_id, '') IS NOT NULL;
|
|
28634
|
+
|
|
28635
|
+
pdf_url := nullif(item.payload->>'pdf_url', '');
|
|
28636
|
+
pdf_b64 := nullif(item.payload->>'pdf_base64', '');
|
|
28637
|
+
herkomst := nullif(item.payload->>'herkomst', '');
|
|
28638
|
+
|
|
28639
|
+
IF NOT COALESCE(_is_herprint, false) AND _cart_id IS NOT NULL THEN
|
|
28640
|
+
v_sleutel := 'pakbon:' || item.id::text || ':' || _cart_id || ':'
|
|
28641
|
+
|| coalesce(target_layout::text, '-') || ':' || coalesce(target_printer::text, '-');
|
|
28642
|
+
END IF;
|
|
28643
|
+
|
|
28644
|
+
INSERT INTO public.print_jobs(
|
|
28645
|
+
printer_id, layout_id, documenttype, documentnaam, status, foutmelding,
|
|
28646
|
+
payload, gebruiker_naam, pdf_url, pdf_base64, herkomst, is_herprint, idempotentie_sleutel
|
|
28647
|
+
)
|
|
28648
|
+
VALUES (
|
|
28649
|
+
target_printer,
|
|
28650
|
+
target_layout,
|
|
28651
|
+
doc_type,
|
|
28652
|
+
COALESCE(item.document_number, 'Pickdocument'),
|
|
28653
|
+
'wachtend',
|
|
28654
|
+
CASE
|
|
28655
|
+
WHEN target_layout IS NULL AND pdf_url IS NULL AND pdf_b64 IS NULL
|
|
28656
|
+
THEN COALESCE(layout_reden, 'Maak of activeer een ' || COALESCE(nullif(doc_code, ''), 'document') || 'layout in Layouts en printers.')
|
|
28657
|
+
ELSE NULL
|
|
28658
|
+
END,
|
|
28659
|
+
jsonb_build_object(
|
|
28660
|
+
'source', 'pickstation',
|
|
28661
|
+
'queue_item_id', item.id,
|
|
28662
|
+
'station_id', item.station_id,
|
|
28663
|
+
'print_plek_id', target_plek,
|
|
28664
|
+
'session_id', _session_id,
|
|
28665
|
+
'is_herprint', COALESCE(_is_herprint, false),
|
|
28666
|
+
'document_number', item.document_number,
|
|
28667
|
+
'document_type_code', COALESCE(nullif(doc_code, ''), dt.code),
|
|
28668
|
+
'report_key', dt.report_key,
|
|
28669
|
+
'print_template', dt.print_template,
|
|
28670
|
+
'order_number', COALESCE(selected_cart->>'orderNumber', item.order_number),
|
|
28671
|
+
'customer_name', item.customer_name,
|
|
28672
|
+
'reference', item.reference,
|
|
28673
|
+
'layout_id', target_layout,
|
|
28674
|
+
'layout_keuze', layout_meta->>'keuze',
|
|
28675
|
+
'layout_variant', CASE WHEN v_is_partial THEN 'partial_order' ELSE 'full_cart' END,
|
|
28676
|
+
'barcode', CASE WHEN v_barcode_on THEN COALESCE(v_barcode, item.barcode) ELSE item.barcode END,
|
|
28677
|
+
'country_code', item.country_code,
|
|
28678
|
+
'cart_id', _cart_id,
|
|
28679
|
+
'cart', selected_cart,
|
|
28680
|
+
'data', COALESCE(item.payload, '{}'::jsonb) || jsonb_build_object(
|
|
28681
|
+
'print_plek_id', target_plek,
|
|
28682
|
+
'cart_id', _cart_id,
|
|
28683
|
+
'cart', selected_cart,
|
|
28684
|
+
'orderId', COALESCE(selected_cart->>'orderId', item.payload->>'orderId'),
|
|
28685
|
+
'orderNumber', COALESCE(selected_cart->>'orderNumber', item.order_number)
|
|
28686
|
+
)
|
|
28687
|
+
),
|
|
28688
|
+
'Pickstation',
|
|
28689
|
+
pdf_url,
|
|
28690
|
+
pdf_b64,
|
|
28691
|
+
herkomst,
|
|
28692
|
+
COALESCE(_is_herprint, false),
|
|
28693
|
+
v_sleutel
|
|
28694
|
+
)
|
|
28695
|
+
RETURNING id INTO job_id;
|
|
28696
|
+
|
|
28697
|
+
PERFORM public.logistics_enqueue_sticker_with_slip(_queue_item_id, _printer_id, _session_id, COALESCE(_is_herprint,false), _cart_id, job_id);
|
|
28698
|
+
UPDATE public.pick_queue SET print_job_id = job_id WHERE id = _queue_item_id;
|
|
28699
|
+
|
|
28700
|
+
RETURN job_id;
|
|
28701
|
+
END;
|
|
28702
|
+
$function$;
|
|
28703
|
+
|
|
28704
|
+
REVOKE EXECUTE ON FUNCTION public.logistics_own_sticker_sync(integer) FROM PUBLIC, anon, authenticated;
|
|
28705
|
+
GRANT EXECUTE ON FUNCTION public.logistics_own_sticker_sync(integer) TO service_role;
|
|
28706
|
+
REVOKE EXECUTE ON FUNCTION public.logistics_document_for_order(uuid, text) FROM PUBLIC, anon;
|
|
28707
|
+
GRANT EXECUTE ON FUNCTION public.logistics_document_for_order(uuid, text) TO authenticated, service_role;
|
|
28708
|
+
REVOKE EXECUTE ON FUNCTION public.logistics_document_selection_status() FROM PUBLIC, anon;
|
|
28709
|
+
GRANT EXECUTE ON FUNCTION public.logistics_document_selection_status() TO authenticated, service_role;
|
|
28710
|
+
|
|
28711
|
+
-- Veiligheid: draaien met de rechten van de aanroeper.
|
|
28712
|
+
ALTER FUNCTION public.logistics_document_selection_status() SECURITY INVOKER;
|
|
28713
|
+
ALTER FUNCTION public.logistics_document_for_order(uuid, text) SECURITY INVOKER;
|
|
28714
|
+
|
|
28715
|
+
-- ===== 1.0.176 reserveringen FO + pakbon centrale keuze =====
|
|
28716
|
+
-- 1.0.176: reserveringen (Voorraad 1.0.93) en pakbon via centrale documentkeuze (Pickschermen 1.0.56).
|
|
28717
|
+
CREATE OR REPLACE FUNCTION public.logistics_recompute_reserved_targeted(p_product_id uuid)
|
|
28718
|
+
RETURNS jsonb
|
|
28719
|
+
LANGUAGE plpgsql
|
|
28720
|
+
SECURITY DEFINER
|
|
28721
|
+
SET search_path TO 'public'
|
|
28722
|
+
AS $function$
|
|
28723
|
+
DECLARE
|
|
28724
|
+
v_t0 timestamptz := clock_timestamp();
|
|
28725
|
+
v_max_lines constant integer := 500;
|
|
28726
|
+
v_max_keys constant integer := 200;
|
|
28727
|
+
v_trace_ms constant numeric := 500;
|
|
28728
|
+
v_nkeys integer; v_nkeys_prev integer := -1; v_nlines integer := 0; v_changed integer := 0; v_ms numeric;
|
|
28729
|
+
oi_rec record; part record; member_rec record;
|
|
28730
|
+
v_key text; v_last_key text; v_remaining numeric; v_available numeric; v_take numeric; v_err text;
|
|
28731
|
+
v_skipped jsonb := '[]'::jsonb; v_skipped_qty numeric := 0;
|
|
28732
|
+
v_struct jsonb := '[]'::jsonb; v_struct_qty numeric := 0;
|
|
28733
|
+
v_freeze boolean := public.logistics_plan_setting('verdeling_bevriezen_actief', 0) = 1;
|
|
28734
|
+
v_frozen_ids uuid[]; v_line_ids uuid[];
|
|
28735
|
+
BEGIN
|
|
28736
|
+
IF p_product_id IS NULL THEN RETURN jsonb_build_object('status', 'geen_product'); END IF;
|
|
28737
|
+
IF current_setting('app.recomputing_reserved', true) = 'on' THEN RETURN jsonb_build_object('status', 'al_bezig'); END IF;
|
|
28738
|
+
PERFORM set_config('app.recomputing_reserved', 'on', true);
|
|
28739
|
+
|
|
28740
|
+
DROP TABLE IF EXISTS _rt_open;
|
|
28741
|
+
DROP TABLE IF EXISTS _rt_pexp;
|
|
28742
|
+
DROP TABLE IF EXISTS _rt_gm;
|
|
28743
|
+
DROP TABLE IF EXISTS _rt_raw;
|
|
28744
|
+
DROP TABLE IF EXISTS _rt_pkeys;
|
|
28745
|
+
DROP TABLE IF EXISTS _rt_keys;
|
|
28746
|
+
DROP TABLE IF EXISTS _rt_lines;
|
|
28747
|
+
DROP TABLE IF EXISTS _rt_demand;
|
|
28748
|
+
DROP TABLE IF EXISTS _rt_alloc;
|
|
28749
|
+
DROP TABLE IF EXISTS _rt_frozen;
|
|
28750
|
+
CREATE TEMP TABLE _rt_open (order_item_id uuid PRIMARY KEY, product_id uuid, qty numeric, created_at timestamptz, order_id uuid) ON COMMIT DROP;
|
|
28751
|
+
CREATE TEMP TABLE _rt_pexp (product_id uuid, ord bigint, kind text, ref text, qty numeric, note text) ON COMMIT DROP;
|
|
28752
|
+
CREATE TEMP TABLE _rt_gm (group_id uuid, raw_key text, canon_key text, ord bigint) ON COMMIT DROP;
|
|
28753
|
+
CREATE TEMP TABLE _rt_raw (raw_key text PRIMARY KEY, canon_key text) ON COMMIT DROP;
|
|
28754
|
+
CREATE TEMP TABLE _rt_pkeys (product_id uuid, canon_key text) ON COMMIT DROP;
|
|
28755
|
+
CREATE TEMP TABLE _rt_keys (canon_key text PRIMARY KEY) ON COMMIT DROP;
|
|
28756
|
+
CREATE TEMP TABLE _rt_lines (order_item_id uuid PRIMARY KEY) ON COMMIT DROP;
|
|
28757
|
+
CREATE TEMP TABLE _rt_demand (trade_item_key text PRIMARY KEY, qty numeric NOT NULL DEFAULT 0) ON COMMIT DROP;
|
|
28758
|
+
CREATE TEMP TABLE _rt_alloc (order_item_id uuid, trade_item_key text, qty numeric, source text, group_id uuid) ON COMMIT DROP;
|
|
28759
|
+
CREATE TEMP TABLE _rt_frozen (order_item_id uuid PRIMARY KEY) ON COMMIT DROP;
|
|
28760
|
+
|
|
28761
|
+
INSERT INTO _rt_open
|
|
28762
|
+
SELECT oi.id, oi.product_id, COALESCE(oi.quantity, 0)::numeric, o.created_at, oi.order_id
|
|
28763
|
+
FROM logistics_active.order_items oi
|
|
28764
|
+
JOIN public.orders o ON o.id = oi.order_id
|
|
28765
|
+
WHERE o.status = 'Nog te picken' AND NOT public.logistics_reserved_order_excluded(o.id)
|
|
28766
|
+
AND COALESCE(oi.quantity, 0) > 0
|
|
28767
|
+
AND oi.product_id IS NOT NULL
|
|
28768
|
+
AND NOT EXISTS (SELECT 1 FROM public.stock_mutation_log sml WHERE sml.order_item_id = oi.id AND sml.mutation_type = 'consumption');
|
|
28769
|
+
-- Groepsregel naast eigen ledenregels: nooit reserveren.
|
|
28770
|
+
DELETE FROM _rt_open o WHERE o.order_item_id IN (SELECT d.order_item_id FROM public.logistics_double_group_lines(NULL) d);
|
|
28771
|
+
|
|
28772
|
+
INSERT INTO _rt_pexp (product_id, ord, kind, ref, qty, note)
|
|
28773
|
+
SELECT d.pid, e.ord, e.kind, e.ref, e.qty, e.note
|
|
28774
|
+
FROM (SELECT DISTINCT product_id AS pid FROM _rt_open UNION SELECT p_product_id) d,
|
|
28775
|
+
LATERAL public.logistics_expand_line(d.pid, 1) WITH ORDINALITY AS e(kind, ref, qty, note, ord);
|
|
28776
|
+
|
|
28777
|
+
INSERT INTO _rt_gm (group_id, raw_key, ord)
|
|
28778
|
+
SELECT g.gid, m.raw_key, m.ord
|
|
28779
|
+
FROM (SELECT DISTINCT ref::uuid AS gid FROM _rt_pexp WHERE kind = 'group') g,
|
|
28780
|
+
LATERAL (
|
|
28781
|
+
SELECT public.resolve_group_member_stock_key(pgi.trade_item_id) AS raw_key,
|
|
28782
|
+
row_number() OVER (ORDER BY pgi.sort_order ASC NULLS LAST, pgi.created_at ASC, pgi.id ASC) AS ord
|
|
28783
|
+
FROM public.product_group_items pgi
|
|
28784
|
+
WHERE pgi.product_group_id = g.gid) m
|
|
28785
|
+
WHERE m.raw_key IS NOT NULL
|
|
28786
|
+
AND m.raw_key NOT LIKE 'group:%';
|
|
28787
|
+
|
|
28788
|
+
INSERT INTO _rt_raw (raw_key, canon_key)
|
|
28789
|
+
SELECT x.k, public.logistics_reserved_key(x.k)
|
|
28790
|
+
FROM (SELECT ref AS k FROM _rt_pexp WHERE kind = 'item' UNION SELECT raw_key FROM _rt_gm) x;
|
|
28791
|
+
UPDATE _rt_gm g SET canon_key = r.canon_key FROM _rt_raw r WHERE r.raw_key = g.raw_key;
|
|
28792
|
+
|
|
28793
|
+
INSERT INTO _rt_pkeys (product_id, canon_key)
|
|
28794
|
+
SELECT DISTINCT e.product_id, r.canon_key
|
|
28795
|
+
FROM _rt_pexp e JOIN _rt_raw r ON r.raw_key = e.ref
|
|
28796
|
+
WHERE e.kind = 'item' AND r.canon_key IS NOT NULL
|
|
28797
|
+
UNION
|
|
28798
|
+
SELECT DISTINCT e.product_id, g.canon_key
|
|
28799
|
+
FROM _rt_pexp e JOIN _rt_gm g ON g.group_id = e.ref::uuid
|
|
28800
|
+
WHERE e.kind = 'group' AND g.canon_key IS NOT NULL;
|
|
28801
|
+
|
|
28802
|
+
INSERT INTO _rt_keys SELECT DISTINCT canon_key FROM _rt_pkeys WHERE product_id = p_product_id ON CONFLICT DO NOTHING;
|
|
28803
|
+
LOOP
|
|
28804
|
+
SELECT count(*) INTO v_nkeys FROM _rt_keys;
|
|
28805
|
+
EXIT WHEN v_nkeys = v_nkeys_prev;
|
|
28806
|
+
v_nkeys_prev := v_nkeys;
|
|
28807
|
+
INSERT INTO _rt_lines
|
|
28808
|
+
SELECT o.order_item_id FROM _rt_open o
|
|
28809
|
+
WHERE EXISTS (SELECT 1 FROM _rt_pkeys pk JOIN _rt_keys k ON k.canon_key = pk.canon_key
|
|
28810
|
+
WHERE pk.product_id = o.product_id)
|
|
28811
|
+
ON CONFLICT DO NOTHING;
|
|
28812
|
+
INSERT INTO _rt_keys
|
|
28813
|
+
SELECT DISTINCT pk.canon_key FROM _rt_pkeys pk
|
|
28814
|
+
JOIN _rt_open o ON o.product_id = pk.product_id
|
|
28815
|
+
JOIN _rt_lines l ON l.order_item_id = o.order_item_id
|
|
28816
|
+
ON CONFLICT DO NOTHING;
|
|
28817
|
+
SELECT count(*) INTO v_nlines FROM _rt_lines;
|
|
28818
|
+
IF v_nlines > v_max_lines OR (SELECT count(*) FROM _rt_keys) > v_max_keys THEN
|
|
28819
|
+
PERFORM set_config('app.recomputing_reserved', 'off', true);
|
|
28820
|
+
PERFORM public.recompute_all_reserved_stock();
|
|
28821
|
+
v_ms := round(extract(epoch FROM clock_timestamp() - v_t0) * 1000, 1);
|
|
28822
|
+
PERFORM public.logistics_trace(jsonb_build_object(
|
|
28823
|
+
'phase', 'reservering', 'step', 'reservering herberekenen', 'status', 'waarschuwing',
|
|
28824
|
+
'actor', 'logistics_recompute_reserved_targeted', 'errorClass', 'omvang',
|
|
28825
|
+
'reason', 'Gerichte herberekening te groot; volledige herberekening uitgevoerd.',
|
|
28826
|
+
'values', jsonb_build_object('product_id', p_product_id, 'regels', v_nlines,
|
|
28827
|
+
'sleutels', (SELECT count(*) FROM _rt_keys), 'duur_ms', v_ms)));
|
|
28828
|
+
RETURN jsonb_build_object('status', 'volledig', 'regels', v_nlines, 'duur_ms', v_ms);
|
|
28829
|
+
END IF;
|
|
28830
|
+
END LOOP;
|
|
28831
|
+
|
|
28832
|
+
-- Bevroren regels eerst, naar rato van het huidige aantal.
|
|
28833
|
+
IF v_freeze THEN
|
|
28834
|
+
INSERT INTO _rt_frozen
|
|
28835
|
+
SELECT o.order_item_id FROM _rt_open o JOIN _rt_lines l ON l.order_item_id = o.order_item_id
|
|
28836
|
+
WHERE EXISTS (SELECT 1 FROM public.logistics_reservation_allocations a WHERE a.order_item_id = o.order_item_id AND a.source <> 'error')
|
|
28837
|
+
AND public.logistics_allocation_frozen(o.order_id)
|
|
28838
|
+
ON CONFLICT DO NOTHING;
|
|
28839
|
+
INSERT INTO _rt_alloc
|
|
28840
|
+
SELECT f.order_item_id, s.trade_item_key, s.qty, s.source, s.group_id
|
|
28841
|
+
FROM _rt_frozen f
|
|
28842
|
+
JOIN _rt_open o ON o.order_item_id = f.order_item_id
|
|
28843
|
+
CROSS JOIN LATERAL public.logistics_frozen_allocation_scaled(f.order_item_id, o.qty) s;
|
|
28844
|
+
INSERT INTO _rt_demand AS d
|
|
28845
|
+
SELECT trade_item_key, SUM(qty) FROM _rt_alloc GROUP BY trade_item_key
|
|
28846
|
+
ON CONFLICT (trade_item_key) DO UPDATE SET qty = d.qty + EXCLUDED.qty;
|
|
28847
|
+
INSERT INTO _rt_keys SELECT DISTINCT trade_item_key FROM _rt_alloc ON CONFLICT DO NOTHING;
|
|
28848
|
+
END IF;
|
|
28849
|
+
|
|
28850
|
+
FOR oi_rec IN
|
|
28851
|
+
SELECT o.order_item_id AS id, o.product_id, o.qty
|
|
28852
|
+
FROM _rt_open o JOIN _rt_lines l ON l.order_item_id = o.order_item_id
|
|
28853
|
+
WHERE NOT EXISTS (SELECT 1 FROM _rt_frozen f WHERE f.order_item_id = o.order_item_id)
|
|
28854
|
+
ORDER BY o.created_at, o.order_item_id
|
|
28855
|
+
LOOP
|
|
28856
|
+
SELECT string_agg(e.note, '; ') INTO v_err FROM _rt_pexp e WHERE e.product_id = oi_rec.product_id AND e.kind = 'error';
|
|
28857
|
+
IF v_err IS NOT NULL THEN
|
|
28858
|
+
v_struct := v_struct || jsonb_build_object('order_item_id', oi_rec.id, 'product_id', oi_rec.product_id, 'reden', v_err);
|
|
28859
|
+
v_struct_qty := v_struct_qty + oi_rec.qty;
|
|
28860
|
+
CONTINUE;
|
|
28861
|
+
END IF;
|
|
28862
|
+
|
|
28863
|
+
FOR part IN
|
|
28864
|
+
SELECT e.kind, e.ref, e.qty * oi_rec.qty AS qty
|
|
28865
|
+
FROM _rt_pexp e WHERE e.product_id = oi_rec.product_id ORDER BY e.ord
|
|
28866
|
+
LOOP
|
|
28867
|
+
IF part.kind = 'item' THEN
|
|
28868
|
+
SELECT canon_key INTO v_key FROM _rt_raw WHERE raw_key = part.ref;
|
|
28869
|
+
IF v_key IS NULL THEN
|
|
28870
|
+
v_skipped := v_skipped || to_jsonb(part.ref);
|
|
28871
|
+
v_skipped_qty := v_skipped_qty + part.qty;
|
|
28872
|
+
ELSE
|
|
28873
|
+
INSERT INTO _rt_demand AS d VALUES (v_key, part.qty)
|
|
28874
|
+
ON CONFLICT (trade_item_key) DO UPDATE SET qty = d.qty + EXCLUDED.qty;
|
|
28875
|
+
INSERT INTO _rt_alloc VALUES (oi_rec.id, v_key, part.qty, 'item', NULL);
|
|
28876
|
+
END IF;
|
|
28877
|
+
ELSE
|
|
28878
|
+
v_remaining := part.qty;
|
|
28879
|
+
v_last_key := NULL;
|
|
28880
|
+
FOR member_rec IN
|
|
28881
|
+
SELECT g.canon_key FROM _rt_gm g WHERE g.group_id = part.ref::uuid ORDER BY g.ord
|
|
28882
|
+
LOOP
|
|
28883
|
+
v_key := member_rec.canon_key;
|
|
28884
|
+
IF v_key IS NULL THEN CONTINUE; END IF;
|
|
28885
|
+
v_last_key := v_key;
|
|
28886
|
+
IF v_remaining <= 0 THEN CONTINUE; END IF;
|
|
28887
|
+
|
|
28888
|
+
SELECT GREATEST(COALESCE(MAX(s.physical_stock), 0)
|
|
28889
|
+
- COALESCE((SELECT d.qty FROM _rt_demand d WHERE d.trade_item_key = v_key), 0), 0)
|
|
28890
|
+
INTO v_available
|
|
28891
|
+
FROM public.trade_item_stock s
|
|
28892
|
+
WHERE s.trade_item_key = v_key;
|
|
28893
|
+
|
|
28894
|
+
IF COALESCE(v_available, 0) <= 0 THEN CONTINUE; END IF;
|
|
28895
|
+
v_take := LEAST(v_available, v_remaining);
|
|
28896
|
+
INSERT INTO _rt_demand AS d VALUES (v_key, v_take)
|
|
28897
|
+
ON CONFLICT (trade_item_key) DO UPDATE SET qty = d.qty + EXCLUDED.qty;
|
|
28898
|
+
INSERT INTO _rt_alloc VALUES (oi_rec.id, v_key, v_take, 'group', part.ref::uuid);
|
|
28899
|
+
v_remaining := v_remaining - v_take;
|
|
28900
|
+
END LOOP;
|
|
28901
|
+
|
|
28902
|
+
IF v_remaining > 0 THEN
|
|
28903
|
+
IF v_last_key IS NULL THEN
|
|
28904
|
+
v_skipped := v_skipped || to_jsonb('group:' || part.ref);
|
|
28905
|
+
v_skipped_qty := v_skipped_qty + v_remaining;
|
|
28906
|
+
ELSE
|
|
28907
|
+
INSERT INTO _rt_demand AS d VALUES (v_last_key, v_remaining)
|
|
28908
|
+
ON CONFLICT (trade_item_key) DO UPDATE SET qty = d.qty + EXCLUDED.qty;
|
|
28909
|
+
INSERT INTO _rt_alloc VALUES (oi_rec.id, v_last_key, v_remaining, 'group', part.ref::uuid);
|
|
28910
|
+
END IF;
|
|
28911
|
+
END IF;
|
|
28912
|
+
END IF;
|
|
28913
|
+
END LOOP;
|
|
28914
|
+
END LOOP;
|
|
28915
|
+
|
|
28916
|
+
DELETE FROM public.logistics_reservation_allocations a
|
|
28917
|
+
WHERE a.order_item_id IN (SELECT l.order_item_id FROM _rt_lines l);
|
|
28918
|
+
INSERT INTO public.logistics_reservation_allocations (order_item_id, trade_item_key, qty, source, group_id, line_qty)
|
|
28919
|
+
SELECT r.order_item_id, r.trade_item_key, SUM(r.qty), r.source, r.group_id, MAX(o.qty)
|
|
28920
|
+
FROM _rt_alloc r
|
|
28921
|
+
LEFT JOIN _rt_open o ON o.order_item_id = r.order_item_id
|
|
28922
|
+
WHERE r.qty > 0
|
|
28923
|
+
GROUP BY r.order_item_id, r.trade_item_key, r.source, r.group_id;
|
|
28924
|
+
|
|
28925
|
+
-- 1.0.176 (Voorraad 1.0.93): Floriday-orders op Floriday-leidende sleutels tellen niet mee
|
|
28926
|
+
-- in reserved_stock; de toewijzingen zelf blijven bestaan. Oudere Voorraad: gedrag zoals nu + melding.
|
|
28927
|
+
IF to_regprocedure('public.voorraad_floriday_leads_key(text)') IS NOT NULL THEN
|
|
28928
|
+
UPDATE _rt_demand d
|
|
28929
|
+
SET qty = COALESCE((
|
|
28930
|
+
SELECT SUM(r.qty)
|
|
28931
|
+
FROM _rt_alloc r
|
|
28932
|
+
JOIN _rt_open op ON op.order_item_id = r.order_item_id
|
|
28933
|
+
JOIN public.orders ord ON ord.id = op.order_id
|
|
28934
|
+
WHERE r.trade_item_key = d.trade_item_key AND r.qty > 0
|
|
28935
|
+
AND NOT (public.normalize_order_source(ord.order_source) = 'FO'
|
|
28936
|
+
AND COALESCE(public.voorraad_floriday_leads_key(d.trade_item_key), false))), 0);
|
|
28937
|
+
ELSE
|
|
28938
|
+
PERFORM public.logistics_trace(jsonb_build_object(
|
|
28939
|
+
'phase', 'reservering', 'step', 'reservering herberekenen', 'status', 'waarschuwing',
|
|
28940
|
+
'actor', 'logistics_recompute_reserved_targeted', 'errorClass', 'afhankelijkheid',
|
|
28941
|
+
'reason', 'voorraad_floriday_leads_key ontbreekt (oudere Voorraad); Floriday-orders tellen nog mee in de reservering.',
|
|
28942
|
+
'values', jsonb_build_object('product_id', p_product_id)));
|
|
28943
|
+
END IF;
|
|
28944
|
+
|
|
28945
|
+
PERFORM set_config('stock.change_source', 'RESERVATION_RECOMPUTE', true);
|
|
28946
|
+
UPDATE public.trade_item_stock s
|
|
28947
|
+
SET reserved_stock = CEIL(COALESCE(d.qty, 0))::integer,
|
|
28948
|
+
change_source = 'RESERVATION_RECOMPUTE',
|
|
28949
|
+
updated_at = now()
|
|
28950
|
+
FROM _rt_keys k
|
|
28951
|
+
LEFT JOIN _rt_demand d ON d.trade_item_key = k.canon_key
|
|
28952
|
+
WHERE s.trade_item_key = k.canon_key
|
|
28953
|
+
AND s.reserved_stock IS DISTINCT FROM CEIL(COALESCE(d.qty, 0))::integer;
|
|
28954
|
+
GET DIAGNOSTICS v_changed = ROW_COUNT;
|
|
28955
|
+
|
|
28956
|
+
v_ms := round(extract(epoch FROM clock_timestamp() - v_t0) * 1000, 1);
|
|
28957
|
+
|
|
28958
|
+
IF jsonb_array_length(v_skipped) > 0 THEN
|
|
28959
|
+
PERFORM public.logistics_trace(jsonb_build_object(
|
|
28960
|
+
'phase', 'reservering', 'step', 'reservering herberekenen', 'status', 'waarschuwing',
|
|
28961
|
+
'actor', 'logistics_recompute_reserved_targeted', 'errorClass', 'ontbrekende_gegevens',
|
|
28962
|
+
'reason', 'Geen voorraadrij en geen actieve Floriday-koppeling om die aan te maken; reservering voor deze artikelen niet berekend.',
|
|
28963
|
+
'values', jsonb_build_object('product_id', p_product_id,
|
|
28964
|
+
'sleutels', (SELECT jsonb_agg(DISTINCT x) FROM jsonb_array_elements_text(v_skipped) x),
|
|
28965
|
+
'gemiste_vraag_stuks', v_skipped_qty)));
|
|
28966
|
+
END IF;
|
|
28967
|
+
|
|
28968
|
+
IF jsonb_array_length(v_struct) > 0 THEN
|
|
28969
|
+
PERFORM public.logistics_trace(jsonb_build_object(
|
|
28970
|
+
'phase', 'reservering', 'step', 'reservering herberekenen', 'status', 'waarschuwing',
|
|
28971
|
+
'actor', 'logistics_recompute_reserved_targeted', 'errorClass', 'structuur',
|
|
28972
|
+
'reason', 'Samenstelling met een lus of te diepe nesting; voor deze bestelregels is niets gereserveerd.',
|
|
28973
|
+
'values', jsonb_build_object('regels', v_struct, 'gemiste_vraag_stuks', v_struct_qty)));
|
|
28974
|
+
END IF;
|
|
28975
|
+
|
|
28976
|
+
IF v_ms > v_trace_ms THEN
|
|
28977
|
+
PERFORM public.logistics_trace(jsonb_build_object(
|
|
28978
|
+
'phase', 'reservering', 'step', 'reservering herberekenen', 'status', 'waarschuwing',
|
|
28979
|
+
'actor', 'logistics_recompute_reserved_targeted', 'errorClass', 'traag',
|
|
28980
|
+
'reason', 'Gerichte herberekening duurde langer dan verwacht.',
|
|
28981
|
+
'values', jsonb_build_object('product_id', p_product_id, 'regels', v_nlines,
|
|
28982
|
+
'sleutels', (SELECT count(*) FROM _rt_keys), 'duur_ms', v_ms)));
|
|
28983
|
+
END IF;
|
|
28984
|
+
|
|
28985
|
+
IF v_freeze THEN
|
|
28986
|
+
SELECT array_agg(order_item_id) INTO v_frozen_ids FROM _rt_frozen;
|
|
28987
|
+
SELECT array_agg(order_item_id) INTO v_line_ids FROM _rt_lines;
|
|
28988
|
+
PERFORM public.logistics_report_frozen_shortage(v_frozen_ids);
|
|
28989
|
+
PERFORM public.logistics_allocation_check_changes(v_line_ids);
|
|
28990
|
+
END IF;
|
|
28991
|
+
|
|
28992
|
+
PERFORM set_config('app.recomputing_reserved', 'off', true);
|
|
28993
|
+
RETURN jsonb_build_object('status', 'gericht', 'regels', v_nlines,
|
|
28994
|
+
'sleutels', (SELECT count(*) FROM _rt_keys), 'gewijzigd', v_changed, 'duur_ms', v_ms);
|
|
28995
|
+
END
|
|
28996
|
+
$function$;
|
|
28997
|
+
|
|
28998
|
+
CREATE OR REPLACE FUNCTION public.logistics_resolve_pick_document(_queue_item_id uuid, _voorbeeld boolean, _session_id text, _is_herprint boolean)
|
|
28999
|
+
RETURNS jsonb
|
|
29000
|
+
LANGUAGE plpgsql
|
|
29001
|
+
STABLE SECURITY DEFINER
|
|
29002
|
+
SET search_path TO 'public'
|
|
29003
|
+
AS $function$
|
|
29004
|
+
DECLARE
|
|
29005
|
+
item public.pick_queue;
|
|
29006
|
+
dt public.pick_document_types;
|
|
29007
|
+
doc_code text;
|
|
29008
|
+
target_layout uuid;
|
|
29009
|
+
target_plek uuid;
|
|
29010
|
+
layout_meta jsonb;
|
|
29011
|
+
v_types public.doc_layout_type[];
|
|
29012
|
+
doc_type public.doc_layout_type := 'vrij';
|
|
29013
|
+
layout_type public.doc_layout_type;
|
|
29014
|
+
pdf_url text;
|
|
29015
|
+
pdf_b64 text;
|
|
29016
|
+
herkomst text;
|
|
29017
|
+
v_variant text;
|
|
29018
|
+
v_is_partial boolean := false;
|
|
29019
|
+
v_cart_id uuid;
|
|
29020
|
+
v_cart jsonb;
|
|
29021
|
+
v_order_id uuid;
|
|
29022
|
+
v_barcode text;
|
|
29023
|
+
v_barcode_on boolean := public.logistics_pick_barcode_enabled();
|
|
29024
|
+
v_ok boolean := true;
|
|
29025
|
+
v_reden text;
|
|
29026
|
+
BEGIN
|
|
29027
|
+
SELECT * INTO item FROM public.pick_queue WHERE id = _queue_item_id;
|
|
29028
|
+
IF NOT FOUND THEN
|
|
29029
|
+
RAISE EXCEPTION 'Dit document bestaat niet meer.' USING ERRCODE = 'P0002';
|
|
29030
|
+
END IF;
|
|
29031
|
+
|
|
29032
|
+
SELECT * INTO dt FROM public.pick_document_types WHERE id = item.document_type_id;
|
|
29033
|
+
|
|
29034
|
+
doc_code := lower(btrim(coalesce(
|
|
29035
|
+
nullif(item.payload->>'documentType', ''),
|
|
29036
|
+
nullif(dt.code, ''),
|
|
29037
|
+
''
|
|
29038
|
+
)));
|
|
29039
|
+
|
|
29040
|
+
v_types := public.logistics_document_type_map(doc_code);
|
|
29041
|
+
|
|
29042
|
+
BEGIN
|
|
29043
|
+
v_cart_id := nullif(coalesce(
|
|
29044
|
+
item.payload->>'cartId', item.payload->>'cart_id',
|
|
29045
|
+
item.payload->'data'->>'cartId', item.payload->'data'->>'cart_id'
|
|
29046
|
+
), '')::uuid;
|
|
29047
|
+
EXCEPTION WHEN invalid_text_representation THEN
|
|
29048
|
+
v_cart_id := NULL;
|
|
29049
|
+
END;
|
|
29050
|
+
|
|
29051
|
+
IF v_cart_id IS NOT NULL THEN
|
|
29052
|
+
SELECT COALESCE(c.order_id, (
|
|
29053
|
+
SELECT oi.order_id FROM logistics_active.order_cart_items ci
|
|
29054
|
+
JOIN logistics_active.order_items oi ON oi.id = ci.order_item_id
|
|
29055
|
+
WHERE ci.cart_id = c.id LIMIT 1))
|
|
29056
|
+
INTO v_order_id
|
|
29057
|
+
FROM logistics_active.order_carts c WHERE c.id = v_cart_id;
|
|
29058
|
+
|
|
29059
|
+
IF v_order_id IS NOT NULL THEN
|
|
29060
|
+
SELECT c INTO v_cart
|
|
29061
|
+
FROM jsonb_array_elements(public.logistics_cart_slip_plan(v_order_id)->'carts') AS c
|
|
29062
|
+
WHERE (c->>'cartId')::uuid = v_cart_id;
|
|
29063
|
+
END IF;
|
|
29064
|
+
|
|
29065
|
+
IF v_barcode_on THEN
|
|
29066
|
+
v_barcode := COALESCE(
|
|
29067
|
+
(SELECT b.barcode FROM public.logistics_cart_barcode b WHERE b.cart_id = v_cart_id),
|
|
29068
|
+
public.logistics_cart_barcode_value(v_cart_id)
|
|
29069
|
+
);
|
|
29070
|
+
IF v_cart IS NOT NULL THEN
|
|
29071
|
+
v_cart := v_cart || jsonb_build_object('barcode', v_barcode);
|
|
29072
|
+
END IF;
|
|
29073
|
+
END IF;
|
|
29074
|
+
END IF;
|
|
29075
|
+
|
|
29076
|
+
IF v_cart IS NOT NULL THEN
|
|
29077
|
+
v_is_partial := NOT COALESCE((v_cart->>'isFullCart')::boolean, false);
|
|
29078
|
+
ELSE
|
|
29079
|
+
v_variant := nullif(coalesce(
|
|
29080
|
+
item.payload->>'slipVariant',
|
|
29081
|
+
item.payload->'data'->>'slipVariant'
|
|
29082
|
+
), '');
|
|
29083
|
+
IF v_variant IS NOT NULL THEN
|
|
29084
|
+
v_is_partial := (v_variant = 'partial_order');
|
|
29085
|
+
ELSIF nullif(coalesce(item.payload->>'pickUnit', item.payload->'data'->>'pickUnit'), '') IS NOT NULL THEN
|
|
29086
|
+
v_is_partial := (coalesce(item.payload->>'pickUnit', item.payload->'data'->>'pickUnit') = 'order');
|
|
29087
|
+
ELSE
|
|
29088
|
+
v_is_partial := (item.cart_count IS NOT NULL AND item.cart_count <= 1);
|
|
29089
|
+
END IF;
|
|
29090
|
+
END IF;
|
|
29091
|
+
|
|
29092
|
+
-- 1.0.176 (Pickschermen 1.0.56): layout alleen via de centrale documentkeuze; payload.layout_id wordt genegeerd.
|
|
29093
|
+
v_order_id := COALESCE(v_order_id, public.logistics_try_uuid(COALESCE(
|
|
29094
|
+
v_cart->>'orderId', item.payload->>'orderId', item.payload->>'order_id', item.payload->'data'->>'orderId')));
|
|
29095
|
+
IF doc_code <> '' AND v_order_id IS NOT NULL THEN
|
|
29096
|
+
layout_meta := public.logistics_document_for_order(v_order_id, doc_code);
|
|
29097
|
+
target_layout := public.logistics_try_uuid(layout_meta->>'layout_id');
|
|
29098
|
+
v_ok := COALESCE(layout_meta->>'ok', 'true') <> 'false';
|
|
29099
|
+
v_reden := nullif(layout_meta->>'reden', '');
|
|
29100
|
+
ELSIF doc_code <> '' THEN
|
|
29101
|
+
layout_meta := public.logistics_document_layout_v2(doc_code, v_is_partial);
|
|
29102
|
+
target_layout := public.logistics_try_uuid(layout_meta->>'layout_id');
|
|
29103
|
+
END IF;
|
|
29104
|
+
|
|
29105
|
+
SELECT l.documenttype INTO layout_type
|
|
29106
|
+
FROM public.document_layouts l
|
|
29107
|
+
WHERE l.id = target_layout AND l.actief IS TRUE;
|
|
29108
|
+
|
|
29109
|
+
IF layout_type IS NULL THEN target_layout := NULL; END IF;
|
|
29110
|
+
|
|
29111
|
+
doc_type := COALESCE(layout_type, v_types[1], 'vrij');
|
|
29112
|
+
|
|
29113
|
+
IF item.station_id IS NOT NULL THEN
|
|
29114
|
+
SELECT k.print_plek_id INTO target_plek
|
|
29115
|
+
FROM public.print_plek_koppelingen k
|
|
29116
|
+
WHERE k.bron IN ('pickstation', 'pick_station')
|
|
29117
|
+
AND k.bron_id = item.station_id::text
|
|
29118
|
+
ORDER BY k.created_at
|
|
29119
|
+
LIMIT 1;
|
|
29120
|
+
END IF;
|
|
29121
|
+
|
|
29122
|
+
pdf_url := nullif(item.payload->>'pdf_url', '');
|
|
29123
|
+
pdf_b64 := nullif(item.payload->>'pdf_base64', '');
|
|
29124
|
+
herkomst := nullif(item.payload->>'herkomst', '');
|
|
29125
|
+
|
|
29126
|
+
IF target_layout IS NULL AND v_reden IS NULL AND pdf_url IS NULL AND pdf_b64 IS NULL THEN
|
|
29127
|
+
v_reden := 'Maak of activeer een ' || COALESCE(nullif(doc_code, ''), 'document') || 'layout in Layouts en printers.';
|
|
29128
|
+
END IF;
|
|
29129
|
+
IF NOT v_ok AND (pdf_url IS NOT NULL OR pdf_b64 IS NOT NULL) THEN v_ok := true; END IF;
|
|
29130
|
+
|
|
29131
|
+
RETURN jsonb_build_object(
|
|
29132
|
+
'ok', v_ok,
|
|
29133
|
+
'reden', CASE WHEN v_ok THEN NULL ELSE v_reden END,
|
|
29134
|
+
'layout_keuze', layout_meta->>'keuze',
|
|
29135
|
+
'queue_item_id', item.id,
|
|
29136
|
+
'station_id', item.station_id,
|
|
29137
|
+
'doc_code', doc_code,
|
|
29138
|
+
'layout_id', target_layout,
|
|
29139
|
+
'layout_variant', CASE WHEN v_is_partial THEN 'partial_order' ELSE 'full_cart' END,
|
|
29140
|
+
'cart_id', v_cart_id,
|
|
29141
|
+
'cart', v_cart,
|
|
29142
|
+
'barcode', v_barcode,
|
|
29143
|
+
'documenttype', doc_type,
|
|
29144
|
+
'documentnaam', COALESCE(item.document_number, 'Pickdocument'),
|
|
29145
|
+
'pdf_url', pdf_url,
|
|
29146
|
+
'pdf_base64', pdf_b64,
|
|
29147
|
+
'herkomst', herkomst,
|
|
29148
|
+
'render_html', nullif(item.payload->>'render_html', ''),
|
|
29149
|
+
'print_plek_id', target_plek,
|
|
29150
|
+
'foutmelding',
|
|
29151
|
+
CASE WHEN target_layout IS NULL AND pdf_url IS NULL AND pdf_b64 IS NULL
|
|
29152
|
+
THEN v_reden
|
|
29153
|
+
ELSE NULL END,
|
|
29154
|
+
'payload', jsonb_build_object(
|
|
29155
|
+
'source', 'pickstation',
|
|
29156
|
+
'voorbeeld', COALESCE(_voorbeeld, false),
|
|
29157
|
+
'queue_item_id', item.id,
|
|
29158
|
+
'station_id', item.station_id,
|
|
29159
|
+
'print_plek_id', target_plek,
|
|
29160
|
+
'session_id', _session_id,
|
|
29161
|
+
'is_herprint', COALESCE(_is_herprint, false),
|
|
29162
|
+
'document_number', item.document_number,
|
|
29163
|
+
'document_type_code', COALESCE(nullif(doc_code, ''), dt.code),
|
|
29164
|
+
'layout_variant', CASE WHEN v_is_partial THEN 'partial_order' ELSE 'full_cart' END,
|
|
29165
|
+
'layout_id', target_layout,
|
|
29166
|
+
'report_key', dt.report_key,
|
|
29167
|
+
'print_template', dt.print_template,
|
|
29168
|
+
'order_number', item.order_number,
|
|
29169
|
+
'customer_name', item.customer_name,
|
|
29170
|
+
'reference', item.reference,
|
|
29171
|
+
'barcode', CASE WHEN v_barcode_on THEN COALESCE(v_barcode, item.barcode) ELSE item.barcode END,
|
|
29172
|
+
'cart_id', v_cart_id,
|
|
29173
|
+
'cart_index', v_cart->>'cartIndex',
|
|
29174
|
+
'cart_total', v_cart->>'cartTotal',
|
|
29175
|
+
'cart_label', v_cart->>'cartLabel',
|
|
29176
|
+
'cart_items', COALESCE(v_cart->'items', '[]'::jsonb),
|
|
29177
|
+
'country_code', item.country_code,
|
|
29178
|
+
'data', (COALESCE(item.payload, '{}'::jsonb) - 'layout_id' - 'layout')
|
|
29179
|
+
|| jsonb_build_object('print_plek_id', target_plek)
|
|
29180
|
+
|| COALESCE(jsonb_build_object('cart', v_cart), '{}'::jsonb)
|
|
29181
|
+
)
|
|
29182
|
+
);
|
|
29183
|
+
END;
|
|
29184
|
+
$function$;
|
|
29185
|
+
|
|
29186
|
+
CREATE OR REPLACE FUNCTION public.pick_enqueue_print_job(_queue_item_id uuid, _printer_id uuid DEFAULT NULL::uuid, _session_id text DEFAULT NULL::text, _is_herprint boolean DEFAULT false)
|
|
29187
|
+
RETURNS uuid
|
|
29188
|
+
LANGUAGE plpgsql
|
|
29189
|
+
SECURITY DEFINER
|
|
29190
|
+
SET search_path TO 'public'
|
|
29191
|
+
AS $function$
|
|
29192
|
+
declare
|
|
29193
|
+
doc jsonb; target_printer uuid; job_id uuid; v_cart_id uuid;
|
|
29194
|
+
v_doc_code text; v_plan jsonb; v_cart jsonb; v_last uuid; v_row_cart text;
|
|
29195
|
+
begin
|
|
29196
|
+
select lower(btrim(coalesce(nullif(q.payload->>'documentType',''), nullif(t.code,''), ''))),
|
|
29197
|
+
nullif(q.payload->>'cartId','')
|
|
29198
|
+
into v_doc_code, v_row_cart
|
|
29199
|
+
from public.pick_queue q
|
|
29200
|
+
left join public.pick_document_types t on t.id = q.document_type_id
|
|
29201
|
+
where q.id = _queue_item_id;
|
|
29202
|
+
|
|
29203
|
+
if v_doc_code = 'pakbon' then
|
|
29204
|
+
-- Karregel: precies die ene kar. Orderregel: per kar één opdracht.
|
|
29205
|
+
if v_row_cart is not null then
|
|
29206
|
+
return public.pick_enqueue_print_job(_queue_item_id, _printer_id, _session_id,
|
|
29207
|
+
coalesce(_is_herprint,false), v_row_cart);
|
|
29208
|
+
end if;
|
|
29209
|
+
|
|
29210
|
+
begin
|
|
29211
|
+
v_plan := public.pick_queue_cart_plan(_queue_item_id);
|
|
29212
|
+
exception when others then v_plan := null; end;
|
|
29213
|
+
|
|
29214
|
+
if v_plan is null or jsonb_array_length(coalesce(v_plan->'carts','[]'::jsonb)) = 0 then
|
|
29215
|
+
raise exception 'Het karplan voor dit document is nog niet klaar; er wordt geen pakbon zonder barcode geprint.' using errcode='check_violation';
|
|
29216
|
+
end if;
|
|
29217
|
+
|
|
29218
|
+
for v_cart in select c from jsonb_array_elements(v_plan->'carts') as c loop
|
|
29219
|
+
v_last := public.pick_enqueue_print_job(_queue_item_id, _printer_id, _session_id,
|
|
29220
|
+
coalesce(_is_herprint,false), v_cart->>'cartId');
|
|
29221
|
+
end loop;
|
|
29222
|
+
return v_last;
|
|
29223
|
+
end if;
|
|
29224
|
+
|
|
29225
|
+
doc := public.logistics_resolve_pick_document(_queue_item_id, false, _session_id, coalesce(_is_herprint,false));
|
|
29226
|
+
-- 1.0.176: centrale documentkeuze zegt nee -> dit document niet maken, reden teruggeven.
|
|
29227
|
+
if doc->>'ok' = 'false' then
|
|
29228
|
+
raise exception '%', coalesce(nullif(doc->>'reden',''), 'Geen layout voor dit document.') using errcode='check_violation';
|
|
29229
|
+
end if;
|
|
29230
|
+
|
|
29231
|
+
if nullif(doc->>'barcode','') is not null then
|
|
29232
|
+
begin v_cart_id := nullif(doc->>'cart_id','')::uuid;
|
|
29233
|
+
exception when invalid_text_representation then v_cart_id := null; end;
|
|
29234
|
+
if v_cart_id is not null then perform public.logistics_ensure_cart_barcode(v_cart_id); end if;
|
|
29235
|
+
end if;
|
|
29236
|
+
|
|
29237
|
+
select p.id into target_printer from public.printers p
|
|
29238
|
+
where p.id = _printer_id and p.actief and nullif(p.extern_printer_id,'') is not null;
|
|
29239
|
+
|
|
29240
|
+
insert into public.print_jobs(
|
|
29241
|
+
printer_id, layout_id, documenttype, documentnaam, status, foutmelding,
|
|
29242
|
+
payload, gebruiker_naam, pdf_url, pdf_base64, herkomst, is_herprint)
|
|
29243
|
+
values (target_printer, nullif(doc->>'layout_id','')::uuid,
|
|
29244
|
+
(doc->>'documenttype')::public.doc_layout_type, doc->>'documentnaam', 'wachtend',
|
|
29245
|
+
nullif(doc->>'foutmelding',''), doc->'payload', 'Pickstation',
|
|
29246
|
+
nullif(doc->>'pdf_url',''), nullif(doc->>'pdf_base64',''), nullif(doc->>'herkomst',''),
|
|
29247
|
+
coalesce(_is_herprint,false))
|
|
29248
|
+
returning id into job_id;
|
|
29249
|
+
|
|
29250
|
+
perform public.logistics_enqueue_sticker_with_slip(_queue_item_id, _printer_id, _session_id,
|
|
29251
|
+
coalesce(_is_herprint,false), nullif(doc->>'cart_id',''), job_id);
|
|
29252
|
+
update public.pick_queue set print_job_id = job_id where id = _queue_item_id;
|
|
29253
|
+
|
|
29254
|
+
return job_id;
|
|
29255
|
+
end; $function$;
|
|
29256
|
+
|
|
29257
|
+
CREATE OR REPLACE FUNCTION public.pick_enqueue_print_job(_queue_item_id uuid, _printer_id uuid, _session_id text, _is_herprint boolean, _cart_id text)
|
|
29258
|
+
RETURNS uuid
|
|
29259
|
+
LANGUAGE plpgsql
|
|
29260
|
+
SECURITY DEFINER
|
|
29261
|
+
SET search_path TO 'public'
|
|
29262
|
+
AS $function$
|
|
29263
|
+
DECLARE
|
|
29264
|
+
item public.pick_queue;
|
|
29265
|
+
dt public.pick_document_types;
|
|
29266
|
+
doc_code text;
|
|
29267
|
+
target_printer uuid;
|
|
29268
|
+
target_layout uuid;
|
|
29269
|
+
target_plek uuid;
|
|
29270
|
+
layout_meta jsonb;
|
|
29271
|
+
layout_reden text;
|
|
29272
|
+
v_types public.doc_layout_type[];
|
|
29273
|
+
doc_type public.doc_layout_type := 'vrij';
|
|
29274
|
+
layout_type public.doc_layout_type;
|
|
29275
|
+
pdf_url text;
|
|
29276
|
+
pdf_b64 text;
|
|
29277
|
+
herkomst text;
|
|
29278
|
+
job_id uuid;
|
|
29279
|
+
cart_plan jsonb := NULL;
|
|
29280
|
+
selected_cart jsonb := NULL;
|
|
29281
|
+
v_cart_uuid uuid;
|
|
29282
|
+
v_barcode text;
|
|
29283
|
+
v_barcode_on boolean := public.logistics_pick_barcode_enabled();
|
|
29284
|
+
v_is_partial boolean := false;
|
|
29285
|
+
v_sleutel text;
|
|
29286
|
+
v_order uuid;
|
|
29287
|
+
BEGIN
|
|
29288
|
+
SELECT * INTO item FROM public.pick_queue WHERE id = _queue_item_id;
|
|
29289
|
+
IF NOT FOUND THEN RAISE EXCEPTION 'Dit document bestaat niet meer.'; END IF;
|
|
29290
|
+
SELECT * INTO dt FROM public.pick_document_types WHERE id = item.document_type_id;
|
|
29291
|
+
doc_code := lower(btrim(coalesce(nullif(item.payload->>'documentType', ''), nullif(dt.code, ''), '')));
|
|
29292
|
+
v_types := public.logistics_document_type_map(doc_code);
|
|
29293
|
+
|
|
29294
|
+
IF _cart_id IS NOT NULL THEN
|
|
29295
|
+
cart_plan := public.pick_queue_cart_plan(_queue_item_id);
|
|
29296
|
+
SELECT c INTO selected_cart FROM jsonb_array_elements(COALESCE(cart_plan->'carts', '[]'::jsonb)) AS c
|
|
29297
|
+
WHERE c->>'cartId' = _cart_id LIMIT 1;
|
|
29298
|
+
IF selected_cart IS NULL THEN
|
|
29299
|
+
RAISE EXCEPTION 'De gekozen kar bestaat niet meer in het actuele karplan.';
|
|
29300
|
+
END IF;
|
|
29301
|
+
v_is_partial := NOT COALESCE((selected_cart->>'isFullCart')::boolean, false);
|
|
29302
|
+
IF v_barcode_on THEN
|
|
29303
|
+
BEGIN
|
|
29304
|
+
v_cart_uuid := nullif(_cart_id, '')::uuid;
|
|
29305
|
+
EXCEPTION WHEN invalid_text_representation THEN
|
|
29306
|
+
v_cart_uuid := NULL;
|
|
29307
|
+
END;
|
|
29308
|
+
IF v_cart_uuid IS NOT NULL THEN
|
|
29309
|
+
v_barcode := public.logistics_ensure_cart_barcode(v_cart_uuid);
|
|
29310
|
+
selected_cart := selected_cart || jsonb_build_object('barcode', v_barcode);
|
|
29311
|
+
END IF;
|
|
29312
|
+
END IF;
|
|
29313
|
+
END IF;
|
|
29314
|
+
|
|
29315
|
+
-- 1.0.176: het document wordt automatisch bepaald uit de order.
|
|
29316
|
+
v_order := public.logistics_try_uuid(COALESCE(selected_cart->>'orderId', item.payload->>'orderId', item.payload->>'order_id'));
|
|
29317
|
+
IF doc_code <> '' AND v_order IS NOT NULL THEN
|
|
29318
|
+
layout_meta := public.logistics_document_for_order(v_order, doc_code);
|
|
29319
|
+
target_layout := public.logistics_try_uuid(layout_meta->>'layout_id');
|
|
29320
|
+
layout_reden := nullif(layout_meta->>'reden', '');
|
|
29321
|
+
IF layout_meta->>'ok' = 'false' AND nullif(item.payload->>'pdf_url', '') IS NULL AND nullif(item.payload->>'pdf_base64', '') IS NULL THEN
|
|
29322
|
+
RAISE EXCEPTION '%', COALESCE(layout_reden, 'Geen layout voor dit document.') USING ERRCODE = 'check_violation';
|
|
29323
|
+
END IF;
|
|
29324
|
+
ELSIF doc_code <> '' THEN
|
|
29325
|
+
layout_meta := public.logistics_document_layout_v2(doc_code, v_is_partial);
|
|
29326
|
+
target_layout := public.logistics_try_uuid(layout_meta->>'layout_id');
|
|
29327
|
+
END IF;
|
|
29328
|
+
|
|
29329
|
+
SELECT l.documenttype INTO layout_type FROM public.document_layouts l WHERE l.id = target_layout AND l.actief IS TRUE;
|
|
29330
|
+
IF layout_type IS NULL THEN target_layout := NULL; END IF;
|
|
29331
|
+
doc_type := COALESCE(layout_type, v_types[1], 'vrij');
|
|
29332
|
+
|
|
29333
|
+
IF item.station_id IS NOT NULL THEN
|
|
29334
|
+
SELECT k.print_plek_id INTO target_plek FROM public.print_plek_koppelingen k
|
|
29335
|
+
WHERE k.bron IN ('pickstation', 'pick_station') AND k.bron_id = item.station_id::text
|
|
29336
|
+
ORDER BY k.created_at LIMIT 1;
|
|
29337
|
+
END IF;
|
|
29338
|
+
|
|
29339
|
+
SELECT p.id INTO target_printer FROM public.printers p
|
|
29340
|
+
WHERE p.id = _printer_id AND p.actief AND nullif(p.extern_printer_id, '') IS NOT NULL;
|
|
29341
|
+
|
|
29342
|
+
pdf_url := nullif(item.payload->>'pdf_url', '');
|
|
29343
|
+
pdf_b64 := nullif(item.payload->>'pdf_base64', '');
|
|
29344
|
+
herkomst := nullif(item.payload->>'herkomst', '');
|
|
29345
|
+
|
|
29346
|
+
IF NOT COALESCE(_is_herprint, false) AND _cart_id IS NOT NULL THEN
|
|
29347
|
+
v_sleutel := 'pakbon:' || item.id::text || ':' || _cart_id || ':'
|
|
29348
|
+
|| coalesce(target_layout::text, '-') || ':' || coalesce(target_printer::text, '-');
|
|
29349
|
+
END IF;
|
|
29350
|
+
|
|
29351
|
+
INSERT INTO public.print_jobs(
|
|
29352
|
+
printer_id, layout_id, documenttype, documentnaam, status, foutmelding,
|
|
29353
|
+
payload, gebruiker_naam, pdf_url, pdf_base64, herkomst, is_herprint, idempotentie_sleutel
|
|
29354
|
+
)
|
|
29355
|
+
VALUES (
|
|
29356
|
+
target_printer, target_layout, doc_type, COALESCE(item.document_number, 'Pickdocument'), 'wachtend',
|
|
29357
|
+
CASE WHEN target_layout IS NULL AND pdf_url IS NULL AND pdf_b64 IS NULL
|
|
29358
|
+
THEN COALESCE(layout_reden, 'Maak of activeer een ' || COALESCE(nullif(doc_code, ''), 'document') || 'layout in Layouts en printers.')
|
|
29359
|
+
ELSE NULL END,
|
|
29360
|
+
jsonb_build_object(
|
|
29361
|
+
'source', 'pickstation', 'queue_item_id', item.id, 'station_id', item.station_id,
|
|
29362
|
+
'print_plek_id', target_plek, 'session_id', _session_id, 'is_herprint', COALESCE(_is_herprint, false),
|
|
29363
|
+
'document_number', item.document_number, 'document_type_code', COALESCE(nullif(doc_code, ''), dt.code),
|
|
29364
|
+
'report_key', dt.report_key, 'print_template', dt.print_template,
|
|
29365
|
+
'order_number', COALESCE(selected_cart->>'orderNumber', item.order_number),
|
|
29366
|
+
'customer_name', item.customer_name, 'reference', item.reference,
|
|
29367
|
+
'layout_id', target_layout, 'layout_keuze', layout_meta->>'keuze',
|
|
29368
|
+
'layout_variant', CASE WHEN v_is_partial THEN 'partial_order' ELSE 'full_cart' END,
|
|
29369
|
+
'barcode', CASE WHEN v_barcode_on THEN COALESCE(v_barcode, item.barcode) ELSE item.barcode END,
|
|
29370
|
+
'country_code', item.country_code, 'cart_id', _cart_id, 'cart', selected_cart,
|
|
29371
|
+
'data', (COALESCE(item.payload, '{}'::jsonb) - 'layout_id' - 'layout') || jsonb_build_object(
|
|
29372
|
+
'print_plek_id', target_plek, 'cart_id', _cart_id, 'cart', selected_cart,
|
|
29373
|
+
'orderId', COALESCE(selected_cart->>'orderId', item.payload->>'orderId'),
|
|
29374
|
+
'orderNumber', COALESCE(selected_cart->>'orderNumber', item.order_number))
|
|
29375
|
+
),
|
|
29376
|
+
'Pickstation', pdf_url, pdf_b64, herkomst, COALESCE(_is_herprint, false), v_sleutel
|
|
29377
|
+
)
|
|
29378
|
+
RETURNING id INTO job_id;
|
|
29379
|
+
|
|
29380
|
+
PERFORM public.logistics_enqueue_sticker_with_slip(_queue_item_id, _printer_id, _session_id, COALESCE(_is_herprint,false), _cart_id, job_id);
|
|
29381
|
+
UPDATE public.pick_queue SET print_job_id = job_id WHERE id = _queue_item_id;
|
|
29382
|
+
RETURN job_id;
|
|
29383
|
+
END;
|
|
29384
|
+
$function$;
|
|
29385
|
+
|
|
29386
|
+
-- ===== 1.0.176 verzenddocument Floriday bepalen =====
|
|
29387
|
+
-- 1.0.176: welk verzenddocument levert Floriday voor deze order (afleverbrief of veilingbrief).
|
|
29388
|
+
-- Bron: logistics_slip_shipping_note.fulfillment_order_id -> floriday_fulfillment_orders_cache.floriday_id,
|
|
29389
|
+
-- velden data->>'type', data->>'isReAuctioning', data->'deliveryNoteCodes'. Fail closed: niet gokken.
|
|
29390
|
+
CREATE OR REPLACE FUNCTION public.logistics_floriday_shipping_document(p_order_id uuid)
|
|
29391
|
+
RETURNS jsonb
|
|
29392
|
+
LANGUAGE plpgsql
|
|
29393
|
+
STABLE
|
|
29394
|
+
SET search_path TO 'public'
|
|
29395
|
+
AS $function$
|
|
29396
|
+
DECLARE
|
|
29397
|
+
v_fo text;
|
|
29398
|
+
v_data jsonb;
|
|
29399
|
+
v_type text;
|
|
29400
|
+
BEGIN
|
|
29401
|
+
IF to_regclass('public.logistics_slip_shipping_note') IS NULL OR to_regclass('public.floriday_fulfillment_orders_cache') IS NULL THEN
|
|
29402
|
+
RETURN jsonb_build_object('ok', false, 'documenttype', NULL, 'fulfillment_order_id', NULL,
|
|
29403
|
+
'reden', 'De Floriday-zendinggegevens ontbreken in deze omgeving; het verzenddocument kan niet worden bepaald.');
|
|
29404
|
+
END IF;
|
|
29405
|
+
SELECT s.fulfillment_order_id::text INTO v_fo
|
|
29406
|
+
FROM public.logistics_slip_shipping_note s
|
|
29407
|
+
WHERE s.order_id = p_order_id AND s.fulfillment_order_id IS NOT NULL
|
|
29408
|
+
ORDER BY s.updated_at DESC NULLS LAST, s.created_at DESC LIMIT 1;
|
|
29409
|
+
IF v_fo IS NULL THEN
|
|
29410
|
+
RETURN jsonb_build_object('ok', false, 'documenttype', NULL, 'fulfillment_order_id', NULL,
|
|
29411
|
+
'reden', 'Nog geen Floriday-zending bekend voor deze order; het verzenddocument volgt zodra Floriday die heeft vastgelegd.');
|
|
29412
|
+
END IF;
|
|
29413
|
+
SELECT c.data INTO v_data FROM public.floriday_fulfillment_orders_cache c
|
|
29414
|
+
WHERE c.floriday_id::text = v_fo AND c.is_deleted IS NOT TRUE ORDER BY c.fetched_at DESC NULLS LAST LIMIT 1;
|
|
29415
|
+
IF v_data IS NULL THEN
|
|
29416
|
+
RETURN jsonb_build_object('ok', false, 'documenttype', NULL, 'fulfillment_order_id', v_fo,
|
|
29417
|
+
'reden', 'De Floriday-zending van deze order is nog niet opgehaald; het verzenddocument volgt na de volgende Floriday-synchronisatie.');
|
|
29418
|
+
END IF;
|
|
29419
|
+
v_type := upper(coalesce(v_data->>'type', ''));
|
|
29420
|
+
IF lower(coalesce(v_data->>'isReAuctioning', '')) = 'true' OR v_type LIKE '%CLOCK%' OR v_type LIKE '%AUCTION%' THEN
|
|
29421
|
+
RETURN jsonb_build_object('ok', true, 'documenttype', 'veilingbrief', 'fulfillment_order_id', v_fo, 'reden', NULL);
|
|
29422
|
+
END IF;
|
|
29423
|
+
IF v_type = 'DIRECT_SALES' AND jsonb_typeof(v_data->'deliveryNoteCodes') = 'array'
|
|
29424
|
+
AND jsonb_array_length(v_data->'deliveryNoteCodes') > 0 THEN
|
|
29425
|
+
RETURN jsonb_build_object('ok', true, 'documenttype', 'afleverbrief', 'fulfillment_order_id', v_fo, 'reden', NULL);
|
|
29426
|
+
END IF;
|
|
29427
|
+
RETURN jsonb_build_object('ok', false, 'documenttype', NULL, 'fulfillment_order_id', v_fo,
|
|
29428
|
+
'reden', 'Onbekend Floriday-zendingtype "' || coalesce(nullif(v_type, ''), 'leeg')
|
|
29429
|
+
|| '" of nog geen verzendbriefcode; het verzenddocument wordt niet gegokt.');
|
|
29430
|
+
END;
|
|
29431
|
+
$function$;
|
|
29432
|
+
REVOKE EXECUTE ON FUNCTION public.logistics_floriday_shipping_document(uuid) FROM PUBLIC, anon;
|
|
29433
|
+
GRANT EXECUTE ON FUNCTION public.logistics_floriday_shipping_document(uuid) TO authenticated, service_role;
|
|
29434
|
+
|
|
29435
|
+
CREATE OR REPLACE FUNCTION public.logistics_document_for_order(p_order_id uuid, p_documenttype text)
|
|
29436
|
+
RETURNS jsonb
|
|
29437
|
+
LANGUAGE plpgsql
|
|
29438
|
+
STABLE
|
|
29439
|
+
SET search_path TO 'public'
|
|
29440
|
+
AS $function$
|
|
29441
|
+
DECLARE
|
|
29442
|
+
v_soort text := lower(btrim(coalesce(p_documenttype, '')));
|
|
29443
|
+
v_floriday boolean;
|
|
29444
|
+
v_bron text;
|
|
29445
|
+
v_type text;
|
|
29446
|
+
v_res jsonb;
|
|
29447
|
+
v_n int; v_std int;
|
|
29448
|
+
v_l public.document_layouts%ROWTYPE;
|
|
29449
|
+
v_ship jsonb;
|
|
29450
|
+
v_extra jsonb := '{}'::jsonb;
|
|
29451
|
+
BEGIN
|
|
29452
|
+
IF v_soort = '' THEN
|
|
29453
|
+
RETURN jsonb_build_object('ok', false, 'layout_id', NULL, 'reden', 'Geen documentsoort opgegeven.');
|
|
29454
|
+
END IF;
|
|
29455
|
+
|
|
29456
|
+
-- 1.0.176: 'verzenddocument' wordt hier vertaald naar het echte document van de order.
|
|
29457
|
+
IF v_soort IN ('verzenddocument', 'verzendbrief') THEN
|
|
29458
|
+
SELECT o.order_source = 'floriday' INTO v_floriday FROM public.orders o WHERE o.id = p_order_id;
|
|
29459
|
+
IF NOT FOUND THEN
|
|
29460
|
+
RETURN jsonb_build_object('ok', false, 'layout_id', NULL, 'reden', 'Order niet gevonden.');
|
|
29461
|
+
END IF;
|
|
29462
|
+
IF coalesce(v_floriday, false) THEN
|
|
29463
|
+
v_ship := public.logistics_floriday_shipping_document(p_order_id);
|
|
29464
|
+
IF NOT coalesce((v_ship->>'ok')::boolean, false) THEN
|
|
29465
|
+
RETURN jsonb_build_object('ok', false, 'layout_id', NULL, 'keuze', 'engine',
|
|
29466
|
+
'fulfillment_order_id', v_ship->>'fulfillment_order_id', 'reden', v_ship->>'reden');
|
|
29467
|
+
END IF;
|
|
29468
|
+
v_soort := v_ship->>'documenttype';
|
|
29469
|
+
v_extra := jsonb_build_object('verzenddocument_bepaald', v_soort,
|
|
29470
|
+
'fulfillment_order_id', v_ship->>'fulfillment_order_id');
|
|
29471
|
+
ELSE
|
|
29472
|
+
v_soort := 'afleverbrief';
|
|
29473
|
+
v_extra := jsonb_build_object('verzenddocument_bepaald', 'afleverbrief');
|
|
29474
|
+
END IF;
|
|
29475
|
+
END IF;
|
|
29476
|
+
|
|
29477
|
+
IF to_regprocedure('public.layout_voor_document(uuid,text)') IS NOT NULL THEN
|
|
29478
|
+
EXECUTE 'SELECT to_jsonb(public.layout_voor_document($1, $2))' INTO v_res USING p_order_id, v_soort;
|
|
29479
|
+
IF jsonb_typeof(v_res) IS DISTINCT FROM 'object' THEN
|
|
29480
|
+
RETURN jsonb_build_object('ok', false, 'layout_id', NULL, 'keuze', 'layouts',
|
|
29481
|
+
'reden', 'Layouts gaf geen bruikbaar antwoord voor ' || v_soort || '.') || v_extra;
|
|
29482
|
+
END IF;
|
|
29483
|
+
RETURN v_res || jsonb_build_object('keuze', 'layouts',
|
|
29484
|
+
'ok', coalesce((v_res->>'ok')::boolean, nullif(v_res->>'layout_id', '') IS NOT NULL)) || v_extra;
|
|
29485
|
+
END IF;
|
|
29486
|
+
SELECT o.order_source = 'floriday' INTO v_floriday FROM public.orders o WHERE o.id = p_order_id;
|
|
29487
|
+
IF v_floriday IS NULL THEN
|
|
29488
|
+
SELECT EXISTS (SELECT 1 FROM public.orders WHERE id = p_order_id) INTO v_floriday;
|
|
29489
|
+
IF NOT v_floriday THEN
|
|
29490
|
+
RETURN jsonb_build_object('ok', false, 'layout_id', NULL, 'keuze', 'automatisch', 'reden', 'Order niet gevonden.');
|
|
29491
|
+
END IF;
|
|
29492
|
+
v_floriday := false;
|
|
29493
|
+
END IF;
|
|
29494
|
+
v_type := CASE
|
|
29495
|
+
WHEN v_soort IN ('eigen_sticker', 'sticker', 'etiket') THEN 'sticker'
|
|
29496
|
+
WHEN v_soort IN ('verzenddocument', 'verzendbrief', 'afleverbrief', 'afleverbon') THEN 'afleverbrief'
|
|
29497
|
+
WHEN v_soort IN ('veilingbrief', 'veilingbon') THEN 'veilingbrief'
|
|
29498
|
+
WHEN v_soort LIKE '%pakbon%' THEN 'pakbon'
|
|
29499
|
+
WHEN v_soort LIKE '%productie%' THEN 'productiebon'
|
|
29500
|
+
ELSE v_soort END;
|
|
29501
|
+
v_bron := CASE
|
|
29502
|
+
WHEN v_floriday AND v_soort <> 'eigen_sticker' AND v_type IN ('sticker', 'traysticker', 'afleverbrief', 'veilingbrief') THEN 'floriday'
|
|
29503
|
+
ELSE 'eigen' END;
|
|
29504
|
+
IF v_bron = 'eigen' AND v_type = 'veilingbrief' THEN
|
|
29505
|
+
RETURN jsonb_build_object('ok', false, 'layout_id', NULL, 'keuze', 'automatisch',
|
|
29506
|
+
'reden', 'Een veilingbrief hoort alleen bij een Floriday-order; voor een eigen order wordt de afleverbrief gebruikt.');
|
|
29507
|
+
END IF;
|
|
29508
|
+
SELECT count(*), count(*) FILTER (WHERE is_standaard IS TRUE) INTO v_n, v_std
|
|
29509
|
+
FROM public.document_layouts
|
|
29510
|
+
WHERE actief IS TRUE AND coalesce(bron, 'eigen') = v_bron AND documenttype::text = v_type;
|
|
29511
|
+
IF v_n >= 1 THEN
|
|
29512
|
+
SELECT * INTO v_l FROM public.document_layouts
|
|
29513
|
+
WHERE actief IS TRUE AND coalesce(bron, 'eigen') = v_bron AND documenttype::text = v_type
|
|
29514
|
+
ORDER BY is_standaard DESC NULLS LAST, updated_at DESC LIMIT 1;
|
|
29515
|
+
END IF;
|
|
29516
|
+
IF v_l.id IS NULL THEN
|
|
29517
|
+
RETURN jsonb_build_object('ok', false, 'layout_id', NULL, 'keuze', 'automatisch', 'bron', v_bron, 'documenttype', v_type,
|
|
29518
|
+
'reden', CASE WHEN v_bron = 'floriday'
|
|
29519
|
+
THEN 'Geen actieve ' || v_type || '-layout met bron Floriday. Activeer de Floriday-systeemlayout in Layouts en printers.'
|
|
29520
|
+
ELSE 'Maak of activeer een ' || v_type || 'layout in Layouts en printers.' END) || v_extra;
|
|
29521
|
+
END IF;
|
|
29522
|
+
RETURN jsonb_build_object('ok', true, 'layout_id', v_l.id, 'keuze', 'automatisch', 'bron', v_bron,
|
|
29523
|
+
'documenttype', v_type, 'breedte_mm', v_l.breedte_mm, 'hoogte_mm', v_l.hoogte_mm, 'reden', NULL) || v_extra;
|
|
29524
|
+
END;
|
|
29525
|
+
$function$;
|