Compare commits

..

1 Commits

Author SHA1 Message Date
66c6b1595a work on merging with pg format 2023-11-13 16:10:42 -05:00
15 changed files with 217 additions and 1282 deletions

21
api.ts
View File

@ -34,35 +34,18 @@ const query = await Deno.readTextFile("sql/get.pg.sql");
const query_dseg = await Deno.readTextFile("sql/get_dseg.pg.sql"); const query_dseg = await Deno.readTextFile("sql/get_dseg.pg.sql");
// exact scenario for existing codes // exact scenario for existing codes
router.get('/code/:billcode/:shipcode/:partcode/:qty', async (ctx) => { router.get('/code_price/:billcode/:shipcode/:partcode/:qty', async (ctx) => {
const { billcode, shipcode, partcode, qty } = ctx.params; const { billcode, shipcode, partcode, qty } = ctx.params;
const result = await client.queryObject({args: [billcode, shipcode, partcode, qty], text: query} ); const result = await client.queryObject({args: [billcode, shipcode, partcode, qty], text: query} );
ctx.response.body = apply_guidance(result.rows[0]["doc"]); ctx.response.body = apply_guidance(result.rows[0]["doc"]);
}); });
// specific customres codes but generic style code and data segment to accomodate custom colors and branding
router.get('/dseg/:billcode/:shipcode/:stlc/:dseg/:qty', async (ctx) => {
const { billcode, shipcode, stlc, dseg, qty } = ctx.params;
const result = await client.queryObject({args: [billcode, shipcode, stlc, dseg, qty], text: query_dseg} );
ctx.response.body = apply_guidance(result.rows[0]["doc"]);
});
// specific customres codes but generic style code and data segment to accomodate custom colors and branding // specific customres codes but generic style code and data segment to accomodate custom colors and branding
router.get('/dseg_price/:billcode/:shipcode/:stlc/:dseg/:qty', async (ctx) => { router.get('/dseg_price/:billcode/:shipcode/:stlc/:dseg/:qty', async (ctx) => {
const { billcode, shipcode, stlc, dseg, qty } = ctx.params; const { billcode, shipcode, stlc, dseg, qty } = ctx.params;
const result = await client.queryObject({args: [billcode, shipcode, stlc, dseg, qty], text: query_dseg} ); const result = await client.queryObject({args: [billcode, shipcode, stlc, dseg, qty], text: query_dseg} );
const ag = apply_guidance(result.rows[0]["doc"]); ctx.response.body = apply_guidance(result.rows[0]["doc"]);
ctx.response.body = ag.guidance.finalPrice.Snapped;
}); });
// specific customres codes but generic style code and data segment to accomodate custom colors and branding
router.get('/dseg_reason/:billcode/:shipcode/:stlc/:dseg/:qty', async (ctx) => {
const { billcode, shipcode, stlc, dseg, qty } = ctx.params;
const result = await client.queryObject({args: [billcode, shipcode, stlc, dseg, qty], text: query_dseg} );
const ag = apply_guidance(result.rows[0]["doc"]);
ctx.response.body = ag.guidance.finalPrice.Snapped + ' (' + ag.guidance.finalPrice.Reason + ')';
});
app.use(router.routes()); app.use(router.routes());
app.use(router.allowedMethods()); app.use(router.allowedMethods());

View File

