mirror of
https://github.com/jambonz/jambonz-api-server.git
synced 2026-10-05 03:13:09 +00:00
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;
|