I separated the calculatePrice method into calculatePremiumPrice and calculateRegularPrice methods. This made the code easier to visually inspect.
I also made the two blocks of if statements consistent, starting with the lower discounts and working my way up to the larger discounts. Again, this makes the code easier to visually inspect.
I was more measured in my use of blank lines. There's no need to put a blank line after every statement. Use blank lines to separate logical concepts within a method.
If the method code fits on one screen, it's easier to visually inspect.
Finally, I ran all the test cases and formatted the output into currency.
import java.text.NumberFormat; public class ShoppingCartDiscount { static NumberFormat formatter = NumberFormat.getCurrencyInstance(); public static void main(String args[]) { System.out.println("Price for the regular customer: " + formatter.format(calculatePrice("Regular", 5000))); System.out.println("Price for the regular customer: " + formatter.format(calculatePrice("Regular", 10000))); System.out.println("Price for the regular customer: " + formatter.format(calculatePrice("Regular", 15000))); System.out.println(); System.out.println("Price for the premium customer: " + formatter.format(calculatePrice("Premium", 4000))); System.out.println("Price for the premium customer: " + formatter.format(calculatePrice("Premium", 8000))); System.out.println("Price for the premium customer: " + formatter.format(calculatePrice("Premium", 12000))); System.out.println("Price for the premium customer: " + formatter.format(calculatePrice("Premium", 20000))); } static float calculatePrice(String customerType, float purchaseAmount) { float total = 0f; if (customerType.equalsIgnoreCase("Regular")) { total = calculateRegularPrice(purchaseAmount); } else if (customerType.equalsIgnoreCase("Premium")) { total = calculatePremiumPrice(purchaseAmount); } return total; } static float calculateRegularPrice(float purchaseAmount) { float total = 0f; if (purchaseAmount <= 5000) { total = purchaseAmount; } else if (purchaseAmount > 5000 && purchaseAmount <= 10000) { float firstSlab = purchaseAmount - 5000; firstSlab = firstSlab - (float) (firstSlab * 0.1); total = 5000 + firstSlab; } else { float secondSlab = purchaseAmount - 10000; secondSlab = secondSlab - (float) (secondSlab * 0.2); float firstSlab = 10000 - 5000; firstSlab = firstSlab - (float) (firstSlab * 0.1); total = 5000 + firstSlab; total = total + secondSlab; } return total; } static float calculatePremiumPrice(float purchaseAmount) { float total = 0f; if (purchaseAmount <= 4000) { total = purchaseAmount - (float) (purchaseAmount * 0.1); } else if (purchaseAmount > 4000 && purchaseAmount <= 8000) { float secondSlab = purchaseAmount - 4000; secondSlab = secondSlab - (float) (secondSlab * 0.15); float firstSlab = 8000 - 4000; total = firstSlab - (float) (firstSlab * 0.1); total = total + secondSlab; } else if (purchaseAmount > 8000 && purchaseAmount <= 12000) { float thirdSlab = purchaseAmount - 8000; thirdSlab = thirdSlab - (float) (thirdSlab * 0.20); float secondSlab = 8000 - 4000; secondSlab = secondSlab - (float) (secondSlab * 0.15); float firstSlab = 8000 - 4000; total = firstSlab - (float) (firstSlab * 0.1); total = total + secondSlab + thirdSlab; } else { float fourthSlab = purchaseAmount - 12000; fourthSlab = fourthSlab - (float) (fourthSlab * 0.30); float thirdSlab = 8000 - 4000; thirdSlab = thirdSlab - (float) (thirdSlab * 0.20); float secondSlab = 8000 - 4000; secondSlab = secondSlab - (float) (secondSlab * 0.15); float firstSlab = 8000 - 4000; total = firstSlab - (float) (firstSlab * 0.1); total = total + secondSlab + thirdSlab + fourthSlab; } return total; } }
Based on the comment by the OP, I created more adaptable code. I'm not sure what pattern this is, except I used a factory to build the rewards.
I created a Tier class to hold a tier, a Reward class to hold a reward, and a RewardFactory to define the rewards. This should make it easier to change tiers or add new reward types.
If a new reward concept is created, then some code would have to be added.
Here's the revised code.
import java.text.NumberFormat; import java.util.ArrayList; import java.util.List; public class ShoppingCartDiscount { static NumberFormat formatter = NumberFormat.getCurrencyInstance(); public static void main(String args[]) { ShoppingCartDiscount scd = new ShoppingCartDiscount(); RewardFactory rewardFactory = scd.new RewardFactory(); String rewardType = "Regular"; float amount = 5_000f; float discount = rewardFactory.calculateDiscount( rewardType, amount); displayDiscount(rewardType, amount, discount); amount = 10_000f; discount = rewardFactory.calculateDiscount( rewardType, amount); displayDiscount(rewardType, amount, discount); amount = 15_000f; discount = rewardFactory.calculateDiscount( rewardType, amount); displayDiscount(rewardType, amount, discount); System.out.println(); rewardType = "Premium"; amount = 4_000f; discount = rewardFactory.calculateDiscount( rewardType, amount); displayDiscount(rewardType, amount, discount); amount = 8_000f; discount = rewardFactory.calculateDiscount( rewardType, amount); displayDiscount(rewardType, amount, discount); amount = 12_000f; discount = rewardFactory.calculateDiscount( rewardType, amount); displayDiscount(rewardType, amount, discount); amount = 20_000f; discount = rewardFactory.calculateDiscount( rewardType, amount); displayDiscount(rewardType, amount, discount); } static void displayDiscount(String rewardType, float amount, float discount) { System.out.print(rewardType); System.out.print(" customer spends "); System.out.print(formatter.format(amount)); System.out.print(", so we discount "); System.out.print(formatter.format(discount)); System.out.print(", so he owes "); amount -= discount; System.out.print(formatter.format(amount)); System.out.println("."); } public class RewardFactory { private List<Reward> rewards; public RewardFactory() { this.rewards = new ArrayList<>(); createRewards(); } private void createRewards() { Reward reward = new Reward("Regular"); Tier tier = new Tier(0f, 5_000f, 0.00f); reward.addTier(tier); tier = new Tier(5_000f, 10_000f, 0.10f); reward.addTier(tier); tier = new Tier(10_000f, Float.MAX_VALUE, 0.20f); reward.addTier(tier); rewards.add(reward); reward = new Reward("Premium"); tier = new Tier(0f, 4_000f, 0.10f); reward.addTier(tier); tier = new Tier(4_000f, 8_000f, 0.15f); reward.addTier(tier); tier = new Tier(8_000f, 12_000f, 0.20f); reward.addTier(tier); tier = new Tier(12_000f, Float.MAX_VALUE, 0.30f); reward.addTier(tier); rewards.add(reward); } public float calculateDiscount(String rewardType, float amount) { float discount = 0f; for (Reward reward : rewards) { if (reward.isDiscountApplied(rewardType)) { discount += reward.calculateDiscount(amount); } } return discount; } } public class Reward { private final String rewardType; private List<Tier> tiers; public Reward(String rewardType) { this.rewardType = rewardType; this.tiers = new ArrayList<>(); } public void addTier(Tier tier) { this.tiers.add(tier); } public boolean isDiscountApplied(String type) { return (rewardType.equalsIgnoreCase(type)); } public float calculateDiscount(float amount) { float discount = 0f; for (Tier tier : tiers) { if (tier.isDiscountApplied(amount)) { discount += tier.calculateDiscount(amount); } } return discount; } } public class Tier { private final float lowerAmount; private final float upperAmount; private final float percentDiscount; public Tier(float lowerAmount, float upperAmount, float percentDiscount) { this.lowerAmount = lowerAmount; this.upperAmount = upperAmount; this.percentDiscount = percentDiscount; } public boolean isDiscountApplied(float amount) { return (lowerAmount < amount); } public float calculateDiscount(float amount) { if (amount > upperAmount) { return (upperAmount - lowerAmount) * percentDiscount; } else { return (amount - lowerAmount) * percentDiscount; } } } }