@ -1,165 +1,151 @@
export function apply_guidance(doc: any) { export function apply_guidance(doc: any) {
function sortObjectKeys(obj) { /*-----------------------------------------------------------------------------------------------------------------------------------------------------
// If the object is not an actual object or is an array, return it as is price optimization lookup table
if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) { -----------------------------------------------------------------------------------------------------------------------------------------------------*/
return obj;
}
// Create a new object and sort the keys
const sortedObj = {};
Object.keys(obj).sort().forEach(key => {
// Recursively apply the function for nested objects
sortedObj[key] = sortObjectKeys(obj[key]);
});
return sortedObj;
}
function getAdjValue(number) { function getAdjValue(number) {
const data = [ const data = [
{f: 2.001, t: 1000, snap: 3, adj: 0 }, {f: 2.001, t: 1000, snap: 3, adj: 0 },
{f: 1.001, t: 2, snap: 2, adj: 0 }, {f: 1.001, t: 2, snap: 2, adj: 0 },
{f: 0.1, t: 1, snap: 1, adj: 0 }, {f: 0.1, t: 1, snap: 1, adj: 0 },
{f: 0, t: 0.1, snap: 0, adj: 0 }, {f: 0, t: 0.1, snap: 0, adj: 0 },
{f: -1, t: -0.00001, snap: -1, adj: 0.05}, {f: -1, t: -0.00001, snap: -1, adj: 0.05},
{f: -2, t: -0.999999, snap: -2, adj: 0.05}, {f: -2, t: -0.999999, snap: -2, adj: 0.05},
{f: -1000, t: -2.001, snap: -3, adj: 0.10}, {f: -1000, t: -2.001, snap: -3, adj: 0.10},
]; ];
const match = data.find(row => number >= row.f && number <= row.t); const match = data.find(row => number >= row.f && number <= row.t);
return match ? match.adj : null; return match ? match.adj : null;
} }
//-------------------------------set flor prices------------------------------- const targetPrice = doc.pricing?.v1tp ?? doc.pricing?.v0tp;
function getFloor(stlc) { const bridgePremium = doc.pricing?.bridgePremium ;
switch (stlc) { const earlyPriceOrig = doc.hist?.cust?.early_price;
case "SDD10000": const earlyPrice = doc.hist?.cust?.early_price * bridgePremium;
return 0.045; const earlyMarketPrice = doc.hist?.market?.early_price;
case "SDD10001": const earlySeason = doc.hist?.cust?.early_season;
return 0.045; const earlyMarketSeason = doc.hist?.market?.early_season;
case "SDD12000": const altHist = doc.hist?.cust?.ds;
return 0.065; const iidx = doc.pricing?.iidx;
default: const curr = doc.customer?.curr;
return null; const chan = doc.customer?.chan;
} const fxrate = doc.customer?.fxrate ?? 1.0;
const qty = doc.inputs?.qty;
const pltq = doc.product?.pltq;
const band = doc.pricing?.v1stdv ?? doc.pricing?.v0stdv ?? 0;
let custPrice = null;
let custSource = null;
let guidance = {};
let calcCeiling = null;
let finalReasonUSD = "";
let finalPriceUSD = null;
let finalReason = "";
let finalPrice = null;
let ltp = qty < pltq ? .15 : 0;
let ltpf = qty < pltq ? true : false;
let increase = null;
let isWarehouse = chan[0] === "W"
const inflationidx = Math.max(...Object.keys(iidx).map(Number));
const inflation = iidx[inflationidx];
const list = doc.pricing?.list && doc.product?.itemrel === "2" ? doc.pricing?.list : null;
const listUSD = (list && fxrate) ? list / fxrate : null;
/*-----------------------------------------------------------------------------------------------------------------------------------------------------
determine anchor price
-----------------------------------------------------------------------------------------------------------------------------------------------------*/
let anchorPrice =
earlyPrice ? earlyPrice :
targetPrice ? targetPrice :
earlyMarketPrice ? earlyMarketPrice :
null;
let anchorSource =
earlyPrice
? bridgePremium
? `${earlySeason} ${altHist} price ${earlyPriceOrig} x ${bridgePremium} = ${earlyPrice}`
: `${earlySeason} price ${(earlyPrice * 1000).toFixed(2)}` :
earlyPrice ? earlyReason :
targetPrice ? `Target price ${(targetPrice * 1000).toFixed(2)}` :
earlyMarketPrice ? `${earlyMarketSeason} price ${earlyMarketPrice}` :
null;
/*-----------------------------------------------------------------------------------------------------------------------------------------------------
calculated increase percentages
-----------------------------------------------------------------------------------------------------------------------------------------------------*/
let anchorSD = (band && targetPrice) ? ((anchorPrice - targetPrice) / band).toFixed(2) : 0
let optFactor = getAdjValue(anchorSD) ;
let increaseAnch = 1 + optFactor + ltp + inflation;
let increaseTarg = 1 + ltp + inflation;
/*-----------------------------------------------------------------------------------------------------------------------------------------------------
apply increases
-----------------------------------------------------------------------------------------------------------------------------------------------------*/
let anchorGoal = anchorPrice * increaseAnch;
let capTarget = targetPrice * increaseTarg;
let capMarket = earlyMarketPrice * increaseTarg;
/*-----------------------------------------------------------------------------------------------------------------------------------------------------
calculate price caps
-----------------------------------------------------------------------------------------------------------------------------------------------------*/
/* there are 3 price points
* anchor + increase
* target + increase
* list
goal is to demonstrate calculation of anchor + increase then give then cap if applicable
*/
//default to anchor goal
finalPriceUSD = anchorGoal;
finalReason = "";
let increaseReason = "";
let cap = "";
//if the target is less than the anchor goal, cap at target
if ((capTarget ?? anchorGoal ) < anchorGoal) {
finalPriceUSD = capTarget;
cap = ` cap at target ${(targetPrice * 1000).toFixed(2)} + ${((increaseTarg - 1) * 100).toFixed(1)}%`
} }
//if list price is even less than the capped price, then cap at list
function lowestPrice(priceObject) { if ((listUSD ?? anchorGoal) < finalPriceUSD ) {
let Price = Infinity; finalPriceUSD = listUSD;
let Reason = ''; cap = ` cap at list ${listUSD}`
let Source = ''; }
let Snapped = Infinity; /*-----use _p.list if available for warehouse-----------*/
if (isWarehouse) {
//console.log(priceObject["targ"][0]); if (listUSD) {
// Iterate over each property in the object finalPriceUSD = listUSD;
for (let key in priceObject) { cap_curr = ` snap to list ${listUSD}`;
// Ignore markPrice unless targPrice is null
if (key === "mark" && priceObject["targ"][0] !== null) {
continue;
}
if (priceObject.hasOwnProperty(key)) {
let [cprice, creason, csource, csnap] = priceObject[key];
// Check if the current price is lower than the found so far
if (cprice && cprice < Price) {
Price = cprice;
Reason = creason;
Source = csource;
Snapped = csnap;
}
}
} }
return {Reason, Price, Source, Snapped};
} }
finalPrice = finalPriceUSD / fxrate;
function ceiling(value, significance) { /*-----------------------------------------------------------------------------------------------------------------------------------------------------
return Math.ceil(value / significance) * significance; build the logic text
} -----------------------------------------------------------------------------------------------------------------------------------------------------*/
function r5(value) { cap = cap ? ";" + cap : "";
return Number(value.toFixed(5)); let fltp = ltpf ? ` + ${(ltp * 100).toFixed(1) + '%'} LTP` : "";
} let fopt = optFactor ? ` + ${(optFactor * 100).toFixed(1) + '%'} opt` : "";
let fguidance = inflation ? ` + ${(inflation * 100).toFixed(1) + '%'} guidance` : "";
finalReason = `${(finalPrice*1000).toFixed(2)} (${anchorSource}${fguidance}${fltp}${fopt}${cap}) `;
function pp(value) { guidance.AnchorPrice = anchorPrice;
// Multiplies by 1000 and rounds to the nearest 2 decimals guidance.AnchorSource = anchorSource;
var result = Math.round(value * 1000 * 100) / 100; //guidance.CustAnchorPrice = custPrice;
//guidance.CustAnchorSource = custSource;
// Converts the number to a string with commas for thousand separators guidance.InflationFactor = inflation;
return result.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2}); //guidance.Ceiling = calcCeiling;
} guidance.FinalPriceUSD = finalPriceUSD;
guidance.FinalReason = finalReason;
// --------------------extract incoming data------------------------------------------------------ guidance.FinalPrice = finalPrice;
const targetPrice = doc.pricing?.v1tp ?? doc.pricing?.v0tp; guidance.FinalReason = finalReason;
const priceBand = doc.pricing?.v1stdv ?? doc.pricing?.v0stdv; guidance.BridgePremium = bridgePremium;
const earlyCustPrice = doc.hist?.cust?.early_price; guidance.TargetPrice = targetPrice;
const earlyCustSeason = doc.hist?.cust?.early_season; guidance.ListPrice = list;
const earlyMarkPrice = doc.hist?.market?.early_price;
const earlyMarkSeason = doc.hist?.market?.early_season;
const bridgePremium = doc.pricing?.bridgePremium;
const bridgedPrice = Number((earlyCustPrice * (bridgePremium ?? 1.00)).toFixed(5));
const altHist = doc.hist?.cust?.ds;
const iidx = doc.pricing?.iidx;
const curr = doc.customer?.curr;
const fxrate = doc.customer?.fxrate ?? 1.0;
const qty = doc.inputs?.qty;
const pltq = doc.product?.pltq;
const inflation = Math.max(...Object.keys(iidx).map(Number));
const inflationFactor = iidx[inflation];
const list = doc.pricing?.list && doc.product?.itemrel === "2" ? doc.pricing?.list : null;
const listUSD = list ? list * fxrate :null;
const stlc = doc.inputs.stlc;
// ------------------calculate price adders------------------------------------------------------
let ltp = stlc.includes("SDD") || stlc.includes("HZP") ? 0 : (qty < pltq ? 0.15 : null);
let anchor_sd = priceBand ? ((bridgedPrice - targetPrice) / priceBand).toFixed(2) : 0
let optimization = getAdjValue(anchor_sd);
let custAdder = (ltp ?? 0) + optimization + inflationFactor;
let markAdder = (ltp ?? 0) + inflationFactor;
let inflReason = (inflationFactor ?? 0) !== 0 ? ` + ${(inflationFactor * 100).toFixed(1)}% infl`: "";
let ltpReason = ltp ? ` + ${(ltp * 100).toFixed(1)}% ltp` : "";
let optReason = (optimization ?? 0) !== 0 ? ` + ${(optimization * 100).toFixed(1)}% opt`: "";
let custAddReason = `${inflReason}${ltpReason}${optReason}`;
let markAddReason = `${inflReason}${ltpReason}`;
let floor = getFloor(stlc);
// ------------------start building price options------------------------------------------------
let snap = .0005;
let custPrice = r5(bridgedPrice * (1 + custAdder));
let custSeason = earlyCustSeason;
let custReason = bridgePremium
? `${custSeason} (similar ${altHist} price ${pp(earlyCustPrice)} x ${bridgePremium} = ${pp(bridgedPrice)})${custAddReason}`
: `${custSeason} price ${pp(bridgedPrice)}${custAddReason}`;
let markPrice = r5(earlyMarkPrice * (1 + markAdder));
let markReason = `${earlyMarkSeason} ASP ${pp(earlyMarkPrice)}${markAddReason}`;
let targPrice = targetPrice ? r5(targetPrice * (1 + markAdder)) : null;
let targReason = `Target price ${pp(targetPrice)}${markAddReason}`;
let listPrice = listUSD;
let listReason = fxrate === 1 ? `list ${pp(list)}` : `list ${pp(list)} CAD ${pp(listUSD)} USD`;
let prices = {
cust: [custPrice, custReason, "cust", r5(ceiling(custPrice,snap))],
mark: [markPrice, markReason, "mark", r5(ceiling(markPrice,snap))],
targ: [targPrice, targReason, "targ", r5(ceiling(targPrice,snap))],
list: [listPrice, listReason, "list", r5(ceiling(listPrice,snap))]
}
let finalPrice = lowestPrice(prices);
if (floor && floor > finalPrice.Price) {
finalPrice.Price = floor;
finalPrice.Snapped = floor;
finalPrice.Reason = `${finalPrice.Reason} floor at ${floor}`;
}
let guidance = {
prices
,finalPrice
,targetPrice
,listUSD
,ltp
,inflationFactor
,optimization
}
doc.guidance = guidance; doc.guidance = guidance;
//return doc; return doc;
return sortObjectKeys(doc);
} }

View File

