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(
-- Step 4b.1: Populate composite fields from precedence chain using JSON-based helper JSON_MODIFY(
-------------------------------------------------------------------------------- JSON_MODIFY(
-- Use new helper to select best last price, source, and date directly from JSON JSON_MODIFY(
UPDATE q ISNULL(q.expl, '{}'),
SET '$.last_price', j.price
last_price = b.price, ),
last_source = b.source, '$.last_date', CONVERT(NVARCHAR(10), j.odate, 23)
last_date = b.odate, ),
last_qty = b.qty, '$.last_order', j.ordnum
last_dataseg = b.dataseg, ),
last_order = b.ord, '$.last_quote', j.quoten
last_quote = b.quote )
FROM @queue q FROM @queue q
CROSS APPLY ( JOIN pricing.lastprice lp
SELECT TOP 1 price, source, odate, qty, dataseg, ord, quote ON lp.customer = q.cust
FROM pricing.pick_last_price_from_hist_json(q.hist, q.v1ds) AND lp.mold = SUBSTRING(q.part, 1, 8)
) b; OUTER APPLY (
SELECT TOP 1 *
-------------------------------------------------------------------------------- FROM OPENJSON(lp.part_stats) AS p
-- Step 4b.2: Build JSON explanation object from populated columns OUTER APPLY OPENJSON(p.value)
-------------------------------------------------------------------------------- WITH (
UPDATE q qty NUMERIC(20,5),
SET expl = ( price NUMERIC(20,5),
SELECT odate DATE,
q.last_price AS last_price, ordnum INT,
q.last_qty AS last_qty, quoten INT
q.last_dataseg AS last_dataseg, ) AS j
q.last_source AS last_source, WHERE p.[key] COLLATE SQL_Latin1_General_CP1_CI_AS = q.part
FORMAT(q.last_date, 'yyyy-MM-dd') AS last_date, ORDER BY j.odate DESC
q.tprice AS [target_price], ) AS j;
JSON_QUERY(q.tmath) AS [target_math],
FLOOR(q.vol / NULLIF(q.pltq, 0)) AS [calculated_pallets],
CAST(ROUND(q.vol / NULLIF(q.pltq, 0), 5) AS NUMERIC(20,5)) AS [exact_pallets],
q.cust AS [customer],
q.chan AS [channel],
TRIM(q.tier) AS [tier]
-- JSON_QUERY(hist) AS [history]
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
)
FROM @queue q;
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Step 5: Add list price info from external pricelist -- Step 5: Add list price info from external pricelist
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
WITH ranked_prices AS ( WITH ranked_prices AS (
SELECT SELECT
q.bill, q.ship, q.part, q.stlc, q.v1ds, q.vol, q.bill, q.ship, q.part, q.stlc, q.v1ds, q.vol,
CAST(p.price AS NUMERIC(20,5)) AS price, CAST(p.price AS NUMERIC(20,5)) AS price,
p.jcplcd, p.jcplcd,
ROW_NUMBER() OVER ( ROW_NUMBER() OVER (
PARTITION BY q.bill, q.ship, q.part, q.stlc, q.v1ds, q.vol PARTITION BY q.bill, q.ship, q.part, q.stlc, q.v1ds, q.vol
ORDER BY p.price ASC ORDER BY p.price ASC
) AS rn ) AS rn
FROM @queue q FROM @queue q
INNER JOIN CMSInterfaceIn."CMS.CUSLG".IPRCBHC i INNER JOIN CMSInterfaceIn."CMS.CUSLG".IPRCBHC i
ON TRIM(i.jbplvl) = TRIM(q.plevel) ON TRIM(i.jbplvl) = TRIM(q.plevel)
AND CAST(GETDATE() AS DATE) BETWEEN i.jbfdat AND i.jbtdat AND CAST(GETDATE() AS DATE) BETWEEN i.jbfdat AND i.jbtdat
INNER JOIN pricing.pricelist_ranged p INNER JOIN pricing.pricelist_ranged p
ON p.jcplcd = TRIM(i.jbplcd) ON p.jcplcd = TRIM(i.jbplcd)
AND p.jcpart = q.part AND p.jcpart = q.part
AND q.vol >= p.vb_from AND q.vol >= p.vb_from
AND (p.vb_to IS NULL OR q.vol < p.vb_to) AND (p.vb_to IS NULL OR q.vol < p.vb_to)
) )
UPDATE q UPDATE q
SET expl = JSON_MODIFY( SET expl = JSON_MODIFY(
JSON_MODIFY( JSON_MODIFY(
ISNULL(q.expl, '{}'), ISNULL(q.expl, '{}'),
'$.list_price', rp.price '$.list_price', rp.price
), ),
'$.list_code', rp.jcplcd '$.list_code', rp.jcplcd
) )
,listcode = rp.jcplcd ,listcode = rp.jcplcd
,listprice = rp.price ,listprice = rp.price
FROM @queue q FROM @queue q
JOIN ranked_prices rp JOIN ranked_prices rp
ON q.bill = rp.bill ON q.bill = rp.bill
AND q.ship = rp.ship AND q.ship = rp.ship
AND q.part = rp.part AND q.part = rp.part
AND q.stlc = rp.stlc AND q.stlc = rp.stlc
AND q.v1ds = rp.v1ds AND q.v1ds = rp.v1ds
AND q.vol = rp.vol AND q.vol = rp.vol
AND rp.rn = 1; 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
SELECT
'Target Support' AS label,
(
SELECT
-- parse each item in target_math
RTRIM(SUBSTRING(value,1,18)) label,
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,
SUBSTRING(value,19,1) AS note
FROM OPENJSON(q.expl, '$.target_math')
WITH (value NVARCHAR(MAX) '$')
FOR JSON PATH
) AS details
-- Target Support Panel UNION ALL
SELECT
'Target Support' AS label,
(
SELECT
RTRIM(SUBSTRING(value,1,18)) AS label,
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 'Price' ELSE 'Premium' END AS note
FROM OPENJSON(q.expl, '$.target_math')
WITH (value NVARCHAR(MAX) '$')
FOR JSON PATH
) AS details
UNION ALL -- Guidance Panel
SELECT
-- Guidance Panel 'Guidance' AS label,
SELECT (
'Guidance' AS label, SELECT
( 'Last Price Capped' AS label,
SELECT q.guidance_price AS value,
'Price' AS label, 'currency' AS type,
q.guidance_price AS value, CONCAT(
'currency' AS type, 'Last price ', q.last_price,
q.guidance_reason AS note ' capped at ',
FOR JSON PATH ROUND((q.last_price - q.guidance_price) / NULLIF(q.last_price, 0) * 100, 2),
) '%'
) AS panel ) AS note
FOR JSON PATH FOR JSON PATH
) AS details, )
JSON_QUERY(q.expl) AS data -- 👈 adds the full expl content as a JSON object ) AS panel
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER -- 👈 make it a single JSON object FOR JSON PATH, ROOT('details')
) )
FROM @queue q; FROM @queue q;
--------------------------------------------------------------------------------
-- Final: Return the enriched result row
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
RETURN; -- Final: Return the enriched result row
END; --------------------------------------------------------------------------------
RETURN;
END;