Compare commits

..

No commits in common. "ab5808d1e85c91a05a39f036d6cd6c485ca9a894" and "849d176ad05520487c4251b45e518474c141602c" have entirely different histories.

4 changed files with 141 additions and 386 deletions

View File

@ -1,20 +1,14 @@
EXEC pricing.single_price_call
@bill = 'FARM0001',
@ship = 'KEYB0001',
@part = 'HZP3E100E21D050',
@v1ds = 'v1:T..BDL..',
@vol = 50000;
EXEC pricing.single_price_call EXEC pricing.single_price_call
@bill = 'GRIF0001', @bill = 'GRIF0001',
@ship = 'GRIF0001', @ship = 'GRIF0001',
@part = 'XNS0T1G3G18B96', @part = 'XNS0T1G3G18B096',
@v1ds = 'v1:B..PLT..', @v1ds = 'v1:B.L.PLT..',
@vol = 9600; @vol = 9600;
SELECT SELECT
guidance_price, ui_json *
FROM pricing.single_price_call_fn( FROM pricing.single_price_call_fn(
'GRIF0001', 'GRIF0001',
'GRIF0001', 'GRIF0001',
@ -51,15 +45,4 @@ FROM
,q.units_each ,q.units_each
) p ) p
WHERE WHERE
qstat LIKE 'Submitted%' qstat LIKE 'Submitted%'
SELECT
*
FROM pricequote.single_price_call(
'GRIF0001',
'GRIF0001',
'XNS0T1G3G18B096',
'v1:B..PLT..',
9600
) f

View File

@ -1,10 +0,0 @@
SELECT
*
FROM pricequote.single_price_call(
'FARM0001',
'KEYB0001',
'HZP3E100E21D050',
'v1:T..BDL..',
50000
) f

View File

