public class QuoteCalculator{ // Small helper class to represent a product on the quote public class QuoteProduct{ public String name; public Decimal monthlyPrice; public QuoteProduct(String name, Decimal monthlyPrice){ this.name=name; this.monthlyPrice=monthlyPrice; }} // Custom exception for quote rule errors public class QuoteRuleException extends Exception{} // Method to build a quote product list (simulate “add products to quote”) public static List<QuoteProduct> addProductsToQuote(Decimal realTimePrice, Decimal historicalPrice, Decimal newsAnalyticsPrice, Boolean includeRealTime, Boolean includeHistorical, Boolean includeNewsAnalytics ){List<QuoteProduct> products =newList<QuoteProduct>(); if (includeRealTime){ products.add(newQuoteProduct('Real-Time Market Data Feed', realTimePrice)); } if (includeHistorical){ products.add(newQuoteProduct('Historical Data Feed', historicalPrice)); } if (includeNewsAnalytics){ products.add(newQuoteProduct('News Analytics Feed', newsAnalyticsPrice)); } return products; } // Main method: enforces rules, discount and calculates final price public static Decimal calculateFinalQuotePrice(List<QuoteProduct> products, Integer termInMonths ){ if (products==null || products.isEmpty()){ return 0; } if (termInMonths==null || termInMonths <=0){ termInMonths =1; // default} // Flags for rule checking Boolean hasRealTime =false; Boolean hasNewsAnalytics =false; // Sum monthly prices Decimal monthlyTotal =0; for (QuoteProduct p : products){ monthlyTotal +=p.monthlyPrice; if (p.name=='Real-Time Market Data Feed'){ hasRealTime =true; } if (p.name=='News Analytics Feed'){ hasNewsAnalytics =true; }} // Product rule: // NewsAnalyticsFeed requires Real-TimeMarketDataFeed if (hasNewsAnalytics && !hasRealTime){ // Throw exception if rule is not met throw new QuoteRuleException('News Analytics Feed requires Real-Time Market Data Feed.'); } // Discount rule: // If there are 3 products on the quote apply a 10% discount Decimal discountPercent =0; if (products.size()==3){ discountPercent =0.10; // 10% }Decimal discountedMonthlyTotal =monthlyTotal * (1 - discountPercent); // Final quote price for the given term Decimal finalPrice =discountedMonthlyTotal * termInMonths; return finalPrice.setScale(2); }}