@ -1,70 +0,0 @@
set work_mem TO '4GB';
DROP TABLE IF EXISTS rlarp.live_quotes_review_mv;
CREATE TABLE rlarp.live_quotes_review_mv AS
WITH
lq AS MATERIALIZED (
SELECT
lq.*
,substring(lq.part,1,8) mold
FROM
pricequote.live_quotes lq
)
,lqg AS (
SELECT
lq.*
,pricing->'product'->>'mold' part_group
,substring(pricing->'customer'->>'chan',1,1) qchan
,pricing->'customer'->>'cust' qcust
,pricing->'product'->>'itemrel' item_fit
,(pricing->'product'->>'pltq')::numeric pltq
,(pricing->'guidance'->'finalPrice'->>'Price')::numeric guidance
,pricing->'guidance'->'finalPrice'->>'Reason' reason
,(pricing->'product'->>'cstd_usd_ina')::numeric fstd_usd
,(pricing->'guidance'->>'ltp')::numeric ltp
,(pricing->'guidance'->>'optimization')::numeric optimization
,(pricing->'guidance'->>'inflationFactor')::numeric inflation
,jsonb_pretty(pricing) pricing
FROM
lq
LEFT JOIN LATERAL rlarp.guidance_r1(
rlarp.get_guidance_dseg(lq.billto,lq.shipto,substring(lq.part,1,8),lq.v1ds,lq.units_each,2024)
) pricing ON TRUE
WHERE
lq.qstat ~ 'Submitted'
)
,hist AS (
SELECT
g.*
,gset.chan
--,gset.mold moldh
,gset.v1ds v1dsh
,gset.cust
,gset.vers
,je.k
,seas.*
FROM
lqg g
LEFT OUTER JOIN rlarp.price_pool_dev p ON
p.gset @> jsonb_build_object('mold',g.part_group)
AND p.gset ? 'cust'
AND p.gset ? 'v1ds'
LEFT JOIN LATERAL jsonb_to_record(p.gset) AS gset(
chan text
,mold text
,v1ds text
,v0ds text
,cust text
,vers text
--,nurs text
--,ghse text
) ON TRUE
LEFT JOIN LATERAL jsonb_each(p.season) je(k,v) on true
LEFT JOIN Lateral jsonb_to_record(je.v) as seas(
units numeric
,sales_usd numeric
,price_usd numeric
) ON TRUE
)
SELECT * FROM hist;

View File

@ -1,152 +0,0 @@
CREATE OR REPLACE FUNCTION rlarp.guidance_r1(doc jsonb)
RETURNS jsonb
LANGUAGE plv8
AS $function$
function getAdjValue(number) {
const data = [
{f: 2.001, t: 1000, snap: 3, adj: 0 },
{f: 1.001, t: 2, snap: 2, adj: 0 },
{f: 0.1, t: 1, snap: 1, adj: 0 },
{f: 0, t: 0.1, snap: 0, adj: 0 },
{f: -1, t: -0.00001, snap: -1, adj: 0.05},
{f: -2, t: -0.999999, snap: -2, adj: 0.05},
{f: -1000, t: -2.001, snap: -3, adj: 0.10},
];
const match = data.find(row => number >= row.f && number <= row.t);
return match ? match.adj : null;
}
//-------------------------------set flor prices-------------------------------
function getFloor(stlc) {
switch (stlc) {
case "SDD10000":
return 0.045;
case "SDD10001":
return 0.045;
case "SDD12000":
return 0.065;
default:
return null;
}
}
function lowestPrice(priceObject) {
let Price = Infinity;
let Reason = '';
let Source = '';
let Snapped = Infinity;
//console.log(priceObject["targ"][0]);
// Iterate over each property in the object
for (let key in priceObject) {
// Ignore markPrice unless targPrice is null
if (key === "mark" && priceObject["targ"][0] !== null) {
continue;
}
if (priceObject.hasOwnProperty(key)) {
let [cprice, creason, csource, csnap] = priceObject[key];
// Check if the current price is lower than the found so far
if (cprice && cprice < Price) {
Price = cprice;
Reason = creason;
Source = csource;
Snapped = csnap;
}
}
}
return {Reason, Price, Source, Snapped};
}
function ceiling(value, significance) {
return Math.ceil(value / significance) * significance;
}
function r5(value) {
return Number(value.toFixed(5));
}
function pp(value) {
// Multiplies by 1000 and rounds to the nearest 2 decimals
var result = Math.round(value * 1000 * 100) / 100;
// Converts the number to a string with commas for thousand separators
return result.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2});
}
// --------------------extract incoming data------------------------------------------------------
const targetPrice = doc.pricing?.v1tp ?? doc.pricing?.v0tp;
const priceBand = doc.pricing?.v1stdv ?? doc.pricing?.v0stdv;
const earlyCustPrice = doc.hist?.cust?.early_price;
const earlyCustSeason = doc.hist?.cust?.early_season;
const earlyMarkPrice = doc.hist?.market?.early_price;
const earlyMarkSeason = doc.hist?.market?.early_season;
const bridgePremium = doc.pricing?.bridgePremium;
const bridgedPrice = Number((earlyCustPrice * (bridgePremium ?? 1.00)).toFixed(5));
const altHist = doc.hist?.cust?.ds;
const iidx = doc.pricing?.iidx;
const curr = doc.customer?.curr;
const fxrate = doc.customer?.fxrate ?? 1.0;
const qty = doc.inputs?.qty;
const pltq = doc.product?.pltq;
const inflation = iidx ? Math.max(...Object.keys(iidx).map(Number)) : null;
const inflationFactor = iidx ? iidx[inflation] : 0;
const list = doc.pricing?.list && doc.product?.itemrel === "2" ? doc.pricing?.list : null;
const listUSD = list ? list * fxrate :null;
const stlc = doc.inputs.stlc;
// ------------------calculate price adders------------------------------------------------------
let ltp = stlc.includes("SDD") || stlc.includes("HZP") ? 0 : (qty < pltq ? 0.15 : null);
let anchor_sd = priceBand ? ((bridgedPrice - targetPrice) / priceBand).toFixed(2) : 0
let optimization = getAdjValue(anchor_sd);
let custAdder = (ltp ?? 0) + optimization + inflationFactor;
let markAdder = (ltp ?? 0) + inflationFactor;
let inflReason = (inflationFactor ?? 0) !== 0 ? ` + ${(inflationFactor * 100).toFixed(1)}% infl`: "";
let ltpReason = ltp ? ` + ${(ltp * 100).toFixed(1)}% ltp` : "";
let optReason = (optimization ?? 0) !== 0 ? ` + ${(optimization * 100).toFixed(1)}% opt`: "";
let custAddReason = `${inflReason}${ltpReason}${optReason}`;
let markAddReason = `${inflReason}${ltpReason}`;
let floor = getFloor(stlc);
// ------------------start building price options------------------------------------------------
let snap = .0005;
let custPrice = r5(bridgedPrice * (1 + custAdder));
let custSeason = earlyCustSeason;
let custReason = bridgePremium
? `${custSeason} (similar ${altHist} price ${pp(earlyCustPrice)} x ${bridgePremium} = ${pp(bridgedPrice)})${custAddReason}`
: `${custSeason} price ${pp(bridgedPrice)}${custAddReason}`;
let markPrice = r5(earlyMarkPrice * (1 + markAdder));
let markReason = `${earlyMarkSeason} ASP ${pp(earlyMarkPrice)}${markAddReason}`;
let targPrice = targetPrice ? r5(targetPrice * (1 + markAdder)) : null;
let targReason = `Target price ${pp(targetPrice)}${markAddReason}`;
let listPrice = listUSD;
let listReason = fxrate === 1 ? `list ${pp(list)}` : `list ${pp(list)} CAD ${pp(listUSD)} USD`;
let prices = {
cust: [custPrice, custReason, "cust", r5(ceiling(custPrice,snap))],
mark: [markPrice, markReason, "mark", r5(ceiling(markPrice,snap))],
targ: [targPrice, targReason, "targ", r5(ceiling(targPrice,snap))],
list: [listPrice, listReason, "list", r5(ceiling(listPrice,snap))]
}
let finalPrice = lowestPrice(prices);
if (floor && floor > finalPrice.Price) {
finalPrice.Price = floor;
finalPrice.Snapped = floor;
finalPrice.Reason = `${finalPrice.Reason} floor at ${floor}`;
}
let guidance = {
prices
,finalPrice
,targetPrice
,listUSD
,ltp
,inflationFactor
,optimization
}
doc.guidance = guidance;
return doc;
$function$;

View File