@ -85,56 +85,47 @@ BEGIN
bill VARCHAR(100), bill VARCHAR(100),
ship VARCHAR(100), ship VARCHAR(100),
part VARCHAR(100), part VARCHAR(100),
v1ds VARCHAR(100),
vol NUMERIC(18,6),
------------step 1 lookup scenario------------
chan VARCHAR(50),
tier VARCHAR(50),
cust VARCHAR(100),
pltq NUMERIC(18,6),
plevel NVARCHAR(20),
stlc VARCHAR(100), stlc VARCHAR(100),
partgroup VARCHAR(100), partgroup VARCHAR(100),
v1ds VARCHAR(100),
vol NUMERIC(18,6),
part_v1ds VARCHAR(50), part_v1ds VARCHAR(50),
v0ds VARCHAR(10),
curstd_orig NUMERIC(20,5), curstd_orig NUMERIC(20,5),
futstd_orig NUMERIC(20,5), futstd_orig NUMERIC(20,5),
customized VARCHAR(100), v0ds VARCHAR(10),
calculated_pallets numeric(20,0),
exact_pallets numeric(20,5),
----------- step 2 last price------------------
hist NVARCHAR(MAX),
last_price NUMERIC(20,5),
last_source NVARCHAR(100),
last_date DATE,
last_qty NUMERIC(20,5),
last_dataseg NVARCHAR(20),
last_v0ds VARCHAR(10),
last_order NVARCHAR(10),
last_quote NVARCHAR(10),
last_isdiff NVARCHAR(100),
------------step 3 lookup target---------------
tprice NUMERIC(20,5),
tprice_last NUMERIC(20,5),
tmath nvarchar(MAX),
volume_range VARCHAR(100),
------------step 4 normalize last price--------
curstd NUMERIC(20,5), curstd NUMERIC(20,5),
futstd NUMERIC(20,5), futstd NUMERIC(20,5),
curstd_last NUMERIC(20,5), customized VARCHAR(100),
futstd_last NUMERIC(20,5),
last_premium NUMERIC(20,5), last_premium NUMERIC(20,5),
last_price_norm NUMERIC(20,5), chan VARCHAR(50),
last_premium_method VARCHAR(100), cust VARCHAR(100),
------------step 5 list price lookup----------- tier VARCHAR(50),
listcode VARCHAR(10), pltq NUMERIC(18,6),
volume_range VARCHAR(100),
plevel NVARCHAR(20),
listprice NUMERIC(20,5), listprice NUMERIC(20,5),
listcode VARCHAR(10),
listprice_eff NUMERIC(20,5), listprice_eff NUMERIC(20,5),
list_relevance NVARCHAR(100), list_relevance NVARCHAR(100),
------------step 6 compute guidance------------ hist NVARCHAR(MAX),
last_price NUMERIC(20,5),
last_qty NUMERIC(20,5),
last_date DATE,
last_order NVARCHAR(10),
last_quote NVARCHAR(10),
last_dataseg NVARCHAR(20),
last_source NVARCHAR(100),
last_isdiff NVARCHAR(100),
last_v0ds VARCHAR(10),
last_price_norm NUMERIC(20,5),
last_premium_method VARCHAR(100),
curstd_last NUMERIC(20,5),
futstd_last NUMERIC(20,5),
tprice_last NUMERIC(20,5),
tprice NUMERIC(20,5),
tmath nvarchar(MAX),
guidance_price NUMERIC(20,5), guidance_price NUMERIC(20,5),
guidance_reason NVARCHAR(MAX), guidance_reason NVARCHAR(MAX),
------------step 7 build json------------------
expl NVARCHAR(MAX), expl NVARCHAR(MAX),
ui_json NVARCHAR(MAX) ui_json NVARCHAR(MAX)
); );
@ -184,17 +175,15 @@ BEGIN
ELSE bc.plevel ELSE bc.plevel
END, END,
stlc = substring(q.part,1,8), stlc = substring(q.part,1,8),
partgroup = TRIM(i.partgroup), partgroup = i.partgroup,
part_v1ds = TRIM(i.v1ds), part_v1ds = i.v1ds,
v0ds = v0ds =
CASE substring(q.v1ds,4,1) WHEN 'B' THEN 'B' ELSE 'C' END CASE substring(q.v1ds,4,1) WHEN 'B' THEN 'B' ELSE 'C' END
+ CASE substring(q.v1ds,6,1) WHEN 'L' THEN 'L' WHEN 'P' THEN 'P' ELSE '' END, + CASE substring(q.v1ds,6,1) WHEN 'L' THEN 'L' WHEN 'P' THEN 'P' ELSE '' END,
curstd_orig = i.curstdus, curstd_orig = i.curstdus,
futstd_orig = i.futstdus, futstd_orig = i.futstdus,
customized = CASE WHEN i.v1ds IS NOT NULL AND q.v1ds IS NOT NULL AND i.v1ds <> q.v1ds customized = CASE WHEN i.v1ds IS NOT NULL AND q.v1ds IS NOT NULL AND i.v1ds <> q.v1ds
THEN 'Customized' ELSE '' END, THEN 'Customized' ELSE '' END
calculated_pallets = FLOOR(q.vol / NULLIF(i.mpck, 0)),
exact_pallets = CAST(ROUND(q.vol / NULLIF(i.mpck, 0), 5) AS NUMERIC(20,5))
FROM @queue q FROM @queue q
LEFT JOIN rlarp.cust bc ON bc.code = q.bill LEFT JOIN rlarp.cust bc ON bc.code = q.bill
LEFT JOIN rlarp.cust sc ON sc.code = q.ship LEFT JOIN rlarp.cust sc ON sc.code = q.ship
@ -248,18 +237,18 @@ BEGIN
AND q.v1ds = tp.ds AND q.v1ds = tp.ds
AND q.chan = tp.chan AND q.chan = tp.chan
AND q.tier = tp.tier AND q.tier = tp.tier
AND q.calculated_pallets >= tp.lower_bound AND FLOOR(q.vol / NULLIF(q.pltq, 0)) >= tp.lower_bound
AND ( AND (
tp.upper_bound IS NULL OR q.calculated_pallets < tp.upper_bound tp.upper_bound IS NULL OR FLOOR(q.vol / NULLIF(q.pltq, 0)) < tp.upper_bound
) )
LEFT JOIN pricing.target_prices tpl ON LEFT JOIN pricing.target_prices tpl ON
q.stlc = tpl.stlc q.stlc = tpl.stlc
AND q.last_dataseg = tpl.ds AND q.last_dataseg = tpl.ds
AND q.chan = tpl.chan AND q.chan = tpl.chan
AND q.tier = tpl.tier AND q.tier = tpl.tier
AND q.calculated_pallets >= tpl.lower_bound AND FLOOR(q.vol / NULLIF(q.pltq, 0)) >= tpl.lower_bound
AND ( AND (
tpl.upper_bound IS NULL OR q.calculated_pallets < tpl.upper_bound tpl.upper_bound IS NULL OR FLOOR(q.vol / NULLIF(q.pltq, 0)) < tpl.upper_bound
); );
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -395,16 +384,11 @@ BEGIN
,q.tprice_last AS tprice_last ,q.tprice_last AS tprice_last
,q.tprice AS target_price ,q.tprice AS target_price
,JSON_QUERY(q.tmath) AS target_math ,JSON_QUERY(q.tmath) AS target_math
,q.calculated_pallets AS calculated_pallets ,FLOOR(q.vol / NULLIF(q.pltq, 0)) AS calculated_pallets
,q.exact_pallets AS exact_pallets ,CAST(ROUND(q.vol / NULLIF(q.pltq, 0), 5) AS NUMERIC(20,5)) AS exact_pallets
,q.cust AS customer ,q.cust AS customer
,q.chan AS channel ,q.chan AS channel
,q.part AS part
,q.stlc AS stlc
,TRIM(q.tier) AS tier ,TRIM(q.tier) AS tier
,q.vol AS vol
,q.pltq AS pltq
,q.v1ds AS v1ds
,q.part_v1ds AS part_v1ds ,q.part_v1ds AS part_v1ds
,q.curstd_orig AS curstd_orig ,q.curstd_orig AS curstd_orig
,q.futstd_orig AS futstd_orig ,q.futstd_orig AS futstd_orig
@ -482,7 +466,7 @@ BEGIN
RTRIM(SUBSTRING(value,1,18)) AS label, RTRIM(SUBSTRING(value,1,18)) AS label,
TRY_CAST(SUBSTRING(value,23,7) AS NUMERIC(20,5)) TRY_CAST(SUBSTRING(value,23,7) AS NUMERIC(20,5))
+ CASE SUBSTRING(value,19,1) WHEN '+' THEN 0 ELSE -1 END AS value, + CASE SUBSTRING(value,19,1) WHEN '+' THEN 0 ELSE -1 END AS value,
CASE SUBSTRING(value,19,1) WHEN '+' THEN 'currency' ELSE 'Percent' END AS type, CASE SUBSTRING(value,19,1) WHEN '+' THEN 'currency' ELSE 'Percentage' END AS type,
CASE SUBSTRING(value,19,1) WHEN '+' THEN 'Price' ELSE 'Premium' END AS note CASE SUBSTRING(value,19,1) WHEN '+' THEN 'Price' ELSE 'Premium' END AS note
FROM OPENJSON(q.expl, '$.target_math') FROM OPENJSON(q.expl, '$.target_math')
WITH (value NVARCHAR(MAX) '$') WITH (value NVARCHAR(MAX) '$')
@ -513,5 +497,5 @@ BEGIN
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Final: Return all calculated fields and JSON payloads. -- Final: Return all calculated fields and JSON payloads.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
SELECT guidance_price, ui_json FROM @queue; SELECT * FROM @queue;
END; END;

