zuora to eloqua | sync zuora eloqua end to end | calculate price test | Search

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.

Run example

npm run import -- "calculate price"

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;

What the code could have been:

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:

  1. Grouping and Filtering:

  2. Product and Pricing Lookup:

  3. Discount Handling:

  4. Price Calculation:

  5. Subtotal and Discount:

  6. TODOs: