Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
8ab61b7199 |
10
api.ts
10
api.ts
@ -52,15 +52,7 @@ 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"]);
|
const ag = apply_guidance(result.rows[0]["doc"]);
|
||||||
ctx.response.body = ag.guidance.finalPrice.Snapped;
|
ctx.response.body = ag.guidance.FinalReason;
|
||||||
});
|
|
||||||
|
|
||||||
// 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());
|
||||||
|
@ -1,21 +1,5 @@
|
|||||||
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
|
|
||||||
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 },
|
||||||
@ -30,136 +14,110 @@ export function apply_guidance(doc: any) {
|
|||||||
return match ? match.adj : null;
|
return match ? match.adj : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------set flor prices-------------------------------
|
//let custPrice null;
|
||||||
function getFloor(stlc) {
|
//let custReason null;
|
||||||
switch (stlc) {
|
//let cvolPrice null;
|
||||||
case "SDD10000":
|
//let cvolReason null;
|
||||||
return 0.045;
|
//let markPrice null;
|
||||||
case "SDD10001":
|
//let markReason null;
|
||||||
return 0.045;
|
//let targPrice null;
|
||||||
case "SDD12000":
|
//let targReason null;
|
||||||
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 targetPrice = doc.pricing?.v1tp ?? doc.pricing?.v0tp;
|
||||||
const priceBand = doc.pricing?.v1stdv ?? doc.pricing?.v0stdv;
|
const priceBand = doc.pricing?.v1stdv ?? doc.pricing?.v0stdv;
|
||||||
const earlyCustPrice = doc.hist?.cust?.early_price;
|
const earlyPrice = doc.hist?.cust?.[0]?.early_price;
|
||||||
const earlyCustSeason = doc.hist?.cust?.early_season;
|
const earlySeason = doc.hist?.cust?.[0]?.early_season;
|
||||||
const earlyMarkPrice = doc.hist?.market?.early_price;
|
const bridgePremium = doc.pricing?.bridgePremium ?? 1.00000;
|
||||||
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 altHist = doc.hist?.cust?.ds;
|
||||||
const iidx = doc.pricing?.iidx;
|
const iidx = doc.pricing?.iidx;
|
||||||
const curr = doc.customer?.curr;
|
const curr = doc.customer?.curr;
|
||||||
const fxrate = doc.customer?.fxrate ?? 1.0;
|
const fxrate = doc.customer?.fxrate ?? 1.0;
|
||||||
const qty = doc.inputs?.qty;
|
const qty = doc.inputs?.qty;
|
||||||
const pltq = doc.product?.pltq;
|
const pltq = doc.product?.pltq;
|
||||||
|
let anchorPrice = null;
|
||||||
|
let anchorSource = null;
|
||||||
|
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 ? 1.15 : null;
|
||||||
|
let increase = null;
|
||||||
const inflation = Math.max(...Object.keys(iidx).map(Number));
|
const inflation = Math.max(...Object.keys(iidx).map(Number));
|
||||||
const inflationFactor = iidx[inflation];
|
const inflationFactor = iidx[inflation] + 1;
|
||||||
const list = doc.pricing?.list && doc.product?.itemrel === "2" ? doc.pricing?.list : null;
|
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------------------------------------------------------
|
//-------set basic customer pricing--------------
|
||||||
let ltp = stlc.includes("SDD") || stlc.includes("HZP") ? 0 : (qty < pltq ? 0.15 : null);
|
custPrice = Number((earlyPrice * bridgePremium).toFixed(5));
|
||||||
let anchor_sd = priceBand ? ((bridgedPrice - targetPrice) / priceBand).toFixed(2) : 0
|
anchorPrice = custPrice;
|
||||||
|
let anchor_sd = priceBand ? ((anchorPrice - targetPrice) / priceBand).toFixed(2) : 0
|
||||||
let optimization = getAdjValue(anchor_sd);
|
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;
|
// ------if there is not target price just exit---------------
|
||||||
|
if (!targetPrice) {
|
||||||
let custPrice = r5(bridgedPrice * (1 + custAdder));
|
anchorSource = "No target pricing setup";
|
||||||
let custSeason = earlyCustSeason;
|
guidance.FinalReason = "No target pricing setup";
|
||||||
let custReason = bridgePremium
|
} else {
|
||||||
? `${custSeason} (similar ${altHist} price ${pp(earlyCustPrice)} x ${bridgePremium} = ${pp(bridgedPrice)})${custAddReason}`
|
// if there is no customer anchor price use target
|
||||||
: `${custSeason} price ${pp(bridgedPrice)}${custAddReason}`;
|
if (earlyPrice) {
|
||||||
let markPrice = r5(earlyMarkPrice * (1 + markAdder));
|
// translate alternate product history to current product quoted
|
||||||
let markReason = `${earlyMarkSeason} ASP ${pp(earlyMarkPrice)}${markAddReason}`;
|
// --------if the price needs bridged, add the details to the description--------
|
||||||
let targPrice = targetPrice ? r5(targetPrice * (1 + markAdder)) : null;
|
if (bridgePremium === 1) {
|
||||||
let targReason = `Target price ${pp(targetPrice)}${markAddReason}`;
|
anchorSource = earlySeason + ' Price ' + earlyPrice;
|
||||||
let listPrice = listUSD;
|
custSource = anchorSource;
|
||||||
let listReason = fxrate === 1 ? `list ${pp(list)}` : `list ${pp(list)} CAD ${pp(listUSD)} USD`;
|
} else {
|
||||||
|
anchorSource = earlySeason + ' Similar (' + altHist + ') Price ' + earlyPrice + ' x ' + bridgePremium + ' = ' + anchorPrice;
|
||||||
let prices = {
|
custSource = anchorSource;
|
||||||
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))]
|
|
||||||
}
|
}
|
||||||
|
// --------after the early price is translated see if target is still less-------
|
||||||
let finalPrice = lowestPrice(prices);
|
if (targetPrice < anchorPrice) {
|
||||||
if (floor && floor > finalPrice.Price) {
|
anchorSource = `Target Price ${targetPrice}`;
|
||||||
finalPrice.Price = floor;
|
anchorPrice = targetPrice;
|
||||||
finalPrice.Snapped = floor;
|
|
||||||
finalPrice.Reason = `${finalPrice.Reason} floor at ${floor}`;
|
|
||||||
}
|
}
|
||||||
let guidance = {
|
} else {
|
||||||
prices
|
anchorPrice = targetPrice;
|
||||||
,finalPrice
|
anchorSource = `Target Price ${targetPrice}`;
|
||||||
,targetPrice
|
|
||||||
,listUSD
|
|
||||||
,ltp
|
|
||||||
,inflationFactor
|
|
||||||
,optimization
|
|
||||||
}
|
}
|
||||||
|
//------get the most relevant inflation factor number---------------------------------
|
||||||
|
//------anchor x inflation / fxrate---------------------------------------------------
|
||||||
|
let calcPriceUSD = parseFloat((anchorPrice * inflationFactor).toFixed(5));
|
||||||
|
let calcPrice = parseFloat((calcPriceUSD / fxrate).toFixed(5));
|
||||||
|
if (calcPrice >= list && list) {
|
||||||
|
calcCeiling = "Cap At List";
|
||||||
|
//multiply list by FX to get to USD if in CAD
|
||||||
|
finalPrice = list;
|
||||||
|
if (curr === "CA") {
|
||||||
|
finalReason = `${anchorSource} x ${inflationFactor} / ${fxrate} FX = ${calcPrice} CAD, cap at list ${list} CAD`;
|
||||||
|
} else {
|
||||||
|
finalReason = `${anchorSource} x ${inflationFactor} = ${calcPrice}, cap at list ${list}`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
finalPrice = calcPrice;
|
||||||
|
finalPriceUSD = calcPriceUSD;
|
||||||
|
if (curr === "CA") {
|
||||||
|
finalReason = `${anchorSource} x ${inflationFactor} / ${fxrate} FX = ${calcPrice} CAD`;
|
||||||
|
} else {
|
||||||
|
finalReason = `${anchorSource} x ${inflationFactor} = ${calcPrice}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
guidance.AnchorPrice = anchorPrice;
|
||||||
|
guidance.AnchorSource = anchorSource;
|
||||||
|
guidance.CustAnchorPrice = custPrice;
|
||||||
|
guidance.CustAnchorSource = custSource;
|
||||||
|
guidance.InflationFactor = inflationFactor;
|
||||||
|
guidance.Ceiling = calcCeiling;
|
||||||
|
guidance.FinalPriceUSD = finalPriceUSD;
|
||||||
|
guidance.FinalReasonUSD = finalReasonUSD;
|
||||||
|
guidance.FinalPrice = finalPrice;
|
||||||
|
guidance.FinalReason = finalReason;
|
||||||
|
guidance.BridgePremium = bridgePremium;
|
||||||
|
guidance.TargetPrice = targetPrice;
|
||||||
|
guidance.ListPrice = list;
|
||||||
doc.guidance = guidance;
|
doc.guidance = guidance;
|
||||||
//return doc;
|
return doc;
|
||||||
return sortObjectKeys(doc);
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
@ -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$;
|
|
@ -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'];
|
|
@ -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$;
|
|
@ -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
|
||||||
|
@ -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;
|
||||||
@ -69,52 +65,37 @@ BEGIN
|
|||||||
,idxk
|
,idxk
|
||||||
,prefer
|
,prefer
|
||||||
,pltq
|
,pltq
|
||||||
,curstdus
|
|
||||||
,curstdus_ina
|
|
||||||
,futstdus
|
|
||||||
,futstdus_ina
|
|
||||||
INTO
|
INTO
|
||||||
_mold
|
_mold
|
||||||
,_item
|
,_item
|
||||||
,_iidx
|
,_iidx
|
||||||
,_itemr
|
,_itemr
|
||||||
,_pltq
|
,_pltq
|
||||||
,_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
|
,i.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
|
,i.pltq
|
||||||
,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
|
||||||
@ -128,54 +109,49 @@ BEGIN
|
|||||||
,'itemrel',_itemr
|
,'itemrel',_itemr
|
||||||
,'iidx',_iidx
|
,'iidx',_iidx
|
||||||
,'pltq',_pltq
|
,'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);
|
||||||
|
|
||||||
----------------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 +170,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 +187,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 +221,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);
|
||||||
|
|
||||||
|
@ -110,7 +110,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)
|
||||||
@ -123,8 +123,6 @@ FROM
|
|||||||
--,flag.source
|
--,flag.source
|
||||||
--,rel.prefer
|
--,rel.prefer
|
||||||
--,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC) best
|
--,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC) best
|
||||||
jsonb_strip_nulls(
|
|
||||||
jsonb_build_object(
|
|
||||||
flag.source
|
flag.source
|
||||||
,jsonb_build_object(
|
,jsonb_build_object(
|
||||||
'relevance' ,relevance
|
'relevance' ,relevance
|
||||||
@ -141,11 +139,8 @@ FROM
|
|||||||
,'ds' ,COALESCE(v1ds,v0ds)
|
,'ds' ,COALESCE(v1ds,v0ds)
|
||||||
,'rank' ,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC)
|
,'rank' ,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC)
|
||||||
,'pricinghistory' ,season
|
,'pricinghistory' ,season
|
||||||
)
|
|
||||||
)
|
|
||||||
) 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
|
||||||
@ -154,7 +149,8 @@ FROM
|
|||||||
relevance ~ 'vol|exact'
|
relevance ~ 'vol|exact'
|
||||||
)
|
)
|
||||||
--SELECT jsonb_pretty(jsonb_agg(doc)) FROM rel_sort
|
--SELECT jsonb_pretty(jsonb_agg(doc)) FROM rel_sort
|
||||||
SELECT jsonb_obj_aggc(doc) INTO _result FROM rel_sort WHERE rnk = 1;
|
SELECT jsonb_obj_aggc(doc) INTO _result FROM (SELECT jsonb_build_object(source, jsonb_agg(doc ORDER BY doc->>'rank' ASC)) doc FROM rel_sort GROUP BY source) x;
|
||||||
|
--SELECT jsonb_obj_aggc(doc) INTO _result FROM rel_sort WHERE rnk = 1;
|
||||||
|
|
||||||
RETURN _result;
|
RETURN _result;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
WITH
|
WITH
|
||||||
sel AS (select 'v1:T..PLT..' _v1ds, 'KAWAHARA NURSERY' _cust, 'AZE10001' _mold, 'D' _chan)
|
sel AS (select 'v1:P.P.PLT..' _v1ds, 'ALTMAN PLANTS' _cust, 'XNS0T1G3' _mold, 'D' _chan)
|
||||||
,sort AS (
|
,sort AS (
|
||||||
SELECT
|
SELECT
|
||||||
p.agglevel
|
p.agglevel
|
||||||
@ -53,19 +53,6 @@ sel AS (select 'v1:T..PLT..' _v1ds, 'KAWAHARA NURSERY' _cust, 'AZE10001' _mold,
|
|||||||
source ASC
|
source ASC
|
||||||
,rn 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 (
|
,flag AS (
|
||||||
SELECT
|
SELECT
|
||||||
--agglevel
|
--agglevel
|
||||||
@ -97,7 +84,6 @@ SELECT
|
|||||||
,cust
|
,cust
|
||||||
,vers
|
,vers
|
||||||
,rn
|
,rn
|
||||||
,row_number() OVER (PARTITION BY source ORDER BY rel.prefer ASC) rnk
|
|
||||||
,avgunits
|
,avgunits
|
||||||
,avgordcount
|
,avgordcount
|
||||||
,avgcustcount
|
,avgcustcount
|
||||||
@ -111,25 +97,19 @@ SELECT
|
|||||||
,season
|
,season
|
||||||
FROM
|
FROM
|
||||||
sort
|
sort
|
||||||
LEFT OUTER JOIN rel ON
|
)
|
||||||
rel.flag = CASE source
|
,rel AS (
|
||||||
WHEN 'cust' THEN
|
SELECT * FROM (values
|
||||||
CASE WHEN v1ds IS NOT NULL THEN
|
('customer exact' ,1)
|
||||||
CASE WHEN v1ds_match THEN 'customer exact' ELSE
|
,('customer v0ds other',7)
|
||||||
CASE WHEN rn = 1 THEN 'customer v1ds vol' ELSE 'customer v1ds other' END
|
,('customer v0ds vol' ,3)
|
||||||
END
|
,('customer v1ds other',6)
|
||||||
ELSE
|
,('customer v1ds vol' ,2)
|
||||||
CASE WHEN rn = 1 THEN 'customer v0ds vol' ELSE 'customer v0ds other' END
|
,('market exact' ,4)
|
||||||
END
|
,('market v0ds other' ,9)
|
||||||
ELSE
|
,('market v0ds vol' ,5)
|
||||||
CASE WHEN v1ds IS NOT NULL THEN
|
,('market v1ds other' ,8)
|
||||||
CASE WHEN v1ds_match THEN 'market exact' ELSE
|
) x (flag,prefer)
|
||||||
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 (
|
,rel_sort AS (
|
||||||
SELECT
|
SELECT
|
||||||
@ -137,8 +117,6 @@ FROM
|
|||||||
--,flag.source
|
--,flag.source
|
||||||
--,rel.prefer
|
--,rel.prefer
|
||||||
--,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC) best
|
--,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC) best
|
||||||
jsonb_strip_nulls(
|
|
||||||
jsonb_build_object(
|
|
||||||
flag.source
|
flag.source
|
||||||
,jsonb_build_object(
|
,jsonb_build_object(
|
||||||
'relevance' ,relevance
|
'relevance' ,relevance
|
||||||
@ -153,21 +131,18 @@ FROM
|
|||||||
,'last_season' ,last_season
|
,'last_season' ,last_season
|
||||||
,'last_price' ,last_price
|
,'last_price' ,last_price
|
||||||
,'ds' ,COALESCE(v1ds,v0ds)
|
,'ds' ,COALESCE(v1ds,v0ds)
|
||||||
,'rank' ,rnk
|
,'rank' ,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC)
|
||||||
,'pricinghistory' ,season
|
,'pricinghistory' ,season
|
||||||
)
|
|
||||||
)
|
|
||||||
) doc
|
) doc
|
||||||
,rnk
|
,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC) rnk
|
||||||
,season
|
|
||||||
FROM
|
FROM
|
||||||
flag
|
flag
|
||||||
|
LEFT OUTER JOIN rel ON
|
||||||
|
rel.flag = flag.relevance
|
||||||
WHERE
|
WHERE
|
||||||
relevance ~ 'vol|exact'
|
relevance ~ 'vol|exact'
|
||||||
)
|
)
|
||||||
--SELECT rnk, jsonb_pretty(doc) doc, jsonb_pretty(season) season FROM rel_sort
|
--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_agg(doc)) FROM rel_sort
|
||||||
--SELECT jsonb_pretty(jsonb_obj_aggc(doc)) FROM rel_sort--INTO _result FROM rel_sort WHERE rnk = 1;
|
--SELECT jsonb_pretty(jsonb_obj_aggc(doc)) FROM rel_sort--INTO _result FROM rel_sort WHERE rnk = 1;
|
||||||
--SELECT * FROM rel_sort;
|
SELECT jsonb_build_object(source, jsonb_agg(doc ORDER BY doc->>'rank' ASC)) FROM rel_sort GROUP BY source;
|
||||||
SELECT * FROM flag
|
|
||||||
--SELECT jsonb_obj_aggc(doc) FROM rel_sort WHERE rnk = 1;
|
|
||||||
|
@ -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;
|
|
@ -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,2025)
|
|
||||||
) 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
|
|
@ -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
|
|
@ -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
|
||||||
@ -242,4 +171,4 @@ 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;
|
END;
|
||||||
|
@ -1,129 +0,0 @@
|
|||||||
-- set work_mem TO '4GB';
|
|
||||||
--
|
|
||||||
DROP VIEW IF EXISTS rlarp.quote_review;
|
|
||||||
CREATE VIEW rlarp.quote_review AS
|
|
||||||
WITH
|
|
||||||
lq AS MATERIALIZED (
|
|
||||||
SELECT
|
|
||||||
lq.*
|
|
||||||
,substring(lq.part,1,8) mold
|
|
||||||
FROM
|
|
||||||
pricequote.live_quotes lq
|
|
||||||
WHERE
|
|
||||||
qstat LIKE 'Submitted%'
|
|
||||||
)
|
|
||||||
,lqg AS (
|
|
||||||
SELECT
|
|
||||||
lq.qid
|
|
||||||
,lq.qline
|
|
||||||
,lq.rep
|
|
||||||
,lq.touched
|
|
||||||
,lq.expires
|
|
||||||
,lq.request
|
|
||||||
,lq.qtitle
|
|
||||||
,lq.qstatid
|
|
||||||
,lq.qstat
|
|
||||||
,lq.quotenumber
|
|
||||||
,lq.billto
|
|
||||||
,lq.shipto
|
|
||||||
,lq.qchan
|
|
||||||
,lq.qcustomer
|
|
||||||
,lq.part
|
|
||||||
,lq.qoptions
|
|
||||||
,lq.partbuilt
|
|
||||||
,lq.colgrp
|
|
||||||
,lq.colc
|
|
||||||
,lq.coltier
|
|
||||||
,lq.brand
|
|
||||||
,lq.dataseg
|
|
||||||
,lq.v1ds
|
|
||||||
,lq.comment
|
|
||||||
,lq.units_each
|
|
||||||
,lq.price
|
|
||||||
,lq.sales
|
|
||||||
,lq.histprice
|
|
||||||
,lq.targetp
|
|
||||||
,lq.lastsalesprice
|
|
||||||
,lq.r_curr
|
|
||||||
,lq.qt_rate
|
|
||||||
,lq.qrn
|
|
||||||
,lq.url
|
|
||||||
,lq.tacticalmodifier
|
|
||||||
,lq.finalrecommendedprice
|
|
||||||
,lq.lowerpricelimit
|
|
||||||
,lq.upperpricelimit
|
|
||||||
,(lq.upperpricelimit + lq.lowerpricelimit) / 2 midrange
|
|
||||||
,i.partgroup part_group
|
|
||||||
-- ,pricing->'product'->>'itemrel' item_fit
|
|
||||||
,i.mpck pltq
|
|
||||||
-- ,(pricing->'guidance'->'finalPrice'->>'Price')::numeric guidance
|
|
||||||
-- ,pricing->'guidance'->'finalPrice'->>'Reason' reason
|
|
||||||
,lq.curstdus cstd_usd
|
|
||||||
,lq.futstdus fstd_usd
|
|
||||||
,CASE
|
|
||||||
WHEN i.glec = '1NU' THEN
|
|
||||||
--if more than 8/24 pallets, use floor
|
|
||||||
CASE WHEN units_each >= 24*mpck THEN lq.lowerpricelimit
|
|
||||||
-- if more than a pallet use the target price
|
|
||||||
ELSE CASE WHEN units_each >= 8*mpck THEN (lq.upperpricelimit + lq.lowerpricelimit) / 2
|
|
||||||
-- if more than a pallet use the target price
|
|
||||||
ELSE CASE WHEN units_each >= 4*mpck THEN lq.upperpricelimit
|
|
||||||
-- if more than a pallet use the target price
|
|
||||||
ELSE lq.upperpricelimit * 1.15
|
|
||||||
END END END
|
|
||||||
ELSE
|
|
||||||
--at least 8 pallets is lower limit
|
|
||||||
CASE WHEN units_each >= 08*mpck THEN lq.lowerpricelimit
|
|
||||||
--at least 2 pallets is mid range
|
|
||||||
ELSE CASE WHEN units_each >= 2*mpck THEN (lq.upperpricelimit + lq.lowerpricelimit) / 2
|
|
||||||
--at least 1 pallet is upper range
|
|
||||||
ELSE CASE WHEN units_each >= 1*mpck THEN lq.upperpricelimit
|
|
||||||
--less than a pallet is upper + 15%
|
|
||||||
ELSE lq.upperpricelimit * 1.15
|
|
||||||
END END END
|
|
||||||
END guidance
|
|
||||||
-- ,(pricing->'guidance'->>'ltp')::numeric ltp
|
|
||||||
-- ,(pricing->'guidance'->>'optimization')::numeric optimization
|
|
||||||
-- ,(pricing->'guidance'->>'inflationFactor')::numeric inflation
|
|
||||||
-- ,jsonb_pretty(pricing) pricing
|
|
||||||
FROM
|
|
||||||
lq
|
|
||||||
LEFT OUTER JOIN "CMS.CUSLG".itemm i ON
|
|
||||||
i.item = lq.part
|
|
||||||
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 = 108655
|
|
Loading…
Reference in New Issue
Block a user