View File

@ -34,9 +34,6 @@
- See also: matrix_guidance.pg.sql for batch/matrix logic - See also: matrix_guidance.pg.sql for batch/matrix logic
==================================================================================== ====================================================================================
*/ */
DROP FUNCTION pricequote.single_price_call(text,text,text,text,numeric);
CREATE OR REPLACE FUNCTION pricequote.single_price_call( CREATE OR REPLACE FUNCTION pricequote.single_price_call(
_bill TEXT, _bill TEXT,
_ship TEXT, _ship TEXT,
@ -57,21 +54,7 @@ RETURNS TABLE (
pltq NUMERIC, pltq NUMERIC,
plevel TEXT, plevel TEXT,
partgroup TEXT, partgroup TEXT,
part_v1ds TEXT, -- history JSONB,
v0ds TEXT,
curstd_orig NUMERIC,
futstd_orig NUMERIC,
curstd NUMERIC,
futstd NUMERIC,
curstd_last NUMERIC,
futstd_last NUMERIC,
customized TEXT,
last_premium NUMERIC,
last_premium_method TEXT,
last_price_norm NUMERIC,
last_isdiff TEXT,
last_v0ds TEXT,
tprice_last NUMERIC,
last_price NUMERIC, last_price NUMERIC,
last_qty NUMERIC, last_qty NUMERIC,
last_dataseg TEXT, last_dataseg TEXT,
@ -84,77 +67,45 @@ RETURNS TABLE (
volume_range TEXT, volume_range TEXT,
listprice NUMERIC, listprice NUMERIC,
listcode TEXT, listcode TEXT,
listprice_eff NUMERIC,
list_relevance TEXT,
guidance_price NUMERIC, guidance_price NUMERIC,
guidance_reason TEXT, guidance_reason TEXT,
expl JSONB, expl JSONB,
ui_json JSONB ui_json JSONB
) AS $$ ) AS $$
DECLARE DECLARE
-----------input parameters-------------- _pltq NUMERIC;
-- _bill
-- _ship
-- _part
-- _v1ds
-- _vol
------------step 1 lookup scenario------------
_chan TEXT; _chan TEXT;
_tier TEXT; _tier TEXT;
_cust TEXT; _cust TEXT;
_pltq NUMERIC;
_plevel TEXT; _plevel TEXT;
_partgroup TEXT; _partgroup TEXT;
_stlc TEXT; _stlc TEXT;
_part_v1ds TEXT;
_v0ds TEXT;
_curstd_orig NUMERIC;
_futstd_orig NUMERIC;
_calculated_pallets INT;
_exact_pallets NUMERIC;
_customized TEXT := '';
----------- step 2 last price------------------
_hist JSONB := '{}'::jsonb;
_last JSONB;
_last_price NUMERIC;
_last_source TEXT;
_last_date DATE;
_last_qty NUMERIC;
_last_dataseg TEXT;
_last_v0ds TEXT;
_last_order TEXT;
_last_quote TEXT;
_last_isdiff TEXT;
_last_part TEXT;
------------step 3 lookup target---------------
_tprice NUMERIC; _tprice NUMERIC;
_tmath JSONB; _tmath JSONB;
_volume_range TEXT; _volume_range TEXT;
_tprice_last NUMERIC;
------------step 4 normalize last price--------
_curstd NUMERIC;
_futstd NUMERIC;
_curstd_last NUMERIC;
_futstd_last NUMERIC;
_last_premium NUMERIC;
_last_price_norm NUMERIC;
_last_premium_method TEXT;
------------step 5 list price lookup-----------
_list_price NUMERIC; _list_price NUMERIC;
_list_code TEXT; _list_code TEXT;
_listprice_eff NUMERIC;
_list_relevance TEXT;
------------step 6 compute guidance------------
_guidance_price NUMERIC; _guidance_price NUMERIC;
_guidance_reason TEXT; _guidance_reason TEXT;
------------step 7 build json------------------ _hist JSONB := '{}'::jsonb;
-- No intermediate price history variables needed
-- Precedence chain
_last_price NUMERIC;
_last_qty NUMERIC;
_last_dataseg TEXT;
_last_date DATE;
_last_order TEXT;
_last_quote TEXT;
_last_source TEXT;
_expl JSONB := '{}'::jsonb; _expl JSONB := '{}'::jsonb;
_ui_json JSONB := '{}'::jsonb; _ui_json JSONB := '{}'::jsonb;
BEGIN BEGIN
------------------------------------------------------------------ ------------------------------------------------------------------
-- Step 1: Resolve customer metadata and part master data -- Step 1: Resolve customer metadata
------------------------------------------------------------------ ------------------------------------------------------------------
SELECT SELECT
i.mpck,
CASE SUBSTRING(bc.cclass, 2, 3) CASE SUBSTRING(bc.cclass, 2, 3)
WHEN 'DIS' THEN WHEN 'DIS' THEN
CASE SUBSTRING(sc.cclass, 2, 3) CASE SUBSTRING(sc.cclass, 2, 3)
@ -162,11 +113,11 @@ BEGIN
ELSE 'DRP' ELSE 'DRP'
END END
ELSE 'DIR' ELSE 'DIR'
END chan, END,
CASE SUBSTRING(bc.cclass, 2, 3) CASE SUBSTRING(bc.cclass, 2, 3)
WHEN 'DIR' THEN bc.tier WHEN 'DIR' THEN bc.tier
ELSE COALESCE(sc.tier, bc.tier) ELSE COALESCE(sc.tier, bc.tier)
END tier, END,
CASE SUBSTRING(bc.cclass, 2, 3) CASE SUBSTRING(bc.cclass, 2, 3)
WHEN 'DIS' THEN WHEN 'DIS' THEN
CASE SUBSTRING(sc.cclass, 2, 3) CASE SUBSTRING(sc.cclass, 2, 3)
@ -174,8 +125,7 @@ BEGIN
ELSE sc.dba ELSE sc.dba
END END
ELSE bc.dba ELSE bc.dba
END cust, END,
i.mpck,
CASE SUBSTRING(bc.cclass, 2, 3) CASE SUBSTRING(bc.cclass, 2, 3)
WHEN 'DIS' THEN WHEN 'DIS' THEN
CASE SUBSTRING(sc.cclass, 2, 3) CASE SUBSTRING(sc.cclass, 2, 3)
@ -183,264 +133,113 @@ BEGIN
ELSE bc.plevel ELSE bc.plevel
END END
ELSE bc.plevel ELSE bc.plevel
END plevel, END,
substring(_part,1,8) stlc,
i.partgroup, i.partgroup,
i.v1ds part_v1ds, substring(_part,1,8)
CASE substring(_v1ds,4,1) WHEN 'B' THEN 'B' ELSE 'C' END || CASE substring(_v1ds,6,1) WHEN 'L' THEN 'L' WHEN 'P' THEN 'P' ELSE '' END v0ds, INTO _pltq, _chan, _tier, _cust, _plevel, _partgroup, _stlc
i.curstdus, FROM rlarp.cust bc
i.futstdus, LEFT JOIN rlarp.cust sc ON sc.code = _ship
FLOOR(_vol / NULLIF(i.mpck, 0)), LEFT JOIN "CMS.CUSLG".itemm i ON i.item = _part
ROUND(_vol / NULLIF(i.mpck, 0), 5) WHERE bc.code = _bill;
INTO
_chan
,_tier
,_cust
,_pltq
,_plevel
,_stlc
,_partgroup
,_part_v1ds
,_v0ds
,_curstd_orig
,_futstd_orig
,_calculated_pallets
,_exact_pallets
FROM
rlarp.cust bc
LEFT JOIN rlarp.cust sc ON
sc.code = _ship
LEFT JOIN "CMS.CUSLG".itemm i ON
i.item = _part
WHERE
bc.code = _bill;
-- Customized flag
IF _part_v1ds IS NOT NULL AND _v1ds IS NOT NULL AND _part_v1ds <> _v1ds THEN
_customized := 'Customized';
END IF;
-- RAISE NOTICE 'Debug Inputs => stlc: "%", v1ds: "%", chan: "%", tier: "%", pallets: "%" , pltq: "%"',
-- _stlc, _v1ds, _chan, _tier, _calculated_pallets, _pltq;
--------------------------------------------------------------------------------
-- Step 3: Lookup Last Price
--------------------------------------------------------------------------------
SELECT
lp.part_stats
INTO
_hist
FROM
pricequote.lastpricedetail lp
WHERE
lp.customer = _cust
AND lp.partgroup = _partgroup;
_last := pricequote.pick_last_price_from_hist(_hist, _v1ds);
_last_price := (_last->>'price')::numeric;
_last_source := _last->>'source';
_last_date := (_last->>'odate')::date;
_last_qty := (_last->>'qty')::numeric;
_last_dataseg := _last->>'datasegment';
_last_v0ds :=
CASE substring(_last_dataseg,4,1) WHEN 'B' THEN 'B' ELSE 'C' END ||
CASE substring(_last_dataseg,6,1) WHEN 'L' THEN 'L' WHEN 'P' THEN 'P' ELSE '' END;
_last_order := _last->>'ordnum';
_last_quote := _last->>'quoten';
IF _last_dataseg IS NOT NULL AND _v1ds IS NOT NULL AND _last_dataseg <> _v1ds THEN
_last_isdiff := 'Last Sale Diff Part';
END IF;
_last_part := _last->>'part';
------------------------------------------------------------------ ------------------------------------------------------------------
-- Step 2: Target price logic (current and for last_dataseg) -- Step 2: Target price logic
------------------------------------------------------------------ ------------------------------------------------------------------
SELECT SELECT tp.price,
tp.price to_json(tp.math),
,to_json(tp.math) tp.vol::text
,tp.vol::text INTO _tprice, _tmath, _volume_range
INTO FROM pricequote.target_prices tp
_tprice WHERE tp.stlc = _stlc
,_tmath
,_volume_range
FROM
pricequote.target_prices tp
WHERE
tp.stlc = _stlc
AND tp.ds = _v1ds AND tp.ds = _v1ds
AND tp.chan = _chan AND tp.chan = _chan
AND tp.tier = _tier AND tp.tier = _tier
AND tp.vol @> _calculated_pallets;
-- RAISE NOTICE 'Debug: tprice=%, tmath=%, volume_range=%',
-- _tprice, _tmath, _volume_range;
-- Target price for last_dataseg
SELECT
tp.price
INTO
_tprice_last
FROM
pricequote.target_prices tp
WHERE
tp.stlc = _stlc
AND tp.ds = _last_dataseg
AND tp.chan = _chan
AND tp.tier = _tier
AND FLOOR(_vol / NULLIF(_pltq, 0))::int <@ tp.vol; AND FLOOR(_vol / NULLIF(_pltq, 0))::int <@ tp.vol;
------------------------------------------------------------------ ------------------------------------------------------------------
-- Step 4: Cost data for normalization -- Step 3: Last sale/quote/volume/segment data
------------------------------------------------------------------ ------------------------------------------------------------------
-- Current/future standard for requested v1ds SELECT
SELECT lp.part_stats
curstdus, futstdus INTO
INTO _hist
_curstd, _futstd FROM pricequote.lastpricedetail lp
FROM WHERE lp.customer = _cust
"CMS.CUSLG".itemm i AND lp.partgroup = _partgroup;
WHERE
i.item = _part
AND i.v1ds = _v1ds;
-- Current/future standard for last_dataseg -- No extraction of price history keys needed; handled in helper
SELECT
curstdus, futstdus -- Use helper function to select the best last price point and extract attributes
INTO DECLARE
_curstd_last, _futstd_last _last JSONB;
FROM BEGIN
"CMS.CUSLG".itemm i _last := pricequote.pick_last_price_from_hist(_hist, _v1ds);
WHERE _last_price := (_last->>'price')::numeric;
i.item = _part _last_qty := (_last->>'qty')::numeric;
AND i.v1ds = _last_dataseg; _last_dataseg := _last->>'datasegment';
_last_date := (_last->>'odate')::date;
_last_order := _last->>'ordnum';
_last_quote := _last->>'quoten';
_last_source := _last->>'source';
END;
------------------------------------------------------------------ ------------------------------------------------------------------
-- Step 5: Normalize last price if needed -- Step 4: List price
------------------------------------------------------------------
IF _last_isdiff IS NOT NULL THEN
IF _tprice_last IS NOT NULL AND _tprice IS NOT NULL AND _tprice_last <> 0 THEN
_last_premium := ROUND(_tprice / _tprice_last,5);
_last_price_norm := ROUND(_last_price * (_tprice / _tprice_last), 5);
_last_premium_method := 'Target Price Ratio';
ELSIF _curstd_last IS NOT NULL AND _curstd IS NOT NULL AND _curstd_last <> 0 THEN
_last_premium := _curstd / _curstd_last;
_last_price_norm := ROUND(_last_price * (_curstd / _curstd_last), 5);
_last_premium_method := 'Cost Ratio';
ELSE
_last_price_norm := _last_price;
_last_premium_method := 'Unknown';
END IF;
ELSE
_last_price_norm := _last_price;
END IF;
------------------------------------------------------------------
-- Step 6: List price logic
------------------------------------------------------------------ ------------------------------------------------------------------
SELECT SELECT
pr.price::numeric(20,5) pr.price::numeric(20,5), pr.jcplcd
,pr.jcplcd
INTO INTO
_list_price _list_price, _list_code
,_list_code
FROM FROM
"CMS.CUSLG".IPRCBHC i "CMS.CUSLG".IPRCBHC i
JOIN pricequote.pricelist_ranged pr ON JOIN pricequote.pricelist_ranged pr
pr.jcplcd = TRIM(i.jbplcd) ON pr.jcplcd = TRIM(i.jbplcd)
AND pr.jcpart = _part AND pr.jcpart = _part
AND _vol >= pr.vb_from AND _vol >= pr.vb_from
AND (_vol < pr.vb_to OR pr.vb_to IS NULL) AND (_vol < pr.vb_to OR pr.vb_to IS NULL)
WHERE WHERE TRIM(i.jbplvl) = TRIM(_plevel)
TRIM(i.jbplvl) = TRIM(_plevel) AND CURRENT_DATE BETWEEN i.jbfdat AND i.jbtdat
AND CURRENT_DATE BETWEEN i.jbfdat AND i.jbtdat ORDER BY pr.price ASC
ORDER BY
pr.price ASC
LIMIT 1; LIMIT 1;
-- List price relevance
IF _customized <> '' THEN
_listprice_eff := NULL;
_list_relevance := 'Ignore - Customized';
ELSE
_listprice_eff := _list_price;
_list_relevance := '';
END IF;
------------------------------------------------------------------ ------------------------------------------------------------------
-- Step 7: Compute guidance price and embed it -- Step 5: Compute guidance price and embed it
------------------------------------------------------------------ ------------------------------------------------------------------
SELECT SELECT
gl.guidance_price gl.guidance_price, gl.guidance_reason
,gl.guidance_reason
INTO INTO
_guidance_price _guidance_price, _guidance_reason
,_guidance_reason FROM
FROM pricequote.guidance_logic(_tprice, _last_price_norm, _listprice_eff, _last_date) gl; pricequote.guidance_logic(_tprice, _last_price, _list_price, _last_date) gl;
------------------------------------------------------------------ ------------------------------------------------------------------
-- Step 8: Build explanation JSON -- Step 6: Build explanation JSON
------------------------------------------------------------------ ------------------------------------------------------------------
_expl := _expl := jsonb_build_object(
jsonb_build_object( 'last_price', _last_price,
'last', 'last_qty', _last_qty,
jsonb_build_object( 'last_dataseg', _last_dataseg,
'last_part', _last_part, 'last_source', _last_source,
'last_price', _last_price, 'last_date', _last_date,
'last_qty', _last_qty, 'last_order', _last_order,
'last_dataseg', _last_dataseg, 'last_quote', _last_quote,
'last_v0ds', _last_v0ds, 'target_price', _tprice,
'last_source', _last_source, 'target_math', _tmath,
'last_date', _last_date, 'calculated_pallets', FLOOR(_vol / NULLIF(_pltq, 0)),
'last_order', _last_order, 'exact_pallets', ROUND(_vol / NULLIF(_pltq, 0), 5),
'last_quote', _last_quote, 'customer', _cust,
'last_isdiff', _last_isdiff, 'channel', _chan,
'last_premium', _last_premium, 'tier', TRIM(_tier),
'last_premium_method', _last_premium_method, 'list_price', _list_price,
'last_price_norm', _last_price_norm, 'list_code', _list_code,
'tprice_last', _tprice_last
),
'scenario',
jsonb_build_object(
'calculated_pallets', FLOOR(_vol / NULLIF(_pltq, 0)),
'exact_pallets', ROUND(_vol / NULLIF(_pltq, 0), 5),
'customer', _cust,
'channel', _chan,
'tier', TRIM(_tier),
'v1ds', _v1ds,
'v0ds', _v0ds,
'part_v1ds', _part_v1ds,
'customized', _customized
),
'cost',
jsonb_build_object(
'curstd_orig', _curstd_orig,
'futstd_orig', _futstd_orig,
'curstd_last', _curstd_last,
'futstd_last', _futstd_last,
'curstd', _curstd,
'futstd', _futstd
),
'targets',
jsonb_build_object(
'target_price', _tprice,
'target_math', _tmath
),
'list',
jsonb_build_object(
'listcode', _list_code,
'listprice', _list_price,
'listprice_eff', _listprice_eff,
'list_relevance', _list_relevance
),
'guidance_price', _guidance_price, 'guidance_price', _guidance_price,
'guidance_reason', _guidance_reason 'guidance_reason', _guidance_reason
); );
------------------------------------------------------------------ ------------------------------------------------------------------
-- Step 9: Build UI JSON (panels) -- Step 7: Build UI JSON (optional, similar to MSSQL)
------------------------------------------------------------------ ------------------------------------------------------------------
_ui_json := jsonb_build_object( _ui_json := jsonb_build_object(
'details', jsonb_build_array( 'details', jsonb_build_array(
jsonb_build_object( jsonb_build_object(
'label', 'History', 'label', 'History',
@ -462,13 +261,13 @@ BEGIN
'label', 'List:' || COALESCE(_list_code, ''), 'label', 'List:' || COALESCE(_list_code, ''),
'value', _list_price, 'value', _list_price,
'type', 'currency', 'type', 'currency',
'note', _list_relevance 'note', _plevel
) )
) )
), ),
jsonb_build_object( jsonb_build_object(
'label', 'Target Support', 'label', 'Target Support',
'details', _tmath 'details', _tmath -- You may need to transform this to match the MSSQL panel
), ),
jsonb_build_object( jsonb_build_object(
'label', 'Guidance', 'label', 'Guidance',
@ -491,12 +290,11 @@ BEGIN
RETURN QUERY RETURN QUERY
SELECT SELECT
_bill, _ship, _part, _stlc, _v1ds, _vol, _bill, _ship, _part, _stlc, _v1ds, _vol,
_chan, _cust, _tier, _pltq, _plevel, _partgroup, _part_v1ds, _v0ds, _chan, _cust, _tier, _pltq, _plevel, _partgroup,
_curstd_orig, _futstd_orig, _curstd, _futstd, _curstd_last, _futstd_last, -- _hist,
_customized, _last_premium, _last_premium_method, _last_price_norm, _last_isdiff, _last_v0ds, _tprice_last,
_last_price, _last_qty, _last_dataseg, _last_date, _last_order, _last_quote, _last_source, _last_price, _last_qty, _last_dataseg, _last_date, _last_order, _last_quote, _last_source,
_tprice, _tmath, _volume_range, _tprice, _tmath, _volume_range,
_list_price, _list_code, _listprice_eff, _list_relevance, _list_price, _list_code,
_guidance_price, _guidance_reason, _guidance_price, _guidance_reason,
_expl, _ui_json; _expl, _ui_json;
END; END;