Compare commits

..

1 Commits

Author SHA1 Message Date
8ab61b7199 change structure of returned history 2023-11-15 15:27:09 -05:00
14 changed files with 204 additions and 912 deletions

10
api.ts
View File

@ -52,15 +52,7 @@ router.get('/dseg_price/: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;
});
// 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 + ')';
ctx.response.body = ag.guidance.FinalReason;
});
app.use(router.routes());

View File

@ -1,21 +1,5 @@
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) {
const data = [
{f: 2.001, t: 1000, snap: 3, adj: 0 },
@ -30,136 +14,110 @@ export function apply_guidance(doc: any) {
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;
}
}
//let custPrice null;
//let custReason null;
//let cvolPrice null;
//let cvolReason null;
//let markPrice null;
//let markReason null;
//let targPrice null;
//let targReason null;
function lowestPrice(priceObject) {
let Price = Infinity;
let Reason = '';
let Source = '';
let Snapped = Infinity;
const targetPrice = doc.pricing?.v1tp ?? doc.pricing?.v0tp;
const priceBand = doc.pricing?.v1stdv ?? doc.pricing?.v0stdv;
const earlyPrice = doc.hist?.cust?.[0]?.early_price;
const earlySeason = doc.hist?.cust?.[0]?.early_season;
const bridgePremium = doc.pricing?.bridgePremium ?? 1.00000;
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;
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 inflationFactor = iidx[inflation] + 1;
const list = doc.pricing?.list && doc.product?.itemrel === "2" ? doc.pricing?.list : null;
//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;
//-------set basic customer pricing--------------
custPrice = Number((earlyPrice * bridgePremium).toFixed(5));
anchorPrice = custPrice;
let anchor_sd = priceBand ? ((anchorPrice - targetPrice) / priceBand).toFixed(2) : 0
let optimization = getAdjValue(anchor_sd);
// ------if there is not target price just exit---------------
if (!targetPrice) {
anchorSource = "No target pricing setup";
guidance.FinalReason = "No target pricing setup";
} else {
// if there is no customer anchor price use target
if (earlyPrice) {
// translate alternate product history to current product quoted
// --------if the price needs bridged, add the details to the description--------
if (bridgePremium === 1) {
anchorSource = earlySeason + ' Price ' + earlyPrice;
custSource = anchorSource;
} else {
anchorSource = earlySeason + ' Similar (' + altHist + ') Price ' + earlyPrice + ' x ' + bridgePremium + ' = ' + anchorPrice;
custSource = anchorSource;
}
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;
}
// --------after the early price is translated see if target is still less-------
if (targetPrice < anchorPrice) {
anchorSource = `Target Price ${targetPrice}`;
anchorPrice = targetPrice;
}
} else {
anchorPrice = targetPrice;
anchorSource = `Target Price ${targetPrice}`;
}
//------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}`;
}
}
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 = 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
}
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;
//return doc;
return sortObjectKeys(doc);
return 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
_mold,_stlc,_v1ds , _v0ds, _iidx
FROM
"CMS.CUSLG".itemm i
"CMS.CUSLG".itemmv i
INNER JOIN rlarp.molds m ON
m.stlc = i.stlc
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)
RETURNS jsonb
LANGUAGE plpgsql AS
@ -15,10 +15,6 @@ DECLARE
_item text;
_unti text;
_pltq numeric;
_cstd numeric;
_cstdina numeric;
_fstd numeric;
_fstdina numeric;
_cust text;
_curr text;
_rate numeric;
@ -69,52 +65,37 @@ BEGIN
,idxk
,prefer
,pltq
,curstdus
,curstdus_ina
,futstdus
,futstdus_ina
INTO
_mold
,_item
,_iidx
,_itemr
,_pltq
,_cstd
,_cstdina
,_fstd
,_fstdina
FROM
(
SELECT
i.partgroup part_group
m.part_group
,min(i.item) item
,i.stlc
,i.v1ds
,_ds.dataseg 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
,i.v0ds
,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)) 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
"CMS.CUSLG".itemm i
LEFT OUTER JOIN _ds ON
_ds.colgrp = i.colgrp
AND _ds.brand = SUBSTRING(i.branding,1,1)
--INNER JOIN rlarp.molds m ON
-- m.stlc = i.stlc
"CMS.CUSLG".itemmv i
INNER JOIN rlarp.molds m ON
m.stlc = i.stlc
WHERE
i.stlc = _stlc
GROUP BY
i.partgroup
m.part_group
,i.stlc
,i.v1ds
,_ds.dataseg
,i.mpck
,i.v0ds
,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))
,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
ORDER BY
prefer DESC
@ -128,54 +109,49 @@ BEGIN
,'itemrel',_itemr
,'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);
----------------channel-------------------------------------
SELECT rlarp.get_cust(_bill, _ship) INTO _customer;
--_customer := jsonb_build_object('chan',_chan);
SELECT rlarp.channel_code(_bill, _ship) INTO _chan;
_customer := jsonb_build_object('chan',_chan);
----------------customer------------------------------------
--SELECT dba INTO _cust FROM rlarp.cust WHERE code = CASE WHEN _chan = 'DRP' THEN _ship ELSE _bill END ;
--SELECT
-- currency,
-- (SELECT
-- x.rate
-- FROM
-- rlarp.ffcret x
-- WHERE
-- x.perd = (select fspr from rlarp.gld where drange @> current_date)
-- AND x.rtyp = 'MA'
-- and x.fcur = currency
-- AND x.tcur = 'US'
-- )
--INTO
-- _curr
-- ,_rate
--FROM
-- rlarp.cust
--WHERE
-- code = _bill;
SELECT dba INTO _cust FROM rlarp.cust WHERE code = CASE WHEN _chan = 'DRP' THEN _ship ELSE _bill END ;
SELECT
currency,
(SELECT
x.rate
FROM
rlarp.ffcret x
WHERE
x.perd = (select fspr from rlarp.gld where drange @> current_date)
AND x.rtyp = 'MA'
and x.fcur = currency
AND x.tcur = 'US'
)
INTO
_curr
,_rate
FROM
rlarp.cust
WHERE
code = _bill;
--_customer := jsonb_build_object(
-- 'customer',
-- _customer||jsonb_build_object(
-- 'cust',_cust
-- ,'curr',_curr
-- ,'fxrate',_rate
-- )
--);
_customer := jsonb_build_object(
'customer',
_customer||jsonb_build_object(
'cust',_cust
,'curr',_curr
,'fxrate',_rate
)
);
--RAISE NOTICE 'cust %', jsonb_pretty(_customer);
----------------price history-------------------------------
--RAISE NOTICE 'varb %', _customer;
SELECT jsonb_build_object('hist',rlarp.get_hist(_mold, _v1ds, _customer->'customer'->>'cust', substring(_customer->'customer'->>'chan',1,1))) INTO _hist;
SELECT jsonb_build_object('hist',rlarp.get_hist(_mold, _v1ds, _cust, substring(_chan,1,1))) INTO _hist;
--RAISE NOTICE 'history %', jsonb_pretty(_hist);
----------------target pricing------------------------------
@ -194,8 +170,7 @@ BEGIN
mold = _stlc
AND season = _seas
AND data_segment = _v0ds
AND region = 'ALL'
AND chan = _customer->'customer'->>'chantp';
AND region = 'ALL';
----------------target pricing------------------------------
SELECT
jsonb_build_object(
@ -212,8 +187,7 @@ BEGIN
mold = _stlc
AND season = _seas
AND data_segment = _dseg
AND region = 'ALL'
AND chan = _customer->'customer'->>'chantp';
AND region = 'ALL';
--RAISE NOTICE 'target: %', jsonb_pretty(_targ);
_pricing := (COALESCE(_v0tp,'{}'::jsonb)||COALESCE(_v1tp,'{}'::jsonb));
@ -247,7 +221,7 @@ BEGIN
--RAISE NOTICE 'add list: %', jsonb_pretty(_pricing);
----------------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);
--RAISE NOTICE 'add bridge: %', jsonb_pretty(_pricing);

