From 6338060b7825ea8d497a534416d6388223280dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20M=C3=BCller?= Date: Wed, 9 Dec 2020 17:26:56 +0100 Subject: [PATCH] BETTERZON-38: Adjusted prices API --- Backend/src/models/prices/prices.router.ts | 35 ++++----- Backend/src/models/prices/prices.service.ts | 80 +++++++++++++++++++++ 2 files changed, 94 insertions(+), 21 deletions(-) diff --git a/Backend/src/models/prices/prices.router.ts b/Backend/src/models/prices/prices.router.ts index 976cc9f..9672efa 100644 --- a/Backend/src/models/prices/prices.router.ts +++ b/Backend/src/models/prices/prices.router.ts @@ -23,7 +23,20 @@ export const pricesRouter = express.Router(); pricesRouter.get('/', async (req: Request, res: Response) => { try { - const prices: Prices = await PriceService.findAll(); + let prices: Prices = []; + const product = req.query.product; + const vendor = req.query.vendor; + const type = req.query.type; + + if (product) { + if (vendor) { + prices = await PriceService.findByVendor( product, vendor, type); + } else { + prices = await PriceService.findByType( product, type); + } + } else { + prices = await PriceService.findAll(); + } res.status(200).send(prices); } catch (e) { @@ -50,26 +63,6 @@ pricesRouter.get('/:id', async (req: Request, res: Response) => { } }); -// GET items/:name - -pricesRouter.get('/products/:id', async (req: Request, res: Response) => { - const id: number = parseInt(req.params.id, 10); - - if (!id) { - res.status(400).send('Missing parameters.'); - return; - } - - try { - const prices: Prices = await PriceService.findByProduct(id); - - res.status(200).send(prices); - } catch (e) { - res.status(404).send(e.message); - } -}); - - // POST items/ // pricesRouter.post('/', async (req: Request, res: Response) => { diff --git a/Backend/src/models/prices/prices.service.ts b/Backend/src/models/prices/prices.service.ts index 81915e7..14846fe 100644 --- a/Backend/src/models/prices/prices.service.ts +++ b/Backend/src/models/prices/prices.service.ts @@ -106,6 +106,86 @@ export const findByProduct = async (product: number): Promise => { return priceRows; }; +export const findByType = async (product: string, type: string): Promise => { + let conn; + let priceRows = []; + try { + conn = await pool.getConnection(); + let rows = []; + if (type === 'newest') { + // Used to get the newest price for this product per vendor + rows = await conn.query(('WITH summary AS ( ' + + 'SELECT p.product_id, ' + + 'p.vendor_id, ' + + 'p.price_in_cents, ' + + 'p.timestamp, ' + + 'ROW_NUMBER() OVER( ' + + 'PARTITION BY p.vendor_id ' + + 'ORDER BY p.timestamp DESC) AS rk ' + + 'FROM prices p ' + + 'WHERE product_id = ?) ' + + 'SELECT s.* ' + + 'FROM summary s ' + + 'WHERE s.rk = 1 '), product); + } else if (type === 'lowest') { + // Used to get the lowest prices for this product over a period of time + rows = await conn.query('SELECT price_id, product_id, vendor_id, MIN(price_in_cents) as price_in_cents, timestamp FROM prices WHERE product_id = ? GROUP BY DAY(timestamp) ORDER BY timestamp', product); + } else { + // If no type is given, return all prices for this product + rows = await conn.query('SELECT price_id, product_id, vendor_id, price_in_cents, timestamp FROM prices WHERE product_id = ?', product); + } + + for (let row in rows) { + if (row !== 'meta') { + priceRows.push(rows[row]); + } + } + + } catch (err) { + throw err; + } finally { + if (conn) { + conn.end(); + } + } + + return priceRows; +}; + +export const findByVendor = async (product: string, vendor: string, type: string): Promise => { + let conn; + let priceRows = []; + try { + conn = await pool.getConnection(); + let rows = []; + if (type === 'newest') { + // Used to get the newest price for this product and vendor + rows = await conn.query('SELECT price_id, product_id, vendor_id, price_in_cents, timestamp FROM prices WHERE product_id = ? AND vendor_id = ? ORDER BY timestamp DESC LIMIT 1', [product, vendor]); + } else if (type === 'lowest') { + // Used to get the lowest prices for this product and vendor in all time + rows = await conn.query('SELECT price_id, product_id, vendor_id, MIN(price_in_cents) as price_in_cents, timestamp FROM prices WHERE product_id = ? AND vendor_id = ? LIMIT 1', [product, vendor]); + } else { + // If no type is given, return all prices for this product and vendor + rows = await conn.query('SELECT price_id, product_id, vendor_id, price_in_cents, timestamp FROM prices WHERE product_id = ? AND vendor_id = ?', [product, vendor]); + } + + for (let row in rows) { + if (row !== 'meta') { + priceRows.push(rows[row]); + } + } + + } catch (err) { + throw err; + } finally { + if (conn) { + conn.end(); + } + } + + return priceRows; +}; + // export const create = async (newItem: Product): Promise => { // let conn; // try {