Compare commits

..

No commits in common. "af5e4d202bd95f549892b32f1c09653ca40e7945" and "8675120993bd674d902e6753c85dbf81b717e57a" have entirely different histories.

3 changed files with 403 additions and 282 deletions

View File

@ -0,0 +1,76 @@
DELETE FROM pricing.price_queue;
INSERT INTO pricing.price_queue (bill, ship, part, stlc, v1ds, vol) SELECT 'GRIF0001','GRIF0001','XNS0T1G3G18B096','XNS0T1G3','v1:L..PLT..',9600;
SELECT * FROM pricing.price_queue
EXEC pricing.process_queue
EXEC pricing.single_price_call
@bill = 'GRIF0001',
@ship = 'GRIF0001',
@part = 'XNS0T1G3G18B096',
@v1ds = 'v1:B..PLT..',
@vol = 9600;
SELECT * FROM pricing.pick
SELECT * FROM FAnalysis.PRICING.lastpricedetail l OUTER apply pricing.pick_last_price_from_hist_json (part_stats,'v1:B..PLT..') x WHERE customer = 'GRIFFIN' AND partgroup = 'XNS0T1G3'
SELECT
*
FROM pricing.single_price_call_fn(
'GRIF0001',
'GRIF0001',
'XNS0T1G3G18B096',
'XNS0T1G3',
'v1:B..PLT..',
9600
) f
SELECT * INTO #result FROM pricing.price_queue WHERE 0=1
INSERT INTO #result
EXEC pricing.single_price_call_nowrite
@bill = 'GRIF0001',
@ship = 'JRSG0001',
@part = 'XNS0T1G3G18B096',
@stlc = 'XNS0T1G3',
@v1ds = 'v1:T..PLT..',
@vol = 19200;
SELECT * FROM #RESULT
SELECT
q.qid,
q.qrn,
q.qcustomer,
q.part,
q.v1ds,
q.units_each,
q.price,
q.targetp,
q.lastsalesprice,
q.finalrecommendedprice,
q.lowerpricelimit,
q.upperpricelimit,
q.curstdus,
p.price guidance,
p.expl
FROM
rlarp.live_quotes q
OUTER APPLY pricing.single_price_call_fn(
q.billto
,q.shipto
,q.part
,substring(q.part,1,8)
,q.v1ds
,q.units_each
) p
WHERE
qstat LIKE 'Submitted%'

View File

@ -0,0 +1,52 @@
SELECT * FROM
pricequote.single_price_call(
'GRIF0001' ,
'GRIF0001' ,
'XNS0T1G3G18B096' ,
'v1:B..PLT..',
9600
)
SELECT pricing FROM rlarp.osm_stack l WHERE l.customer ='CROS-B-CREST FARM' AND partgroup = 'STG04250'
SELECT * FROM pricequote.lastpricedetail l LEFT JOIN lateral pricequote.pick_last_price_from_hist (part_stats,'v1:B..PLT..') x ON TRUE WHERE customer = 'GRIFFIN' AND partgroup = 'XNS0T1G3'
CALL pricequote.process_queue()
REFRESH MATERIALIZED VIEW rlarp.osm_stack_pretty;
SELECT
q.qid,
q.qrn,
-- q.qcustomer,
q.partbuilt,
i.pricegroup,
q.v1ds,
q.units_each,
q.targetp,
q.lastsalesprice,
-- q.finalrecommendedprice,
-- q.lowerpricelimit,
-- q.upperpricelimit,
q.curstdus,
q.price,
p.guidance_price guidance,
p.expl
FROM
pricequote.live_quotes q
LEFT OUTER JOIN "CMS.CUSLG".itemm i ON
i.item = q.part
LEFT JOIN LATERAL pricequote.single_price_call(
q.billto
,q.shipto
,q.part
,q.v1ds
,q.units_each
) p ON TRUE
WHERE
-- qstat LIKE 'Submitted%'
qid = 111832 --AND q.qrn = 1
ORDER BY
qrn ASC

View File