View File

@ -110,7 +110,7 @@ FROM
,('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
,('customer v1ds vol' ,2)
,('market exact' ,4)
,('market v0ds other' ,9)
,('market v0ds vol' ,5)
@ -123,29 +123,24 @@ FROM
--,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' ,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC)
,'pricinghistory' ,season
)
)
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' ,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC)
,'pricinghistory' ,season
) doc
,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC) rnk
,season
FROM
flag
LEFT OUTER JOIN rel ON
@ -154,7 +149,8 @@ FROM
relevance ~ 'vol|exact'
)
--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;

View File

@ -1,5 +1,5 @@
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 (
SELECT
p.agglevel
@ -53,19 +53,6 @@ sel AS (select 'v1:T..PLT..' _v1ds, 'KAWAHARA NURSERY' _cust, 'AZE10001' _mold,
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
@ -97,7 +84,6 @@ SELECT
,cust
,vers
,rn
,row_number() OVER (PARTITION BY source ORDER BY rel.prefer ASC) rnk
,avgunits
,avgordcount
,avgcustcount
@ -111,25 +97,19 @@ SELECT
,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 AS (
SELECT * FROM (values
('customer exact' ,1)
,('customer v0ds other',7)
,('customer v0ds vol' ,3)
,('customer v1ds other',6)
,('customer v1ds vol' ,2)
,('market exact' ,4)
,('market v0ds other' ,9)
,('market v0ds vol' ,5)
,('market v1ds other' ,8)
) x (flag,prefer)
)
,rel_sort AS (
SELECT
@ -137,37 +117,32 @@ FROM
--,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
)
)
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' ,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC)
,'pricinghistory' ,season
) doc
,rnk
,season
,row_number() OVER (PARTITION BY flag.source ORDER BY rel.prefer ASC) rnk
FROM
flag
LEFT OUTER JOIN rel ON
rel.flag = flag.relevance
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;
SELECT jsonb_build_object(source, jsonb_agg(doc ORDER BY doc->>'rank' ASC)) FROM rel_sort GROUP BY source;

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()
--LANGUAGE plpgsql AS
--$func$
--BEGIN;
DROP MATERIALIZED VIEW IF EXISTS rlarp.price_pool_dev CASCADE;
--CREATE TABLE IF NOT EXISTS rlarp.price_pool_dev AS (
CREATE MATERIALIZED VIEW rlarp.price_pool_dev AS (
BEGIN;
DROP TABLE IF EXISTS rlarp.price_pool_dev;
CREATE TABLE IF NOT EXISTS rlarp.price_pool_dev AS (
WITH
agg AS (
SELECT
@ -76,76 +75,6 @@ CREATE MATERIALIZED VIEW rlarp.price_pool_dev AS (
HAVING
round(sum(o.qty),0) > 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 (
SELECT
@ -242,4 +171,4 @@ CREATE MATERIALIZED VIEW rlarp.price_pool_dev AS (
) WITH DATA;
create index ppd_gset on rlarp.price_pool_dev using gin (gset);
--END;
END;