public static BigDecimal calculateFee( final Period period, final BigDecimal amount, final GuaranteeFeeVO guaranteeFee) { Amount result = null; switch (guaranteeFee.getType()) { case FIXED: result = Amount.fixed(guaranteeFee.getFee()); // fall down! case PERCENTAGE: result = result != null ? result : Amount.percentage(guaranteeFee.getFee()); return result.apply(amount); case VARIABLE_ACCORDING_TO_TIME: // it's a compound interest calculation if (period.getBegin().after(period.getEnd())) { throw new IllegalArgumentException( "Can't calculate the guarantee fee. Invalid period time: the begin date must be less than the end date"); } else if (amount.doubleValue() == 0d || guaranteeFee.getFee().doubleValue() == 0d) { return BigDecimal.ZERO; } final double periodInDays = DateHelper.daysBetween(period.getBegin(), period.getEnd()); final double pow = periodInDays / 365D; final double value = (Math.pow(1 + guaranteeFee.getFee().doubleValue() / 100D, pow) - 1) * amount.doubleValue(); return new BigDecimal(value); default: throw new IllegalArgumentException( "Can't calculate the guarantee fee: unknown fee type: " + guaranteeFee.getType()); } }
@Override public Period clone() { Period newPeriod; try { newPeriod = (Period) super.clone(); } catch (final CloneNotSupportedException e) { // this should never happen, since it is Cloneable throw new InternalError(e.getMessage()); } newPeriod.begin = begin == null ? null : (Calendar) begin.clone(); newPeriod.end = end == null ? null : (Calendar) end.clone(); return newPeriod; }