@ -1,33 +0,0 @@
SELECT
gset.cust
,gset.vers
,gset.chan
,gset.nurs
,gset.ghse
,gset.mold
,gset.v1ds
,gset.v0ds
,je.k
,seas.*
FROM
rlarp.price_pool_dev p
LEFT JOIN LATERAL jsonb_to_record(p.gset) AS gset(
chan text
,mold text
,v1ds text
,v0ds text
,cust text
,vers text
,nurs text
,ghse text
) ON TRUE
LEFT JOIN LATERAL jsonb_each(p.season) je(k,v) on true
LEFT JOIN Lateral jsonb_to_record(je.v) as seas(
units numeric
,sales_usd numeric
,price_usd numeric
) ON TRUE
WHERE
gset @> '{"mold":"TFR001G0","v0ds":"BASE"}'
AND agglevel ?| array['chan', 'mold', 'v0ds']
AND NOT agglevel ?| array['cust','ghse'];

View File

@ -1,79 +0,0 @@
----takes 2 DBA's and returns the channel----------
CREATE OR REPLACE FUNCTION rlarp.get_cust(billcode text, shipcode text)
RETURNS jsonb
LANGUAGE plpgsql AS
$func$
DECLARE
_chan text;
_chantp text;
_bill_class text;
_ship_class text;
_bill_dba text;
_ship_dba text;
_cust text;
_bill_curr text;
_bill_rate numeric;
_crec jsonb;
_ret jsonb;
_record jsonb;
BEGIN
SELECT jsonb_agg(row_to_json(c)::jsonb) INTO _crec FROM rlarp.cust c WHERE code IN (billcode, shipcode);
--RAISE NOTICE '%', jsonb_pretty(_crec);
FOR _record IN SELECT * FROM jsonb_array_elements(_crec)
LOOP
-- Check if the record is for billcode or shipcode and assign values accordingly
IF (_record->>'code')::text = billcode THEN
_bill_dba := (_record->>'dba')::text;
_bill_class := (_record->>'cclass')::text;
_bill_curr := (_record->>'currency')::text;
_bill_rate := (_record->>'fxcurr')::text;
-- Add other billcode related assignments here
END IF;
IF (_record->>'code')::text = shipcode THEN
_ship_dba := (_record->>'dba')::text;
_ship_class := (_record->>'cclass')::text;
-- Add other shipcode related assignments here
END IF;
END LOOP;
SELECT
CASE WHEN SUBSTRING(_bill_class,2,3) = 'DIS'
THEN CASE WHEN SUBSTRING(_ship_class,2,3) = 'DIS' THEN 'WHS' ELSE 'DRP' END
ELSE 'DIR'
END
INTO
_chan;
SELECT
CASE WHEN SUBSTRING(_bill_class,2,3) = 'DIS'
THEN CASE WHEN SUBSTRING(_ship_class,2,3) = 'DIS' THEN 'DISTRIBUTOR' ELSE 'DISTRIB DROP SHIP' END
ELSE 'DIRECT'
END
INTO
_chantp;
SELECT
CASE WHEN _chan = 'DRP' THEN _ship_dba ELSE _bill_dba END
INTO
_cust;
_ret := jsonb_build_object('customer',
jsonb_build_object(
'cust',_cust,
'chan',_chan,
'chantp',_chantp,
'curr',_bill_curr,
'fxrate',_bill_rate,
'bill_dba',_bill_dba,
'ship_dba',_ship_dba
)
);
RETURN _ret;
END
$func$;

View File

@ -42,7 +42,7 @@ BEGIN
INTO INTO
_mold,_stlc,_v1ds , _v0ds, _iidx _mold,_stlc,_v1ds , _v0ds, _iidx
FROM FROM
"CMS.CUSLG".itemm i "CMS.CUSLG".itemmv i
INNER JOIN rlarp.molds m ON INNER JOIN rlarp.molds m ON
m.stlc = i.stlc m.stlc = i.stlc
WHERE WHERE

View File

