mirror of
https://github.com/jambonz/jambonz-api-server.git
synced 2026-07-04 19:21:53 +00:00
ed51d8b13f
major merge of features from the hosted branch that was created temporarily during the initial launch of jambonz.org
109 lines
4.3 KiB
JavaScript
109 lines
4.3 KiB
JavaScript
const router = require('express').Router();
|
|
const Product = require('../../models/product');
|
|
const {promisePool} = require('../../db');
|
|
const sysError = require('../error');
|
|
const sqlRetrieveSpecialOffers = `SELECT *
|
|
FROM account_offers offer
|
|
LEFT JOIN products AS product ON product.product_sid = offer.product_sid
|
|
WHERE offer.account_sid = ?`;
|
|
|
|
const combineProductAndPrice = (localProducts, product, prices) => {
|
|
const lp = localProducts.find((lp) => lp.category === product.metadata.jambonz_category);
|
|
return {
|
|
product_sid: lp.product_sid,
|
|
name: lp.name,
|
|
category: lp.category,
|
|
stripe_product_id: product.id,
|
|
description: product.description,
|
|
unit_label: product.unit_label,
|
|
prices: prices.map((price) => {
|
|
return {
|
|
stripe_price_id: price.id,
|
|
billing_scheme: price.billing_scheme,
|
|
currency: price.currency,
|
|
recurring: price.recurring,
|
|
tiers_mode: price.tiers_mode,
|
|
tiers: price.tiers,
|
|
type: price.type,
|
|
unit_amount: price.unit_amount,
|
|
unit_amount_decimal: price.unit_amount_decimal
|
|
};
|
|
})
|
|
};
|
|
};
|
|
|
|
|
|
/* list */
|
|
router.get('/', async(req, res) => {
|
|
const logger = req.app.locals.logger;
|
|
const {account_sid} = req.user || {};
|
|
const {listProducts, retrieveProduct, retrievePricesForProduct} = require('../../utils/stripe-utils');
|
|
try {
|
|
const localProducts = await Product.retrieveAll();
|
|
|
|
/**
|
|
* If this request is for a specific account (we have an account_sid)
|
|
* then check to see if we have any special offers for this account
|
|
*/
|
|
const selectedProducts = [];
|
|
if (account_sid) {
|
|
const [r] = await promisePool.query({sql: sqlRetrieveSpecialOffers, nestTables: true}, account_sid);
|
|
logger.debug({r}, `retrieved special offer ids for account_sid ${account_sid}`);
|
|
|
|
if (r.length > 0) {
|
|
/* retrieve all the offers for this account */
|
|
const products = await Promise.all(r.map((row) => retrieveProduct(logger, row.offer.stripe_product_id)));
|
|
logger.debug({products}, `retrieved special offer products for account_sid ${account_sid}`);
|
|
const prices = await Promise.all(products.map((prod) => retrievePricesForProduct(logger, prod.id)));
|
|
logger.debug({prices}, `retrieved special offer prices for account_sid ${account_sid}`);
|
|
|
|
for (let i = 0; i < products.length; i++) {
|
|
selectedProducts.push(combineProductAndPrice(localProducts, products[i], prices[i].data));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* we must return at least pricing for sessions and devices, so find and use
|
|
* the general pricing if no account-specific product was specified for these
|
|
*/
|
|
const haveSessionPricing = selectedProducts.find((prod) => prod.category === 'voice_call_session');
|
|
const haveDevicePricing = selectedProducts.find((prod) => prod.category === 'device');
|
|
|
|
if (haveSessionPricing && haveDevicePricing) {
|
|
logger.debug({selectedProducts}, 'found account level offers for sessions and devices');
|
|
return res.status(200).json(selectedProducts);
|
|
}
|
|
|
|
/* need to get default pricing */
|
|
const allProducts = await listProducts(logger);
|
|
logger.debug({allProducts}, 'retrieved all products');
|
|
const defaultProducts = allProducts.data.filter((prod) =>
|
|
['voice_call_session', 'device'].includes(prod.metadata.jambonz_category) &&
|
|
'general' === prod.metadata.availability);
|
|
logger.debug({defaultProducts}, 'default products');
|
|
|
|
if (!haveSessionPricing) {
|
|
const product = defaultProducts.find((prod) => 'voice_call_session' === prod.metadata.jambonz_category);
|
|
if (product) {
|
|
logger.debug(`retrieving prices for product id ${product.id}`);
|
|
const prices = await retrievePricesForProduct(logger, product.id);
|
|
selectedProducts.push(combineProductAndPrice(localProducts, product, prices.data));
|
|
}
|
|
}
|
|
if (!haveDevicePricing) {
|
|
const product = defaultProducts.find((prod) => 'device' === prod.metadata.jambonz_category);
|
|
if (product) {
|
|
logger.debug(`retrieving prices for product id ${product.id}`);
|
|
const prices = await retrievePricesForProduct(logger, product.id);
|
|
selectedProducts.push(combineProductAndPrice(localProducts, product, prices.data));
|
|
}
|
|
}
|
|
res.status(200).json(selectedProducts);
|
|
} catch (err) {
|
|
sysError(logger, res, err);
|
|
}
|
|
});
|
|
|
|
module.exports = router;
|