VoucherifyUtils { public static BigDecimal calculatePrice(BigDecimal basePrice, VoucherResponse voucher, BigDecimal unitPrice) { if (voucher.getGift() != null) { BigDecimal priceDiscount = valueOf(voucher.getGift().getBalance() / 100.0).min(basePrice); return basePrice.subtract(priceDiscount).setScale(2, RoundingMode.HALF_UP); } Discount discount = voucher.getDiscount(); if (discount.getType() == DiscountType.PERCENT) { validatePercentDiscount(discount); BigDecimal priceDiscount = basePrice.multiply(valueOf(discount.getPercentOff() / 100.0)); return basePrice.subtract(priceDiscount).setScale(2, RoundingMode.HALF_UP); } else if (discount.getType() == DiscountType.AMOUNT) { validateAmountDiscount(discount); BigDecimal amountOff = valueOf(discount.getAmountOff() / 100.0); BigDecimal newPrice = basePrice.subtract(amountOff); return (newPrice.doubleValue() > 0.0 ? newPrice : BigDecimal.valueOf(0)).setScale(2, RoundingMode.HALF_UP); } else if (discount.getType() == DiscountType.UNIT) { validateUnitDiscount(discount); BigDecimal amountOff = unitPrice.multiply(valueOf(discount.getUnitOff())); BigDecimal newPrice = basePrice.subtract(amountOff); return (newPrice.doubleValue() > 0.0 ? newPrice : BigDecimal.valueOf(0)).setScale(2, RoundingMode.HALF_UP); } else { throw new RuntimeException("Unknown voucher type"); } } private  VoucherifyUtils(); static BigDecimal calculatePrice(BigDecimal basePrice, VoucherResponse voucher, BigDecimal unitPrice); static BigDecimal calculateDiscount(BigDecimal basePrice, VoucherResponse voucher, BigDecimal unitPrice);  }
@Test(expected = RuntimeException.class) public void calculatePrice_invalidType_throwException() throws Exception { BigDecimal basePrice = new BigDecimal(10); Discount discount = createFakeDiscount(null, null, null, null, null); VoucherResponse voucherResponse = createFakeVoucherResponse("", true, discount, null, null, null); VoucherifyUtils.calculatePrice(basePrice, voucherResponse, null); }