@ -1,4 +1,4 @@
DROP FUNCTION rlarp.get_guidance_dseg CASCADE; DROP FUNCTION rlarp.get_guidance_dseg;
CREATE OR REPLACE FUNCTION rlarp.get_guidance_dseg(_bill text, _ship text, _stlc text, _dseg text, _qty numeric, _seas int) CREATE OR REPLACE FUNCTION rlarp.get_guidance_dseg(_bill text, _ship text, _stlc text, _dseg text, _qty numeric, _seas int)
RETURNS jsonb RETURNS jsonb
LANGUAGE plpgsql AS LANGUAGE plpgsql AS
@ -15,10 +15,6 @@ DECLARE
_item text; _item text;
_unti text; _unti text;
_pltq numeric; _pltq numeric;
_cstd numeric;
_cstdina numeric;
_fstd numeric;
_fstdina numeric;
_cust text; _cust text;
_curr text; _curr text;
_rate numeric; _rate numeric;
@ -68,114 +64,110 @@ BEGIN
,item ,item
,idxk ,idxk
,prefer ,prefer
,pltq ,(SELECT unti FROM "CMS.CUSLG".itemm WHERE item = best.item)
,curstdus
,curstdus_ina
,futstdus
,futstdus_ina
INTO INTO
_mold _mold
,_item ,_item
,_iidx ,_iidx
,_itemr ,_itemr
,_pltq ,_unti
,_cstd
,_cstdina
,_fstd
,_fstdina
FROM FROM
( (
SELECT SELECT
i.partgroup part_group m.part_group
,min(i.item) item ,min(i.item) item
,i.stlc ,i.stlc
,i.v1ds ,i.v1ds
,_ds.dataseg v0ds ,i.v0ds
,i.mpck pltq
,avg(i.curstdus) FILTER (WHERE aplnt <> 'I') curstdus
,avg(i.curstdus) curstdus_ina
,avg(i.futstdus) FILTER (WHERE aplnt <> 'I') futstdus
,avg(i.futstdus) futstdus_ina
,jsonb_strip_nulls(jsonb_build_object('assc',CASE WHEN i.assc <> '' THEN i.assc ELSE null::text END,'majg',i.majg::int,'coltier',i.coltier)) idxk ,jsonb_strip_nulls(jsonb_build_object('assc',CASE WHEN i.assc <> '' THEN i.assc ELSE null::text END,'majg',i.majg::int,'coltier',i.coltier)) idxk
,CASE WHEN i.v1ds = _v1ds THEN 2 ELSE CASE WHEN _ds.dataseg = _v0ds THEN 1 ELSE 0 END END prefer ,CASE WHEN i.v1ds = _v1ds THEN 2 ELSE CASE WHEN i.v0ds = _v0ds THEN 1 ELSE 0 END END prefer
FROM FROM
"CMS.CUSLG".itemm i "CMS.CUSLG".itemmv i
LEFT OUTER JOIN _ds ON INNER JOIN rlarp.molds m ON
_ds.colgrp = i.colgrp m.stlc = i.stlc
AND _ds.brand = SUBSTRING(i.branding,1,1)
--INNER JOIN rlarp.molds m ON
-- m.stlc = i.stlc
WHERE WHERE
i.stlc = _stlc i.stlc = _stlc
GROUP BY GROUP BY
i.partgroup m.part_group
,i.stlc ,i.stlc
,i.v1ds ,i.v1ds
,_ds.dataseg ,i.v0ds
,i.mpck
,jsonb_strip_nulls(jsonb_build_object('assc',CASE WHEN i.assc <> '' THEN i.assc ELSE null::text END,'majg',i.majg::int,'coltier',i.coltier)) ,jsonb_strip_nulls(jsonb_build_object('assc',CASE WHEN i.assc <> '' THEN i.assc ELSE null::text END,'majg',i.majg::int,'coltier',i.coltier))
,CASE WHEN i.v1ds = _v1ds THEN 2 ELSE CASE WHEN _ds.dataseg = _v0ds THEN 1 ELSE 0 END END ,CASE WHEN i.v1ds = _v1ds THEN 2 ELSE CASE WHEN i.v0ds = _v0ds THEN 1 ELSE 0 END END
) best ) best
ORDER BY ORDER BY
prefer DESC prefer DESC
LIMIT 1; LIMIT 1;
_product := _product :=
jsonb_build_object( jsonb_build_object(
'product' 'mold',_mold
,jsonb_build_object( ,'item',_item
'mold',_mold ,'itemrel',_itemr
,'item',_item ,'iidx',_iidx
,'itemrel',_itemr ,'unti',_unti
,'iidx',_iidx
,'pltq',_pltq
,'cstd_usd',_cstd
,'cstd_usd_ina',_cstdina
,'fstd_usd',_fstd
,'fstd_usd_ina',_fstdina
)
); );
--RAISE NOTICE 'item data %', jsonb_pretty(_product||_input); --RAISE NOTICE 'item data %', jsonb_pretty(_product||_input);
----------------pallet quantity-----------------------------
SELECT
ROUND(uom.nm/uom.dm,1) pltq
INTO
_pltq
FROM
(
SELECT
jsonb_agg(row_to_json(d)::jsonb) jdoc
FROM
(
select distinct
_item partn
,'PLT' fu
,_unti tu
) d
) c
JOIN LATERAL rlarp.uom_array(c.jdoc) uom ON TRUE;
_product := jsonb_build_object('product',_product||jsonb_build_object('pltq',_pltq));
----------------channel------------------------------------- ----------------channel-------------------------------------
SELECT rlarp.get_cust(_bill, _ship) INTO _customer; SELECT rlarp.channel_code(_bill, _ship) INTO _chan;
--_customer := jsonb_build_object('chan',_chan); _customer := jsonb_build_object('chan',_chan);
----------------customer------------------------------------ ----------------customer------------------------------------
--SELECT dba INTO _cust FROM rlarp.cust WHERE code = CASE WHEN _chan = 'DRP' THEN _ship ELSE _bill END ; SELECT dba INTO _cust FROM rlarp.cust WHERE code = CASE WHEN _chan = 'DRP' THEN _ship ELSE _bill END ;
--SELECT SELECT
-- currency, currency,
-- (SELECT (SELECT
-- x.rate x.rate
-- FROM FROM
-- rlarp.ffcret x rlarp.ffcret x
-- WHERE WHERE
-- x.perd = (select fspr from rlarp.gld where drange @> current_date) x.perd = (select fspr from rlarp.gld where drange @> current_date)
-- AND x.rtyp = 'MA' AND x.rtyp = 'MA'
-- and x.fcur = currency and x.fcur = currency
-- AND x.tcur = 'US' AND x.tcur = 'US'
-- ) )
--INTO INTO
-- _curr _curr
-- ,_rate ,_rate
--FROM FROM
-- rlarp.cust rlarp.cust
--WHERE WHERE
-- code = _bill; code = _bill;
--_customer := jsonb_build_object( _customer := jsonb_build_object(
-- 'customer', 'customer',
-- _customer||jsonb_build_object( _customer||jsonb_build_object(
-- 'cust',_cust 'cust',_cust
-- ,'curr',_curr ,'curr',_curr
-- ,'fxrate',_rate ,'fxrate',_rate
-- ) )
--); );
--RAISE NOTICE 'cust %', jsonb_pretty(_customer); --RAISE NOTICE 'cust %', jsonb_pretty(_customer);
----------------price history------------------------------- ----------------price history-------------------------------
--RAISE NOTICE 'varb %', _customer; SELECT jsonb_build_object('hist',rlarp.get_hist(_mold, _v1ds, _cust, substring(_chan,1,1))) INTO _hist;
SELECT jsonb_build_object('hist',rlarp.get_hist(_mold, _v1ds, _customer->'customer'->>'cust', substring(_customer->'customer'->>'chan',1,1))) INTO _hist;
--RAISE NOTICE 'history %', jsonb_pretty(_hist); --RAISE NOTICE 'history %', jsonb_pretty(_hist);
----------------target pricing------------------------------ ----------------target pricing------------------------------
@ -194,8 +186,7 @@ BEGIN
mold = _stlc mold = _stlc
AND season = _seas AND season = _seas
AND data_segment = _v0ds AND data_segment = _v0ds
AND region = 'ALL' AND region = 'ALL';
AND chan = _customer->'customer'->>'chantp';
----------------target pricing------------------------------ ----------------target pricing------------------------------
SELECT SELECT
jsonb_build_object( jsonb_build_object(
@ -212,8 +203,7 @@ BEGIN
mold = _stlc mold = _stlc
AND season = _seas AND season = _seas
AND data_segment = _dseg AND data_segment = _dseg
AND region = 'ALL' AND region = 'ALL';
AND chan = _customer->'customer'->>'chantp';
--RAISE NOTICE 'target: %', jsonb_pretty(_targ); --RAISE NOTICE 'target: %', jsonb_pretty(_targ);
_pricing := (COALESCE(_v0tp,'{}'::jsonb)||COALESCE(_v1tp,'{}'::jsonb)); _pricing := (COALESCE(_v0tp,'{}'::jsonb)||COALESCE(_v1tp,'{}'::jsonb));
@ -247,7 +237,7 @@ BEGIN
--RAISE NOTICE 'add list: %', jsonb_pretty(_pricing); --RAISE NOTICE 'add list: %', jsonb_pretty(_pricing);
----------------get premium for quote hist gap-------------- ----------------get premium for quote hist gap--------------
SELECT coalesce(rlarp.get_premium(_stlc, _seas, _customer->'customer'->>'chantp',_hist->'hist'->'cust'->>'ds', _v1ds),'{}'::jsonb) INTO _prem; SELECT coalesce(rlarp.get_premium(_stlc, _seas, (SELECT xchan FROM _chx WHERE chan = _chan),_hist->'hist'->'cust'->>'ds', _v1ds),'{}'::jsonb) INTO _prem;
_pricing := jsonb_build_object('pricing',_pricing||_prem); _pricing := jsonb_build_object('pricing',_pricing||_prem);
--RAISE NOTICE 'add bridge: %', jsonb_pretty(_pricing); --RAISE NOTICE 'add bridge: %', jsonb_pretty(_pricing);

View File

@ -16,7 +16,6 @@ sort AS (
,gset.* ,gset.*
,row_number() OVER (PARTITION BY p.agglevel ORDER BY avgunits DESC) rn ,row_number() OVER (PARTITION BY p.agglevel ORDER BY avgunits DESC) rn
,stats.* ,stats.*
,season
FROM FROM
rlarp.price_pool_dev p rlarp.price_pool_dev p
JOIN LATERAL jsonb_to_record(gset) AS gset( JOIN LATERAL jsonb_to_record(gset) AS gset(
@ -38,8 +37,6 @@ sort AS (
,early_price numeric ,early_price numeric
,recent_season int ,recent_season int
,recent_price numeric ,recent_price numeric
,last_season int
,last_price numeric
) ON TRUE ) ON TRUE
WHERE WHERE
gset @> jsonb_build_object( gset @> jsonb_build_object(
@ -98,9 +95,6 @@ SELECT
,early_price ,early_price
,recent_season ,recent_season
,recent_price ,recent_price
,last_season
,last_price
,season
FROM FROM
sort sort
) )
@ -110,7 +104,7 @@ FROM
,('customer v0ds other',7) ,('customer v0ds other',7)
,('customer v0ds vol' ,3) ,('customer v0ds vol' ,3)
,('customer v1ds other',6) ,('customer v1ds other',6)
,('customer v1ds vol' ,2) --this will always sort to the top, v0ds will never sort to the top. you will always be getting the highest volume base price ,('customer v1ds vol' ,2)
,('market exact' ,4) ,('market exact' ,4)
,('market v0ds other' ,9) ,('market v0ds other' ,9)
,('market v0ds vol' ,5) ,('market v0ds vol' ,5)
@ -136,16 +130,13 @@ FROM
,'early_price' ,early_price ,'early_price' ,early_price
,'recent_season' ,recent_season ,'recent_season' ,recent_season
,'recent_price' ,recent_price ,'recent_price' ,recent_price
,'last_season' ,last_season
,'last_price' ,last_price
,'ds' ,COALESCE(v1ds,v0ds) ,'ds' ,COALESCE(v1ds,v0ds)
,'rank' ,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC) ,'rank'
,'pricinghistory' ,season ,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC)
) )
) )
) doc ) doc
,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC) rnk ,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC) rnk
,season
FROM FROM
flag flag
LEFT OUTER JOIN rel ON LEFT OUTER JOIN rel ON

View File

