export function apply_guidance(doc: any) { 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; } 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 = 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; // ------------------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 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}`; // ------------------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)} CAD ${pp(listUSD)} USD` let prices = { cust: [custPrice, custReason, "cust", ceiling(custPrice,snap)], mark: [markPrice, markReason, "mark", ceiling(markPrice,snap)], targ: [targPrice, targReason, "targ", ceiling(targPrice,snap)], list: [listPrice, listReason, "list", ceiling(listPrice,snap)] } let finalPrice = lowestPrice(prices); let guidance = { prices ,finalPrice } doc.guidance = guidance; return doc; }