This code calculates the total price of a subscription by retrieving product and pricing information from a catalog export and applying discounts, while also identifying areas for future improvement.
npm run import -- "calculate price"
// given a list of subscription IDs and products, calculate the new subscription total using a catalog export and compare with the preview API
// returns [account number, subtotal, previous discount]
function calculatePrice(subscription, products) {
const rpcs = _.groupBy(subscription, r => r['RatePlanCharge.Id']);
const charges = Object.keys(rpcs).map(k => _.sortBy(rpcs[k], r => r['RatePlanCharge.Version']).pop());
var subtotal = 0;
var discount;
var quantity = 0;
charges
// TODO: escelate this to mapDataToFields function?
.filter(c => !(c['ProductRatePlan.Name'] || '').toLowerCase().includes('perpetual'))
.forEach(charge => {
const product = products.filter(p => p['id'] === charge['Product.Id'])[0];
const productRatePlan = product.productRatePlans.filter(p => p['id'] === charge['ProductRatePlan.Id'])[0];
// select correct price plan for the item
const productCharge = productRatePlan.productRatePlanCharges.filter(p => p['id'] === charge['ProductRatePlanCharge.Id'])[0];
const pricing = productCharge.pricing.filter(p => p['currency'] === charge['Account.Currency'])[0];
if((charge['ProductRatePlan.Name'] || '').toLowerCase().includes('discount')
|| (charge['ProductRatePlan.Name'] || '').toLowerCase().includes('volume')) {
// TODO: add handler for quantity based discounts?
discount = pricing.discountPercentage / 100;
} else {
const price = pricing.tiers === null
? pricing.price
: pricing.tiers.filter(t => charge['RatePlanCharge.Quantity'] >= t['startingUnit']
&& charge['RatePlanCharge.Quantity'] <= t['endingUnit'])[0];
if(typeof price === 'undefined') {
throw new Error('unknown rate plan component');
}
quantity += parseInt(charge['RatePlanCharge.Quantity']);
subtotal += parseInt(charge['RatePlanCharge.Quantity']) * price;
}
});
const discounts = charges.filter(c => (c['ProductRatePlan.Name'] || '').toLowerCase().includes('discount') > -1
|| (c['ProductRatePlan.Name'] || '').toLowerCase().includes('volume') > -1)
.filter(c => !(c['ProductRatePlan.Name'] || '').toLowerCase().includes('diamond')
&& !(c['ProductRatePlan.Name'] || '').toLowerCase().includes('distribution'));
assert(!isNaN(subtotal), 'not a number! ' + JSON.stringify(charges, null, 4))
//assert(discounts.length <= 1, 'multiple discounts! ' + JSON.stringify(discounts, null, 4))
return [subscription[0]['Account.AccountNumber'], subtotal, discount, quantity];
}
module.exports = calculatePrice;
const _ = require('lodash');
/**
* Calculates the new subscription total using a catalog export and compares it with the preview API.
*
* @param {Array} subscription - A list of subscription IDs and products.
* @param {Array} products - A list of products.
* @returns {Array} An array containing the account number, subtotal, previous discount, and quantity.
*/
function calculatePrice(subscription, products) {
// Group subscription by rate plan charge ID
const rpcs = _.groupBy(subscription, 'RatePlanCharge.Id');
// Filter and sort charges by rate plan charge version
const charges = Object.keys(rpcs).map(k => _.sortBy(rpcs[k], 'RatePlanCharge.Version')).map(k => k.pop());
// Initialize subtotal, discount, and quantity
let subtotal = 0;
let discount;
let quantity = 0;
// Iterate over charges and filter out perpetual products
charges
.filter(charge =>!charge['ProductRatePlan.Name'].toLowerCase().includes('perpetual'))
.forEach(charge => {
// Find the corresponding product and product rate plan
const product = products.find(p => p.id === charge['Product.Id']);
const productRatePlan = product.productRatePlans.find(p => p.id === charge['ProductRatePlan.Id']);
// Find the correct price plan for the item
const productCharge = productRatePlan.productRatePlanCharges.find(p => p.id === charge['ProductRatePlanCharge.Id']);
const pricing = productCharge.pricing.find(p => p.currency === charge['Account.Currency']);
// Check if the product rate plan name includes 'discount' or 'volume'
if (charge['ProductRatePlan.Name'].toLowerCase().includes('discount') || charge['ProductRatePlan.Name'].toLowerCase().includes('volume')) {
// Calculate discount percentage
discount = pricing.discountPercentage / 100;
} else {
// Calculate price based on quantity
const price = pricing.tiers === null
? pricing.price
: pricing.tiers.find(t => charge['RatePlanCharge.Quantity'] >= t['startingUnit'] && charge['RatePlanCharge.Quantity'] <= t['endingUnit']);
// Check if price is undefined
if (typeof price === 'undefined') {
throw new Error('Unknown rate plan component');
}
// Add quantity and subtotal
quantity += parseInt(charge['RatePlanCharge.Quantity']);
subtotal += parseInt(charge['RatePlanCharge.Quantity']) * price;
}
});
// Filter discounts and ensure only one discount is applied
const discounts = charges.filter(c => (c['ProductRatePlan.Name'] || '').toLowerCase().includes('discount') || (c['ProductRatePlan.Name'] || '').toLowerCase().includes('volume'))
.filter(c =>!(c['ProductRatePlan.Name'] || '').toLowerCase().includes('diamond') &&!(c['ProductRatePlan.Name'] || '').toLowerCase().includes('distribution'));
// Check if subtotal is a number
assert(!isNaN(subtotal), 'Not a number!'+ JSON.stringify(charges, null, 4))
// Return account number, subtotal, discount, and quantity
return [subscription[0]['Account.AccountNumber'], subtotal, discount, quantity];
}
module.exports = calculatePrice;
This code snippet calculates the total price of a subscription based on a list of subscription IDs, products, and a catalog export.
Here's a breakdown:
Grouping and Filtering:
RatePlanCharge.Id
and filters out perpetual charges.Product and Pricing Lookup:
products
array and the catalog export.Discount Handling:
Price Calculation:
Subtotal and Discount:
TODOs:
mapDataToFields
).