@ -1,173 +0,0 @@
WITH
sel AS (select 'v1:T..PLT..' _v1ds, 'KAWAHARA NURSERY' _cust, 'AZE10001' _mold, 'D' _chan)
,sort AS (
SELECT
p.agglevel
,CASE WHEN p.agglevel ? 'cust' THEN 'cust' ELSE 'market' END source
,COALESCE(gset.v1ds = _v1ds,false) v1ds_match
,gset.chan = _chan chan_match
,gset.*
,row_number() OVER (PARTITION BY p.agglevel ORDER BY avgunits DESC) rn
,stats.*
,season
FROM
rlarp.price_pool_dev p
CROSS JOIN sel
JOIN LATERAL jsonb_to_record(gset) AS gset(
chan text
,mold text
,v1ds text
,v0ds text
,cust text
,vers text
--,nurs text
--,ghse text
) ON TRUE
JOIN LATERAL jsonb_to_record(stats) AS stats(
avgunits numeric
,avgtargetprice numeric
,avgordcount numeric
,avgcustcount numeric
,early_season int
,early_price numeric
,recent_season int
,recent_price numeric
,last_season int
,last_price numeric
) ON TRUE
WHERE
gset @> jsonb_build_object(
'mold', _mold
,'vers', 'A'
)
AND (
gset @> jsonb_build_object(
'cust', _cust
)
OR NOT gset ? 'cust'
)
AND COALESCE(stats.early_season,stats.recent_season) IS NOT NULL
AND NOT p.agglevel ? 'nurs'
AND NOT p.agglevel ? 'ghse'
ORDER BY
source ASC
,rn ASC
)
,rel AS (
SELECT * FROM (values
('customer exact' ,1)
,('customer v0ds other',7)
,('customer v0ds vol' ,3)
,('customer v1ds other',6)
,('customer v1ds vol' ,2) --this will always sort to the top, v0ds will never sort to the top. you will always be getting the highest volume base price
,('market exact' ,4)
,('market v0ds other' ,9)
,('market v0ds vol' ,5)
,('market v1ds other' ,8)
) x (flag,prefer)
)
,flag AS (
SELECT
--agglevel
CASE source
WHEN 'cust' THEN
CASE WHEN v1ds IS NOT NULL THEN
CASE WHEN v1ds_match THEN 'customer exact' ELSE
CASE WHEN rn = 1 THEN 'customer v1ds vol' ELSE 'customer v1ds other' END
END
ELSE
CASE WHEN rn = 1 THEN 'customer v0ds vol' ELSE 'customer v0ds other' END
END
ELSE
CASE WHEN v1ds IS NOT NULL THEN
CASE WHEN v1ds_match THEN 'market exact' ELSE
CASE WHEN rn = 1 THEN 'market v1ds vol' ELSE 'market v1ds other' END
END
ELSE
CASE WHEN rn = 1 THEN 'market v0ds vol' ELSE 'market v0ds other' END
END
END relevance
,source
,v1ds_match
,chan_match
,chan
,mold
,v1ds
,v0ds
,cust
,vers
,rn
,row_number() OVER (PARTITION BY source ORDER BY rel.prefer ASC) rnk
,avgunits
,avgordcount
,avgcustcount
,avgtargetprice
,early_season
,early_price
,recent_season
,recent_price
,last_season
,last_price
,season
FROM
sort
LEFT OUTER JOIN rel ON
rel.flag = CASE source
WHEN 'cust' THEN
CASE WHEN v1ds IS NOT NULL THEN
CASE WHEN v1ds_match THEN 'customer exact' ELSE
CASE WHEN rn = 1 THEN 'customer v1ds vol' ELSE 'customer v1ds other' END
END
ELSE
CASE WHEN rn = 1 THEN 'customer v0ds vol' ELSE 'customer v0ds other' END
END
ELSE
CASE WHEN v1ds IS NOT NULL THEN
CASE WHEN v1ds_match THEN 'market exact' ELSE
CASE WHEN rn = 1 THEN 'market v1ds vol' ELSE 'market v1ds other' END
END
ELSE
CASE WHEN rn = 1 THEN 'market v0ds vol' ELSE 'market v0ds other' END
END
END
)
,rel_sort AS (
SELECT
-- flag.relevance
--,flag.source
--,rel.prefer
--,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC) best
jsonb_strip_nulls(
jsonb_build_object(
flag.source
,jsonb_build_object(
'relevance' ,relevance
,'avgunits' ,avgunits
,'avgordcount' ,avgordcount
,'avgcustcount' ,avgcustcount
,'avgtargetprice' ,avgtargetprice
,'early_season' ,early_season
,'early_price' ,early_price
,'recent_season' ,recent_season
,'recent_price' ,recent_price
,'last_season' ,last_season
,'last_price' ,last_price
,'ds' ,COALESCE(v1ds,v0ds)
,'rank' ,rnk
,'pricinghistory' ,season
)
)
) doc
,rnk
,season
FROM
flag
WHERE
relevance ~ 'vol|exact'
)
--SELECT rnk, jsonb_pretty(doc) doc, jsonb_pretty(season) season FROM rel_sort
--SELECT jsonb_pretty(jsonb_agg(doc)) FROM rel_sort
--SELECT jsonb_pretty(jsonb_obj_aggc(doc)) FROM rel_sort--INTO _result FROM rel_sort WHERE rnk = 1;
--SELECT * FROM rel_sort;
SELECT * FROM flag
--SELECT jsonb_obj_aggc(doc) FROM rel_sort WHERE rnk = 1;

View File