@ -1,230 +1,228 @@
DROP FUNCTION IF EXISTS pricing.single_price_call_fn; DROP FUNCTION pricing.single_price_call_fn;
GO
CREATE FUNCTION pricing.single_price_call_fn ( CREATE FUNCTION pricing.single_price_call_fn (
@bill VARCHAR(100), @bill VARCHAR(100),
@ship VARCHAR(100), @ship VARCHAR(100),
@part VARCHAR(100), @part VARCHAR(100),
@v1ds VARCHAR(100), @v1ds VARCHAR(100),
@vol NUMERIC(18,6) @vol NUMERIC(18,6)
) )
RETURNS @queue TABLE ( RETURNS @queue TABLE (
bill VARCHAR(100), bill VARCHAR(100),
ship VARCHAR(100), ship VARCHAR(100),
part VARCHAR(100), part VARCHAR(100),
stlc VARCHAR(100), stlc VARCHAR(100),
v1ds VARCHAR(100), v1ds VARCHAR(100),
vol NUMERIC(18,6), vol NUMERIC(18,6),
chan VARCHAR(50), chan VARCHAR(50),
cust VARCHAR(100), cust VARCHAR(100),
tier VARCHAR(50), tier VARCHAR(50),
pltq NUMERIC(18,6), pltq NUMERIC(18,6),
volume_range TEXT, volume_range TEXT,
plevel NVARCHAR(20), plevel NVARCHAR(20),
listprice NUMERIC(20,5), listprice NUMERIC(20,5),
listcode VARCHAR(10), listcode VARCHAR(10),
hist NVARCHAR(MAX), hist NVARCHAR(MAX),
last_price NUMERIC(20,5), last_price NUMERIC(20,5),
last_date DATE, last_date DATE,
last_order NVARCHAR(10), last_order NVARCHAR(10),
last_quote NVARCHAR(10), last_quote NVARCHAR(10),
tprice 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), expl NVARCHAR(MAX),
expl NVARCHAR(MAX), ui_json NVARCHAR(MAX)
ui_json NVARCHAR(MAX),
partgroup VARCHAR(100)
) )
AS AS
BEGIN BEGIN
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Step 1: Seed the queue with input row -- Step 1: Seed the queue with input row
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
INSERT INTO @queue (bill, ship, part, v1ds, vol, expl) INSERT INTO @queue (bill, ship, part, v1ds, vol, expl)
VALUES (@bill, @ship, @part, @v1ds, @vol, '{}'); VALUES (@bill, @ship, @part, @v1ds, @vol, '{}');
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Step 2: Enrich with channel, tier, customer, pack quantity, and price level -- Step 2: Enrich with channel, tier, customer, pack quantity, and price level
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
UPDATE q UPDATE q
SET SET
chan = chan =
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)
WHEN 'DIS' THEN 'WHS' WHEN 'DIS' THEN 'WHS'
ELSE 'DRP' ELSE 'DRP'
END END
ELSE 'DIR' ELSE 'DIR'
END, END,
tier = tier =
CASE SUBSTRING(bc.cclass, 2, 3) CASE SUBSTRING(bc.cclass, 2, 3)
WHEN 'DIR' THEN bc.tier WHEN 'DIR' THEN bc.tier
ELSE ISNULL(sc.tier, bc.tier) ELSE ISNULL(sc.tier, bc.tier)
END, END,
cust = cust =
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)
WHEN 'DIS' THEN bc.dba WHEN 'DIS' THEN bc.dba
ELSE sc.dba ELSE sc.dba
END END
ELSE q.bill ELSE q.bill
END, END,
pltq = i.mpck, pltq = i.mpck,
plevel = plevel =
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)
WHEN 'DIS' THEN sc.plevel WHEN 'DIS' THEN sc.plevel
ELSE bc.plevel ELSE bc.plevel
END END
ELSE bc.plevel ELSE bc.plevel
END, END,
stlc = substring(q.part,1,8), stlc = substring(q.part,1,8)
partgroup = i.partgroup 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 LEFT JOIN CMSInterfaceIn.[CMS.CUSLG].itemm i ON i.item = q.part;
LEFT JOIN CMSInterfaceIn.[CMS.CUSLG].itemm i ON i.item = q.part;
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Step 3: Apply target price and embed metadata as JSON -- Step 3: Apply target price and embed metadata as JSON
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
UPDATE q UPDATE q
SET SET
tprice = tp.price tprice = tp.price,
,tmath = JSON_QUERY(tp.math) expl = (
,volume_range = CONCAT(tp.lower_bound, '-', ISNULL(CAST(tp.upper_bound AS VARCHAR), '')) SELECT
FROM @queue q 'target price' AS [source],
INNER JOIN pricing.target_prices tp ON tp.price AS [target_price],
q.stlc = tp.stlc FLOOR(q.vol / NULLIF(q.pltq, 0)) AS [calculated_pallets],
AND q.v1ds = tp.ds CAST(ROUND(q.vol / NULLIF(q.pltq, 0), 5) AS NUMERIC(20,5)) AS [exact_pallets],
AND q.chan = tp.chan CONCAT(tp.lower_bound, '-', ISNULL(CAST(tp.upper_bound AS VARCHAR), '')) AS [volume_range],
AND q.tier = tp.tier q.cust AS [customer],
AND FLOOR(q.vol / NULLIF(q.pltq, 0)) >= tp.lower_bound q.chan AS [channel],
AND ( TRIM(q.tier) AS [tier],
tp.upper_bound IS NULL OR FLOOR(q.vol / NULLIF(q.pltq, 0)) < tp.upper_bound JSON_QUERY(tp.math) AS [target_math]
); FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
),
volume_range = CONCAT(tp.lower_bound, '-', ISNULL(CAST(tp.upper_bound AS VARCHAR), ''))
FROM @queue q
INNER JOIN pricing.target_prices tp ON
q.stlc = tp.stlc
AND q.v1ds = tp.ds
AND q.chan = tp.chan
AND q.tier = tp.tier
AND FLOOR(q.vol / NULLIF(q.pltq, 0)) >= tp.lower_bound
AND (
tp.upper_bound IS NULL OR FLOOR(q.vol / NULLIF(q.pltq, 0)) < tp.upper_bound
);
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Step 4: Pull last sale data and embed in columns and JSON -- Step 4: Pull last sale data and embed in columns and JSON
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
UPDATE q UPDATE q
SET SET
hist = lp.part_stats hist = JSON_MODIFY('{}', '$.full_history', JSON_QUERY(lp.part_stats)),
FROM @queue q last_price = j.price,
JOIN pricing.lastpricedetail lp last_date = j.odate,
ON lp.customer = q.cust AND lp.partgroup = q.partgroup; last_order = j.ordnum,
last_quote = j.quoten,
expl = JSON_MODIFY(
JSON_MODIFY(
JSON_MODIFY(
JSON_MODIFY(
ISNULL(q.expl, '{}'),
'$.last_price', j.price
),
'$.last_date', CONVERT(NVARCHAR(10), j.odate, 23)
),
'$.last_order', j.ordnum
),
'$.last_quote', j.quoten
)
FROM @queue q
JOIN pricing.lastprice lp
ON lp.customer = q.cust
AND lp.mold = SUBSTRING(q.part, 1, 8)
OUTER APPLY (
SELECT TOP 1 *
FROM OPENJSON(lp.part_stats) AS p
OUTER APPLY OPENJSON(p.value)
WITH (
qty NUMERIC(20,5),
price NUMERIC(20,5),
odate DATE,
ordnum INT,
quoten INT
) AS j
WHERE p.[key] COLLATE SQL_Latin1_General_CP1_CI_AS = q.part
ORDER BY j.odate DESC
) AS j;
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Step 4b.1: Populate composite fields from precedence chain using JSON-based helper -- Step 5: Add list price info from external pricelist
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Use new helper to select best last price, source, and date directly from JSON WITH ranked_prices AS (
UPDATE q SELECT
SET q.bill, q.ship, q.part, q.stlc, q.v1ds, q.vol,
last_price = b.price, CAST(p.price AS NUMERIC(20,5)) AS price,
last_source = b.source, p.jcplcd,
last_date = b.odate, ROW_NUMBER() OVER (
last_qty = b.qty, PARTITION BY q.bill, q.ship, q.part, q.stlc, q.v1ds, q.vol
last_dataseg = b.dataseg, ORDER BY p.price ASC
last_order = b.ord, ) AS rn
last_quote = b.quote FROM @queue q
FROM @queue q INNER JOIN CMSInterfaceIn."CMS.CUSLG".IPRCBHC i
CROSS APPLY ( ON TRIM(i.jbplvl) = TRIM(q.plevel)
SELECT TOP 1 price, source, odate, qty, dataseg, ord, quote AND CAST(GETDATE() AS DATE) BETWEEN i.jbfdat AND i.jbtdat
FROM pricing.pick_last_price_from_hist_json(q.hist, q.v1ds) INNER JOIN pricing.pricelist_ranged p
) b; ON p.jcplcd = TRIM(i.jbplcd)
AND p.jcpart = q.part
-------------------------------------------------------------------------------- AND q.vol >= p.vb_from
-- Step 4b.2: Build JSON explanation object from populated columns AND (p.vb_to IS NULL OR q.vol < p.vb_to)
-------------------------------------------------------------------------------- )
UPDATE q UPDATE q
SET expl = ( SET expl = JSON_MODIFY(
SELECT JSON_MODIFY(
q.last_price AS last_price, ISNULL(q.expl, '{}'),
q.last_qty AS last_qty, '$.list_price', rp.price
q.last_dataseg AS last_dataseg, ),
q.last_source AS last_source, '$.list_code', rp.jcplcd
FORMAT(q.last_date, 'yyyy-MM-dd') AS last_date, )
q.tprice AS [target_price], ,listcode = rp.jcplcd
JSON_QUERY(q.tmath) AS [target_math], ,listprice = rp.price
FLOOR(q.vol / NULLIF(q.pltq, 0)) AS [calculated_pallets], FROM @queue q
CAST(ROUND(q.vol / NULLIF(q.pltq, 0), 5) AS NUMERIC(20,5)) AS [exact_pallets], JOIN ranked_prices rp
q.cust AS [customer], ON q.bill = rp.bill
q.chan AS [channel], AND q.ship = rp.ship
TRIM(q.tier) AS [tier] AND q.part = rp.part
-- JSON_QUERY(hist) AS [history] AND q.stlc = rp.stlc
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER AND q.v1ds = rp.v1ds
) AND q.vol = rp.vol
FROM @queue q; AND rp.rn = 1;
--------------------------------------------------------------------------------
-- Step 5: Add list price info from external pricelist
--------------------------------------------------------------------------------
WITH ranked_prices AS (
SELECT
q.bill, q.ship, q.part, q.stlc, q.v1ds, q.vol,
CAST(p.price AS NUMERIC(20,5)) AS price,
p.jcplcd,
ROW_NUMBER() OVER (
PARTITION BY q.bill, q.ship, q.part, q.stlc, q.v1ds, q.vol
ORDER BY p.price ASC
) AS rn
FROM @queue q
INNER JOIN CMSInterfaceIn."CMS.CUSLG".IPRCBHC i
ON TRIM(i.jbplvl) = TRIM(q.plevel)
AND CAST(GETDATE() AS DATE) BETWEEN i.jbfdat AND i.jbtdat
INNER JOIN pricing.pricelist_ranged p
ON p.jcplcd = TRIM(i.jbplcd)
AND p.jcpart = q.part
AND q.vol >= p.vb_from
AND (p.vb_to IS NULL OR q.vol < p.vb_to)
)
UPDATE q
SET expl = JSON_MODIFY(
JSON_MODIFY(
ISNULL(q.expl, '{}'),
'$.list_price', rp.price
),
'$.list_code', rp.jcplcd
)
,listcode = rp.jcplcd
,listprice = rp.price
FROM @queue q
JOIN ranked_prices rp
ON q.bill = rp.bill
AND q.ship = rp.ship
AND q.part = rp.part
AND q.stlc = rp.stlc
AND q.v1ds = rp.v1ds
AND q.vol = rp.vol
AND rp.rn = 1;
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Step 6: Compute guidance price and logic, and embed in JSON -- Step 6: Compute guidance price and logic, and embed in JSON
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
UPDATE q UPDATE q
SET SET
guidance_price = g.guidance_price, guidance_price = g.guidance_price,
guidance_reason = g.guidance_reason, guidance_reason = g.guidance_reason,
expl = JSON_MODIFY( expl = JSON_MODIFY(
JSON_MODIFY( JSON_MODIFY(
ISNULL(q.expl, '{}'), ISNULL(q.expl, '{}'),
'$.guidance_reason', '$.guidance_reason',
g.guidance_reason g.guidance_reason
), ),
'$.guidance_price', '$.guidance_price',
g.guidance_price g.guidance_price
) )
FROM @queue q FROM @queue q
CROSS APPLY pricing.guidance_logic( CROSS APPLY pricing.guidance_logic(
CAST(JSON_VALUE(q.expl, '$.target_price') AS NUMERIC(20,5)), CAST(JSON_VALUE(q.expl, '$.target_price') AS NUMERIC(20,5)),
CAST(JSON_VALUE(q.expl, '$.last_price') AS NUMERIC(20,5)), CAST(JSON_VALUE(q.expl, '$.last_price') AS NUMERIC(20,5)),
CAST(JSON_VALUE(q.expl, '$.list_price') AS NUMERIC(20,5)), CAST(JSON_VALUE(q.expl, '$.list_price') AS NUMERIC(20,5)),
CAST(last_date AS DATE) CAST(JSON_VALUE(q.expl, '$.last_date') AS DATE)
) g; ) g;
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -232,84 +230,79 @@ BEGIN
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
UPDATE q UPDATE q
SET ui_json = ( SET ui_json = (
SELECT SELECT
( panel.label,
SELECT JSON_QUERY(panel.details) AS details
panel.label, FROM (
JSON_QUERY(panel.details) AS details -- History Panel
FROM ( SELECT
-- History Panel 'History' AS label,
SELECT (
'History' AS label, SELECT
( 'Last Sale: ' + CAST(q.last_date AS varchar(10)) AS label,
SELECT q.last_price AS value,
'Last Price' AS label, 'currency' AS type,
q.last_price AS value, 'Ord# ' + q.last_order AS note
'currency' AS type, FOR JSON PATH
CONCAT( ) AS details
'Source: ', ISNULL(q.last_source, 'N/A'),
' | Date: ', ISNULL(CONVERT(varchar(10), q.last_date, 120), 'N/A'),
' | Order: ', ISNULL(q.last_order, 'N/A'),
' | Quote: ', ISNULL(q.last_quote, 'N/A'),
' | Dataseg: ', ISNULL(q.last_dataseg, 'N/A'),
' | Qty: ', ISNULL(CAST(q.last_qty AS varchar(32)), 'N/A')
) AS note
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
) AS details
UNION ALL UNION ALL
-- List Panel -- List Panel
SELECT SELECT
'List' AS label, 'List' AS label,
( (
SELECT SELECT
'List:' + q.listcode AS label, 'List:' + q.listcode AS label,
q.listprice AS value, q.listprice AS value,
'currency' AS type, 'currency' AS type,
q.plevel AS note q.plevel AS note
FOR JSON PATH FOR JSON PATH
) )
UNION ALL UNION ALL
-- Target Support Panel -- Target Support Panel
SELECT SELECT
'Target Support' AS label, 'Target Support' AS label,
( (
SELECT SELECT
RTRIM(SUBSTRING(value,1,18)) AS label, -- parse each item in target_math
TRY_CAST(SUBSTRING(value,23,7) AS NUMERIC(20,5)) RTRIM(SUBSTRING(value,1,18)) label,
+ CASE SUBSTRING(value,19,1) WHEN '+' THEN 0 ELSE -1 END AS value, 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 'currency' ELSE 'percentage' 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 SUBSTRING(value,19,1) AS note
FROM OPENJSON(q.expl, '$.target_math') FROM OPENJSON(q.expl, '$.target_math')
WITH (value NVARCHAR(MAX) '$') WITH (value NVARCHAR(MAX) '$')
FOR JSON PATH FOR JSON PATH
) AS details ) AS details
UNION ALL UNION ALL
-- Guidance Panel -- Guidance Panel
SELECT SELECT
'Guidance' AS label, 'Guidance' AS label,
( (
SELECT SELECT
'Price' AS label, 'Last Price Capped' AS label,
q.guidance_price AS value, q.guidance_price AS value,
'currency' AS type, 'currency' AS type,
q.guidance_reason AS note CONCAT(
FOR JSON PATH 'Last price ', q.last_price,
) ' capped at ',
) AS panel ROUND((q.last_price - q.guidance_price) / NULLIF(q.last_price, 0) * 100, 2),
FOR JSON PATH '%'
) AS details, ) AS note
JSON_QUERY(q.expl) AS data -- 👈 adds the full expl content as a JSON object FOR JSON PATH
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER -- 👈 make it a single JSON object )
) AS panel
FOR JSON PATH, ROOT('details')
) )
FROM @queue q; FROM @queue q;
--------------------------------------------------------------------------------
-- Final: Return the enriched result row
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
RETURN; -- Final: Return the enriched result row
--------------------------------------------------------------------------------
RETURN;
END; END;