2023-11-08 12:54:46 -05:00
|
|
|
export function apply_guidance(doc: any) {
|
|
|
|
|
2023-11-15 13:47:00 -05:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-11-15 16:57:21 -05:00
|
|
|
function minExcludingNull(...values) {
|
|
|
|
return values.reduce((min, val) => (val !== null && (min === null || val < min) ? val : min), null);
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------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?.mark?.early_price;
|
|
|
|
const earlyMarkSeason = doc.hist?.mark?.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;
|
2023-11-15 15:26:21 -05:00
|
|
|
|
2023-11-15 16:57:21 -05:00
|
|
|
// ------------------calculate price adders------------------------------------------------------
|
|
|
|
let ltp = qty < pltq ? 0.15 : null;
|
|
|
|
let anchor_sd = priceBand ? ((bridgedPrice - targetPrice) / priceBand).toFixed(2) : 0
|
|
|
|
let optimization = getAdjValue(anchor_sd);
|
|
|
|
let inflReason = inflationFactor !== 0 ? ` +${(inflationFactor *100).toFixed(1)}%`: "";
|
|
|
|
let ltpReason = ltp ? ` +${(ltp * 100).toFixed(1))}%` : "";
|
|
|
|
let optReason = optimization !== 0 ? ` +${(inflationFactor *100).toFixed(1)}%`: "";
|
|
|
|
let custAdder = (ltp ?? 0) + optimization + inflationFactor;
|
|
|
|
let markAdder = (ltp ?? 0) + inflationFactor;
|
|
|
|
let custAddReason = `${inflReason}${ltpReason}${optReason}`;
|
|
|
|
let markAddReason = `${inflReason}${ltpReason}`;
|
2023-11-15 13:47:00 -05:00
|
|
|
|
2023-11-15 16:57:21 -05:00
|
|
|
// ------------------start building price options------------------------------------------------
|
|
|
|
|
|
|
|
let custPrice = bridgedPrice * (1 + custAdder);
|
|
|
|
let custSeason = earlySeason;
|
|
|
|
let custReason = bridgePremium
|
|
|
|
? `${custSeason} (similar + ${altHist} price ${earlyPrice} x ${bridgePremium} = ${custPrice}) + ${custAddReason}`
|
|
|
|
: `${custSeason} + price ${custPrice} + ${custAddReason}`;
|
|
|
|
let markReason = `${markSeason} ASP + ${markPrice} + ${markAddReason}`;
|
|
|
|
let targPrice = targetPrice * (1 + markAdder);
|
|
|
|
let targReason = `Target price ${targetPrice} + ${markAddReason}`;
|
2023-11-15 13:47:00 -05:00
|
|
|
|
2023-11-15 16:57:21 -05:00
|
|
|
let finalPrice = minExcludingNull(listUSD,custPrice,targPrice);
|
2023-11-15 13:47:00 -05:00
|
|
|
|
2023-11-10 16:32:05 -05:00
|
|
|
// ------if there is not target price just exit---------------
|
2023-11-10 16:04:06 -05:00
|
|
|
if (!targetPrice) {
|
|
|
|
anchorSource = "No target pricing setup";
|
2023-11-13 11:02:41 -05:00
|
|
|
guidance.FinalReason = "No target pricing setup";
|
2023-11-10 16:04:06 -05:00
|
|
|
} else {
|
2023-11-10 16:32:05 -05:00
|
|
|
// if there is no customer anchor price use target
|
2023-11-15 16:57:21 -05:00
|
|
|
if (earlyCustPrice) {
|
2023-11-10 16:04:06 -05:00
|
|
|
// translate alternate product history to current product quoted
|
2023-11-10 16:32:05 -05:00
|
|
|
// --------if the price needs bridged, add the details to the description--------
|
|
|
|
if (bridgePremium === 1) {
|
2023-11-15 13:47:00 -05:00
|
|
|
anchorSource = earlySeason + ' Price ' + earlyPrice;
|
2023-11-13 11:45:47 -05:00
|
|
|
custSource = anchorSource;
|
2023-11-10 16:32:05 -05:00
|
|
|
} else {
|
2023-11-15 13:47:00 -05:00
|
|
|
anchorSource = earlySeason + ' Similar (' + altHist + ') Price ' + earlyPrice + ' x ' + bridgePremium + ' = ' + anchorPrice;
|
2023-11-13 11:45:47 -05:00
|
|
|
custSource = anchorSource;
|
2023-11-10 16:32:05 -05:00
|
|
|
}
|
|
|
|
// --------after the early price is translated see if target is still less-------
|
2023-11-10 16:04:06 -05:00
|
|
|
if (targetPrice < anchorPrice) {
|
|
|
|
anchorSource = `Target Price ${targetPrice}`;
|
|
|
|
anchorPrice = targetPrice;
|
|
|
|
}
|
2023-11-10 02:22:23 -05:00
|
|
|
} else {
|
2023-11-10 16:04:06 -05:00
|
|
|
anchorPrice = targetPrice;
|
|
|
|
anchorSource = `Target Price ${targetPrice}`;
|
2023-11-10 02:22:23 -05:00
|
|
|
}
|
2023-11-10 16:32:05 -05:00
|
|
|
//------get the most relevant inflation factor number---------------------------------
|
2023-11-13 12:25:41 -05:00
|
|
|
//------anchor x inflation / fxrate---------------------------------------------------
|
|
|
|
let calcPriceUSD = parseFloat((anchorPrice * inflationFactor).toFixed(5));
|
|
|
|
let calcPrice = parseFloat((calcPriceUSD / fxrate).toFixed(5));
|
2023-11-13 11:02:41 -05:00
|
|
|
if (calcPrice >= list && list) {
|
|
|
|
calcCeiling = "Cap At List";
|
2023-11-13 12:25:41 -05:00
|
|
|
//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}`;
|
|
|
|
}
|
2023-11-10 16:04:06 -05:00
|
|
|
} else {
|
2023-11-13 11:02:41 -05:00
|
|
|
finalPrice = calcPrice;
|
2023-11-13 12:25:41 -05:00
|
|
|
finalPriceUSD = calcPriceUSD;
|
|
|
|
if (curr === "CA") {
|
|
|
|
finalReason = `${anchorSource} x ${inflationFactor} / ${fxrate} FX = ${calcPrice} CAD`;
|
|
|
|
} else {
|
|
|
|
finalReason = `${anchorSource} x ${inflationFactor} = ${calcPrice}`;
|
|
|
|
}
|
2023-11-10 16:04:06 -05:00
|
|
|
}
|
2023-11-10 02:22:23 -05:00
|
|
|
}
|
2023-11-13 11:02:41 -05:00
|
|
|
guidance.AnchorPrice = anchorPrice;
|
|
|
|
guidance.AnchorSource = anchorSource;
|
2023-11-13 11:45:47 -05:00
|
|
|
guidance.CustAnchorPrice = custPrice;
|
|
|
|
guidance.CustAnchorSource = custSource;
|
2023-11-13 11:02:41 -05:00
|
|
|
guidance.InflationFactor = inflationFactor;
|
|
|
|
guidance.Ceiling = calcCeiling;
|
2023-11-13 12:25:41 -05:00
|
|
|
guidance.FinalPriceUSD = finalPriceUSD;
|
|
|
|
guidance.FinalReasonUSD = finalReasonUSD;
|
2023-11-13 11:02:41 -05:00
|
|
|
guidance.FinalPrice = finalPrice;
|
|
|
|
guidance.FinalReason = finalReason;
|
|
|
|
guidance.BridgePremium = bridgePremium;
|
|
|
|
guidance.TargetPrice = targetPrice;
|
2023-11-13 12:43:44 -05:00
|
|
|
guidance.ListPrice = list;
|
2023-11-13 11:02:41 -05:00
|
|
|
doc.guidance = guidance;
|
2023-11-08 12:54:46 -05:00
|
|
|
return doc;
|
|
|
|
}
|