@ -1,233 +0,0 @@
CREATE OR REPLACE FUNCTION rlarp.get_list(_billto text, _shipto text, _item text, _qty numeric)
RETURNS jsonb
LANGUAGE plpgsql AS
--DO
$func$
DECLARE
-- _billto text;
-- _shipto text;
-- _item text;
-- _qty numeric;
_rslt jsonb;
BEGIN
--_billto := 'DIAM0004';
--_shipto := 'DIAM0004';
--_item := 'AMK06000G18B054';
--_qty := 5400;
CREATE TEMP TABLE IF NOT EXISTS cp AS (
--every unqiue price list scenario
SELECT
s.bill_cust
,s.ship_cust
,s.part
,i.unti unit
,s.qtyord
,i.uomp
,CASE WHEN COALESCE(sc.plevel,'') = '' THEN bc.plevel ELSE sc.plevel END plvl
FROM
(SELECT _billto bill_cust, _shipto ship_cust, _item part, _qty qtyord) s
LEFT OUTER JOIN "CMS.CUSLG".itemm i ON
i.item = s.part
LEFT OUTER JOIN rlarp.cust sc ON
sc.code = s.ship_cust
LEFT OUTER JOIN rlarp.cust bc ON
bc.code = s.bill_cust
WHERE
CASE WHEN COALESCE(sc.plevel,'') = '' THEN bc.plevel ELSE sc.plevel END <> ''
GROUP BY
s.bill_cust
,s.ship_cust
,s.part
,i.unti
,s.qtyord
,i.uomp
,CASE WHEN COALESCE(sc.plevel,'') = '' THEN bc.plevel ELSE sc.plevel END
) WITH DATA;
--drop table cp
--SELECT * FROM cp WHERE bill_cust = 'DIST0008' and part = 'TCF06SG0G18C050' and ship_cust = 'DIST0007'
CREATE TEMP TABLE IF NOT EXISTS plfull AS (
--all all rows for relevant part/price levels
WITH
----------unique price points-----------------------
lvl AS (
SELECT DISTINCT
plvl
,part
,unit
FROM
cp
)
------------join prices for price level------------
,plj AS (
SELECT
lvl.plvl
,lvl.part
,lvl.unit
,i.jcplcd
,i.jcunit
,i.jcvoll
,i.jcpric
FROM
lvl
INNER JOIN "CMS.CUSLG".iprcbhc hc ON
hc.jbplvl = lvl.plvl
AND current_date BETWEEN hc.jbfdat AND hc.jbtdat
INNER JOIN lgdat.iprcc i ON
i.jcplcd = hc.jbplcd
AND i.jcpart = lvl.part
)
-----------uom conversions-------------------
,uom AS (
SELECT
uom.p part
,uom.f
,uom.t
,uom.nm/uom.dm rate
FROM
(
SELECT
jsonb_agg(row_to_json(d)::jsonb) jdoc
FROM
(
SELECT DISTINCT
part partn
,jcunit fu
,unit tu
FROM
plj
WHERE
part <> ''
) d
) c
JOIN LATERAL rlarp.uom_array(c.jdoc) uom ON TRUE
)
------price list sorted---------------------
SELECT
plj.plvl
,plj.part
,plj.unit
,plj.jcplcd
--,plj.jcunit
,round(plj.jcvoll * uom.rate,5) vol
,round(plj.jcpric / uom.rate,5) price
--,uom.rate
--dont partition by list code becuase there could be duplicate assignments
,row_number() OVER (PARTITION BY plj.plvl, plj.part, plj.unit ORDER BY round(plj.jcvoll * uom.rate,5) ASC) rn
FROM
plj
INNER JOIN uom ON
uom.part = plj.part
AND uom.f = plj.jcunit
AND uom.t = plj.unit
) WITH DATA;
--select * from plfull
CREATE TEMP TABLE IF NOT EXISTS pl AS (
--create from-to volume range for price list
WITH RECURSIVE
pl(plvl, listcode, part, unit, volf, volt, price1, price2, rn, lvl) AS (
SELECT
p1.plvl
,p1.jcplcd as listcode
,p1.part
,p1.unit
,0::numeric volf
,p1.vol volt
,null::numeric price1
,p1.price price2
,p1.rn
,0 lvl
FROM
plfull p1
WHERE
p1.rn = 1
UNION ALL
SELECT
pl.plvl
,COALESCE(f.jcplcd,pl.listcode) listcode
,pl.part
,pl.unit
,pl.volt volf
,COALESCE(f.vol,999999999) volt
,pl.price2 price1
,f.price price2
,f.rn
,pl.lvl + 1
FROM
pl
LEFT OUTER JOIN plfull f ON
f.plvl = pl.plvl
AND f.part = pl.part
AND f.unit = pl.unit
AND f.rn = pl.rn + 1
WHERE
pl.price2 IS NOT NULL
) SEARCH DEPTH FIRST BY part, plvl, unit SET ordercol
SELECT
plvl
,listcode
,part
,unit
,volf
,volt
,numrange(volf, volt) vrange
,price1 price
--,price2
--,rn
--,lvl
--,ordercol
FROM
pl
ORDER BY
ordercol
) WITH DATA;
--select * from pl
--add primary key to test if there are any price level that overlap the same part number
--alter table pl add primary key (plvl, part, unit, vrange);
CREATE TEMP TABLE IF NOT EXISTS cpj AS (
--go back to every unique scenario and join to modified list with volum range
SELECT
cp.*
,pl.price
,pl.listcode
FROM
cp
INNER JOIN pl ON
pl.part = cp.part
AND pl.plvl = cp.plvl
AND pl.unit = cp.unit
WHERE
pl.vrange @> cp.qtyord
) WITH DATA;
--select * from cpj where part = 'TCF06SG0G18C050'
SELECT
jsonb_build_object('list',cpj.price)
||jsonb_build_object('listcode',cpj.listcode)
||jsonb_build_object('plvl',cpj.plvl)
INTO
_rslt
FROM
cpj;
--RAISE NOTICE 'list: %' ,_rslt;
DROP TABLE IF EXISTS cp;
DROP TABLE IF EXISTS plfull;
DROP TABLE IF EXISTS pl;
DROP TABLE IF EXISTS cpj;
RETURN _rslt;
END;
$func$;

View File

@ -1,69 +0,0 @@
DROP TABLE IF EXISTS rlarp.live_quotes_nohist;
CREATE TABLE rlarp.live_quotes_nohist AS
WITH
lq AS MATERIALIZED (
SELECT
lq.*
,substring(lq.part,1,8) mold
FROM
pricequote.live_quotes lq
)
,lqg AS (
SELECT
lq.*
,pricing->'product'->>'mold' part_group
,substring(pricing->'customer'->>'chan',1,1) qchan
,pricing->'customer'->>'cust' qcust
,pricing->'product'->>'itemrel' item_fit
,(pricing->'product'->>'pltq')::numeric pltq
,(pricing->'guidance'->'finalPrice'->>'Price')::numeric guidance
,pricing->'guidance'->'finalPrice'->>'Reason' reason
,(pricing->'product'->>'cstd_usd_ina')::numeric fstd_usd
,(pricing->'guidance'->>'ltp')::numeric ltp
,(pricing->'guidance'->>'optimization')::numeric optimization
,(pricing->'guidance'->>'inflationFactor')::numeric inflation
,jsonb_pretty(pricing) pricing
FROM
lq
LEFT JOIN LATERAL rlarp.guidance_r1(
rlarp.get_guidance_dseg(lq.billto,lq.shipto,substring(lq.part,1,8),lq.v1ds,lq.units_each,2024)
) pricing ON TRUE
WHERE
TRUE
--lq.qstat ~ 'Submitted'
)
--,hist AS (
-- SELECT
-- g.*
-- ,gset.chan
-- --,gset.mold moldh
-- ,gset.v1ds v1dsh
-- ,gset.cust
-- ,gset.vers
-- ,je.k
-- ,seas.*
-- FROM
-- lqg g
-- LEFT OUTER JOIN rlarp.price_pool_dev p ON
-- p.gset @> jsonb_build_object('mold',g.part_group)
-- AND p.gset ? 'cust'
-- AND p.gset ? 'v1ds'
-- LEFT JOIN LATERAL jsonb_to_record(p.gset) AS gset(
-- chan text
-- ,mold text
-- ,v1ds text
-- ,v0ds text
-- ,cust text
-- ,vers text
-- --,nurs text
-- --,ghse text
-- ) ON TRUE
-- LEFT JOIN LATERAL jsonb_each(p.season) je(k,v) on true
-- LEFT JOIN Lateral jsonb_to_record(je.v) as seas(
-- units numeric
-- ,sales_usd numeric
-- ,price_usd numeric
-- ) ON TRUE
--)
SELECT * FROM lqg;

View File

@ -1,70 +0,0 @@
set work_mem TO '4GB';
DROP VIEW IF EXISTS rlarp.live_quotes_review;
CREATE VIEW rlarp.live_quotes_review AS
WITH
lq AS MATERIALIZED (
SELECT
lq.*
,substring(lq.part,1,8) mold
FROM
pricequote.live_quotes lq
)
,lqg AS (
SELECT
lq.*
,pricing->'product'->>'mold' part_group
,substring(pricing->'customer'->>'chan',1,1) qchan
,pricing->'customer'->>'cust' qcust
,pricing->'product'->>'itemrel' item_fit
,(pricing->'product'->>'pltq')::numeric pltq
,(pricing->'guidance'->'finalPrice'->>'Price')::numeric guidance
,pricing->'guidance'->'finalPrice'->>'Reason' reason
,(pricing->'product'->>'cstd_usd_ina')::numeric cstd_usd
,(pricing->'product'->>'fstd_usd_ina')::numeric fstd_usd
,(pricing->'guidance'->>'ltp')::numeric ltp
,(pricing->'guidance'->>'optimization')::numeric optimization
,(pricing->'guidance'->>'inflationFactor')::numeric inflation
,jsonb_pretty(pricing) pricing
FROM
lq
LEFT JOIN LATERAL rlarp.guidance_r1(
rlarp.get_guidance_dseg(lq.billto,lq.shipto,substring(lq.part,1,8),lq.v1ds,lq.units_each,2024)
) pricing ON TRUE
WHERE
lq.qstat ~ 'Submitted'
)
,hist AS (
SELECT
g.*
,gset.chan
--,gset.mold moldh
,gset.v1ds v1dsh
,gset.cust
,gset.vers
,je.k
,seas.*
FROM
lqg g
LEFT OUTER JOIN rlarp.price_pool_dev p ON
p.gset @> jsonb_build_object('mold',g.part_group)
AND p.gset ? 'cust'
AND p.gset ? 'v1ds'
LEFT JOIN LATERAL jsonb_to_record(p.gset) AS gset(
chan text
,mold text
,v1ds text
,v0ds text
,cust text
,vers text
--,nurs text
--,ghse text
) ON TRUE
LEFT JOIN LATERAL jsonb_each(p.season) je(k,v) on true
LEFT JOIN Lateral jsonb_to_record(je.v) as seas(
units numeric
,sales_usd numeric
,price_usd numeric
) ON TRUE
)
SELECT * FROM hist

View File

