import { Application, Router } from 'https://deno.land/x/oak/mod.ts'; import { Client } from "https://deno.land/x/postgres@v0.17.0/mod.ts"; const app = new Application(); const router = new Router(); //---------dotenv info------------- import { load } from "https://deno.land/std/dotenv/mod.ts"; const env = await load(); const hostname = env["HOSTNAME"]; const port = env["PORT"]; const user = env["USER"]; const password = env["PASSWORD"]; const database = env["DATABASE"]; const app_port = env["APP_PORT"]; // Configure database connection const client = new Client({ hostname:hostname ,port: port ,user: user ,password:password ,database:database ,applicationName: "pricing guidance" }); await client.connect(); // Load SQL from file const query = await Deno.readTextFile("sql/get.pg.sql"); function apply_guidance(doc: any) { let mostRelevantMarketPrice = null; let mostRelevantMarketKey = null; let mostRelevantMarketSeason = null; let highestMarketRelevanceLevel = -1; let mostRelevantCustomerPriceEarly = null; let mostRelevantCustomerPriceRecent = null; let mostRelevantCustomerKey = null; let mostRelevantCustomerSeasonEarly = null; let mostRelevantCustomerSeasonRecent = null; let highestCustomerRelevanceLevel = -1; // Function to update price and assign relevance indicator function setAnchors(items, channelFirstChar, v1ds, v0ds, histKey) { for (let item of items) { // Update the last_price with the most recent price const years = Object.keys(item.season).map(Number).filter(year => year >= 2020); if (years.length > 0) { const recentYear = Math.max(...years.map(Number)); const earlyYear = Math.min(...years.map(Number)); const lastPrice = item.season[recentYear].price_usd; const earlyPrice = item.season[earlyYear].price_usd; item.last_price = lastPrice; item.early_price = earlyPrice; item.last_season = recentYear; item.early_season = earlyYear; } else { item.last_price = null; // or some default value as appropriate } // Initialize relevance as numeric value let marketRelevance = 0; // Assume 0 is 'not relevant' let customerRelevance = 0; // Assume 0 is 'not relevant' // Check if the first character of the item's channel matches the first character of the document's channel if (item.chan.charAt(0) === channelFirstChar) { marketRelevance = 1; // 'relevant' // Further refine relevance based on v1ds and v0ds if (item.v1ds === v1ds) { marketRelevance = 2; // 'most relevant' because v1ds matches // Check for customer relevance if 'cust' key exists customerRelevance = item.cust ? 2 : 1 } else if (item.v0ds === v0ds) { marketRelevance = marketRelevance === 2 ? 2 : 1; // Keep relevance as is if v1ds was matched, otherwise it's just 'relevant' } } // Assign the calculated relevance to the item item.marketRelevance = marketRelevance; item.customerRelevance = customerRelevance; // Update the most relevant market price if this item's relevance is higher and it doesn't have a 'cust' key if (marketRelevance > highestMarketRelevanceLevel) { highestMarketRelevanceLevel = marketRelevance; mostRelevantMarketPrice = item.last_price; mostRelevantMarketKey = histKey; mostRelevantMarketSeason = item.last_season; // Assuming 'season' is the key where the season info is stored } // Update the most relevant customer price if this item's relevance is higher and it has a 'cust' key if (customerRelevance > highestCustomerRelevanceLevel) { highestCustomerRelevanceLevel = customerRelevance; mostRelevantCustomerPriceRecent = item.last_price; mostRelevantCustomerPriceEarly = item.early_price; mostRelevantCustomerKey = histKey; mostRelevantCustomerSeasonRecent = item.last_season; // Assuming 'season' is the key where the season info is stored mostRelevantCustomerSeasonEarly = item.early_season; // Assuming 'season' is the key where the season info is stored } } } // Iterate over each key in the "hist" object for (let key of Object.keys(doc.hist)) { // Update price and relevance for each item in the current key setAnchors(doc.hist[key], doc.chan[0], doc.v1ds, doc.v0ds, key); } // Assign the most relevant market price and key to the top level of the document if (mostRelevantMarketPrice !== null) { doc.mostRelevantMarketPriceInfo = { price: mostRelevantMarketPrice, histKey: mostRelevantMarketKey, season: mostRelevantMarketSeason }; } // Assign the most relevant customer price and key to the top level of the document if (mostRelevantCustomerPriceRecent !== null) { doc.mostRelevantCustomerPriceInfo = { price: mostRelevantCustomerPriceRecent, price_early: mostRelevantCustomerPriceEarly, histKey: mostRelevantCustomerKey, season: mostRelevantCustomerSeasonRecent, season_early: mostRelevantCustomerSeasonEarly }; } doc.targetPrice = doc.v1tp ?? doc.v0tp ?? null; // Determine the anchor price and source if (doc.targetPrice !== undefined && (mostRelevantCustomerPriceEarly === undefined || doc.targetPrice < mostRelevantCustomerPriceEarly)) { doc.anchorPrice = doc.targetPrice; doc.anchorSource = 'Target Price'; } else if (mostRelevantCustomerPriceEarly !== undefined) { doc.anchorPrice = mostRelevantCustomerPriceEarly; doc.anchorSource = mostRelevantCustomerSeasonEarly + ' Customer Price'; } else { doc.anchorPrice = null; doc.anchorSource = 'none'; // or any other default value you wish to indicate no anchor price was found } const inflation = Math.max(...Object.keys(doc.iidx).map(Number)); const inflationFactor = doc.iidx[inflation] + 1; doc.inflationFactor = inflationFactor; var calcPrice = doc.anchorPrice * doc.inflationFactor; calcPrice = parseFloat(calcPrice.toFixed(5)); let finalReason = "" if (calcPrice >= doc.list ) { doc.calcCeiling = "Cap At List"; doc.finalPrice = doc.list; finalReason = `${doc.anchorSource} ${doc.anchorPrice} x ${inflationFactor} = ${calcPrice} but cap at list ${doc.list}`; } else { doc.finalPrice = calcPrice finalReason = `${doc.anchorSource} ${doc.anchorPrice} x ${inflationFactor} = ${calcPrice}`; } doc.finalReason = finalReason; return doc; } // Define a route to retrieve values from the database using parameters router.get('/code_price/:billcode/:shipcode/:partcode/:qty', async (ctx) => { const partcode = ctx.params.partcode; const billcode = ctx.params.billcode; const shipcode = ctx.params.shipcode; const qty = ctx.params.qty; //console.log(partcode) //console.log(customer) const result = await client.queryObject({args: [billcode, shipcode, partcode, qty], text: query} ); const procd = apply_guidance(result.rows[0]["doc"]) ctx.response.body = procd; }); app.use(router.routes()); app.use(router.allowedMethods()); // Start the server console.log('Server is running on http://usmidsap02:8090'); await app.listen({ port: 8090 });