@ -1,59 +0,0 @@
WITH
lq AS MATERIALIZED (
SELECT
lq.*
,substring(lq.part,1,8) mold
FROM
pricequote.live_quotes lq
)
,lqg AS (
SELECT
lq.*
,m.part_group
,(pricing->'guidance'->'finalPrice'->>'Price')::numeric guidance
,pricing->'guidance'->'finalPrice'->>'Reason' reason
,jsonb_pretty(pricing) pricing
FROM
lq
JOIN LATERAL rlarp.guidance_r1(
rlarp.get_guidance_dseg(lq.billto,lq.shipto,substring(lq.part,1,8),lq.v1ds,lq.units_each,2024)
) pricing ON TRUE
LEFT OUTER JOIN rlarp.molds m ON
m.stlc = lq.mold
WHERE
lq.qstat ~ 'Submitted'
)
,hist AS (
SELECT
g.*
,gset.chan
--,gset.mold moldh
,gset.v1ds v1dsh
,gset.cust
,gset.vers
,je.k
,seas.*
FROM
lqg g
LEFT OUTER JOIN rlarp.price_pool_dev p ON
p.gset @> jsonb_build_object('mold',g.part_group)
AND p.gset ? 'cust'
AND p.gset ? 'v1ds'
LEFT JOIN LATERAL jsonb_to_record(p.gset) AS gset(
chan text
,mold text
,v1ds text
,v0ds text
,cust text
,vers text
--,nurs text
--,ghse text
) ON TRUE
LEFT JOIN LATERAL jsonb_each(p.season) je(k,v) on true
LEFT JOIN Lateral jsonb_to_record(je.v) as seas(
units numeric
,sales_usd numeric
,price_usd numeric
) ON TRUE
)
SELECT * FROM hist WHERE qid = 73059

View File

@ -1,10 +1,9 @@
--CREATE OR REPLACE PROCEDURE rlarp.price_pool() --CREATE OR REPLACE PROCEDURE rlarp.price_pool()
--LANGUAGE plpgsql AS --LANGUAGE plpgsql AS
--$func$ --$func$
--BEGIN; --BEGIN
DROP MATERIALIZED VIEW IF EXISTS rlarp.price_pool_dev CASCADE; DROP TABLE IF EXISTS rlarp.price_pool_dev;
--CREATE TABLE IF NOT EXISTS rlarp.price_pool_dev AS ( CREATE TABLE IF NOT EXISTS rlarp.price_pool_dev AS (
CREATE MATERIALIZED VIEW rlarp.price_pool_dev AS (
WITH WITH
agg AS ( agg AS (
SELECT SELECT
@ -76,76 +75,6 @@ CREATE MATERIALIZED VIEW rlarp.price_pool_dev AS (
HAVING HAVING
round(sum(o.qty),0) > 0 round(sum(o.qty),0) > 0
AND round(sum(o.sales_usd)/sum(o.qty),5) > 0 AND round(sum(o.sales_usd)/sum(o.qty),5) > 0
UNION ALL
SELECT
o.customer
,substring(o.version,1,1) version
,o.chanwide
,o.nursery_region
,c.greenhouse_region
,m.part_group baseitem
,m.majg
,m.assc
,i.coltier
,'v1:' || rtrim(COALESCE(i.coltier, ''))|| '.' || rtrim(substring(COALESCE(i.branding, ''), 1, 1))|| '.' || rtrim(COALESCE(i.uomp, ''))|| '.' || rtrim(COALESCE(i.suffix, ''))|| '.' || rtrim(COALESCE(i.accs_ps, '')) v1dataseg
,_ds.dataseg v0dataseg
,0 oseas
,round(sum(o.qty),0) units
,round(sum(o.sales_usd),0) sales_usd
,round(sum(COALESCE(tp.target_price,tq.target_price) * o.qty),2) target_price
,count(DISTINCT o.ordnum) ordcount
FROM
rlarp.osm_stack o
INNER JOIN "CMS.CUSLG".itemm i ON
i.item = o.part
LEFT OUTER JOIN rlarp.molds m ON
m.stlc = i.stlc
LEFT OUTER JOIN _ds ON
_ds.colgrp = o.colgrp
AND _ds.brand = substring(i.branding,1,1)
LEFT OUTER JOIN pricequote.market_setavgprice tp ON
tp.season = (SELECT ssyr FROM rlarp.gld where drange @> current_date)
AND tp.country = 'ALL'
AND tp.geo = 'ALL'
AND tp.region = 'ALL'
AND tp.mold = i.stlc
AND tp.chan = 'DISTRIB DROP SHIP'
AND tp.data_segment = 'v1:' || rtrim(COALESCE(i.coltier, ''))|| '.' || rtrim(substring(COALESCE(i.branding, ''), 1, 1))|| '.' || rtrim(COALESCE(i.uomp, ''))|| '.' || rtrim(COALESCE(i.suffix, ''))|| '.' || rtrim(COALESCE(i.accs_ps, ''))
LEFT OUTER JOIN pricequote.market_setavgprice tq ON
tq.season = (SELECT ssyr FROM rlarp.gld where drange @> current_date)
AND tq.country = 'ALL'
AND tq.geo = 'ALL'
AND tq.region = 'ALL'
AND tq.mold = i.stlc
AND tq.chan = 'DISTRIB DROP SHIP'
AND tq.data_segment = _ds.dataseg
LEFT OUTER JOIN rlarp.cust c ON
c.code = CASE o.chan WHEN 'DIR' THEN o.bill_cust ELSE o.ship_cust END
WHERE
o.version IN ('Actual','Quotes')
AND o.odate >= current_date - '4 months'::interval
AND o.dsm <> 'PW'
--AND o.part like 'SQL035%'
--AND o.calc_status <> 'CANCELED'
--AND o.fs_line = '41010'
--AND o.dsm <> 'PW'
--AND i.coltier <> 'C'
GROUP BY
o.customer
,substring(o.version,1,1)
,o.chanwide
,o.nursery_region
,c.greenhouse_region
,m.part_group
,m.majg
,m.assc
,i.coltier
,'v1:' || rtrim(COALESCE(i.coltier, ''))|| '.' || rtrim(substring(COALESCE(i.branding, ''), 1, 1))|| '.' || rtrim(COALESCE(i.uomp, ''))|| '.' || rtrim(COALESCE(i.suffix, ''))|| '.' || rtrim(COALESCE(i.accs_ps, ''))
,_ds.dataseg
,o.oseas
HAVING
round(sum(o.qty),0) > 0
AND round(sum(o.sales_usd)/sum(o.qty),5) > 0
) )
,gsets AS ( ,gsets AS (
SELECT SELECT
@ -195,9 +124,8 @@ CREATE MATERIALIZED VIEW rlarp.price_pool_dev AS (
,round(avg(ordcount) ,1) avgordcount ,round(avg(ordcount) ,1) avgordcount
,round(avg(units) ,0) avgunits ,round(avg(units) ,0) avgunits
,round(avg(target_price),5) avgtargetprice ,round(avg(target_price),5) avgtargetprice
,min(oseas) FILTER (WHERE oseas BETWEEN 2020 AND 2023)::text early_season ,min(oseas) FILTER (WHERE oseas BETWEEN 2020 AND 2022)::text early_season
,min(oseas) FILTER (WHERE oseas >= 2024)::text recent_season ,min(oseas) FILTER (WHERE oseas >= 2024)::text recent_season
,max(oseas) FILTER (WHERE oseas >= 2020)::text last_season
--,oseas --,oseas
--,units --,units
--,sales_usd --,sales_usd
@ -231,10 +159,6 @@ CREATE MATERIALIZED VIEW rlarp.price_pool_dev AS (
,recent_season::int ,recent_season::int
,'recent_price' ,'recent_price'
,(season->recent_season->>'price_usd')::numeric ,(season->recent_season->>'price_usd')::numeric
,'last_season'
,last_season::int
,'last_price'
,(season->last_season->>'price_usd')::numeric
) stats ) stats
FROM FROM
find_stats find_stats
@ -242,4 +166,3 @@ CREATE MATERIALIZED VIEW rlarp.price_pool_dev AS (
) WITH DATA; ) WITH DATA;
create index ppd_gset on rlarp.price_pool_dev using gin (gset); create index ppd_gset on rlarp.price_pool_dev using gin (gset);
--END;