Java tutorial
/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.gst.portfolio.interestratechart.domain; import static com.gst.portfolio.interestratechart.InterestRateChartSlabApiConstants.amountRangeFromParamName; import static com.gst.portfolio.interestratechart.InterestRateChartSlabApiConstants.amountRangeToParamName; import static com.gst.portfolio.interestratechart.InterestRateChartSlabApiConstants.annualInterestRateParamName; import static com.gst.portfolio.interestratechart.InterestRateChartSlabApiConstants.descriptionParamName; import static com.gst.portfolio.interestratechart.InterestRateChartSlabApiConstants.fromPeriodParamName; import static com.gst.portfolio.interestratechart.InterestRateChartSlabApiConstants.periodTypeParamName; import static com.gst.portfolio.interestratechart.InterestRateChartSlabApiConstants.toPeriodParamName; import java.math.BigDecimal; import java.util.Locale; import java.util.Map; import javax.persistence.Column; import javax.persistence.Embeddable; import com.gst.infrastructure.core.api.JsonCommand; import com.gst.infrastructure.core.data.DataValidatorBuilder; import com.gst.portfolio.savings.SavingsPeriodFrequencyType; import org.joda.time.Days; import org.joda.time.LocalDate; import org.joda.time.Months; import org.joda.time.Weeks; import org.joda.time.Years; @Embeddable public class InterestRateChartSlabFields { @Column(name = "description", nullable = true) private String description; @Column(name = "period_type_enum", nullable = true) private Integer periodType; @Column(name = "from_period") private Integer fromPeriod; @Column(name = "to_period") private Integer toPeriod; @Column(name = "amount_range_from", scale = 6, precision = 19) private BigDecimal amountRangeFrom; public BigDecimal getAmountRangeFrom() { return this.amountRangeFrom; } public BigDecimal getAmountRangeTo() { return this.amountRangeTo; } @Column(name = "amount_range_to", scale = 6, precision = 19) private BigDecimal amountRangeTo; @Column(name = "annual_interest_rate", scale = 6, precision = 19, nullable = false) private BigDecimal annualInterestRate; @Column(name = "currency_code", nullable = false) private String currencyCode; protected InterestRateChartSlabFields() { // } public static InterestRateChartSlabFields createNew(final String description, final SavingsPeriodFrequencyType periodFrequencyType, final Integer fromPeriod, final Integer toPeriod, final BigDecimal amountRangeFrom, final BigDecimal amountRangeTo, final BigDecimal annualInterestRate, final String currencyCode) { return new InterestRateChartSlabFields(description, periodFrequencyType, fromPeriod, toPeriod, amountRangeFrom, amountRangeTo, annualInterestRate, currencyCode); } private InterestRateChartSlabFields(final String description, final SavingsPeriodFrequencyType periodFrequencyType, final Integer fromPeriod, final Integer toPeriod, final BigDecimal amountRangeFrom, final BigDecimal amountRangeTo, final BigDecimal annualInterestRate, final String currencyCode) { this.description = description; this.periodType = (periodFrequencyType == null || periodFrequencyType.isInvalid()) ? null : periodFrequencyType.getValue(); this.fromPeriod = fromPeriod; this.toPeriod = toPeriod; this.amountRangeFrom = amountRangeFrom; this.amountRangeTo = amountRangeTo; this.annualInterestRate = annualInterestRate; this.currencyCode = currencyCode; } public void update(final JsonCommand command, final Map<String, Object> actualChanges, final DataValidatorBuilder baseDataValidator, final Locale locale) { if (command.isChangeInStringParameterNamed(descriptionParamName, this.description)) { final String newValue = command.stringValueOfParameterNamed(descriptionParamName); actualChanges.put(descriptionParamName, newValue); this.description = newValue; } if (command.isChangeInIntegerParameterNamed(periodTypeParamName, this.periodType, locale)) { final Integer newValue = command.integerValueOfParameterNamed(periodTypeParamName, locale); actualChanges.put(periodTypeParamName, newValue); this.periodType = newValue; } if (command.isChangeInIntegerParameterNamed(fromPeriodParamName, this.fromPeriod, locale)) { final Integer newValue = command.integerValueOfParameterNamed(fromPeriodParamName, locale); actualChanges.put(fromPeriodParamName, newValue); this.fromPeriod = newValue; } if (command.isChangeInIntegerParameterNamed(toPeriodParamName, this.toPeriod, locale)) { final Integer newValue = command.integerValueOfParameterNamed(toPeriodParamName, locale); actualChanges.put(toPeriodParamName, newValue); this.toPeriod = newValue; } if (command.isChangeInBigDecimalParameterNamed(amountRangeFromParamName, this.amountRangeFrom, locale)) { final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(amountRangeFromParamName, locale); actualChanges.put(amountRangeFromParamName, newValue); this.amountRangeFrom = newValue; } if (command.isChangeInBigDecimalParameterNamed(amountRangeToParamName, this.amountRangeTo, locale)) { final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(amountRangeToParamName, locale); actualChanges.put(amountRangeToParamName, newValue); this.amountRangeTo = newValue; } if (command.isChangeInBigDecimalParameterNamed(annualInterestRateParamName, this.annualInterestRate, locale)) { final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(annualInterestRateParamName, locale); actualChanges.put(annualInterestRateParamName, newValue); this.annualInterestRate = newValue; } validateChartSlabPlatformRules(command, baseDataValidator, locale); } public void validateChartSlabPlatformRules(final JsonCommand chartSlabsCommand, final DataValidatorBuilder baseDataValidator, Locale locale) { if (isFromPeriodGreaterThanToPeriod()) { final Integer fromPeriod = chartSlabsCommand.integerValueOfParameterNamed(fromPeriodParamName, locale); baseDataValidator.parameter(fromPeriodParamName).value(fromPeriod) .failWithCode("from.period.is.greater.than.to.period"); } if (isAmountRangeFromGreaterThanTo()) { final BigDecimal amountRangeFrom = chartSlabsCommand .bigDecimalValueOfParameterNamed(amountRangeFromParamName, locale); baseDataValidator.parameter(amountRangeFromParamName).value(amountRangeFrom) .failWithCode("amount.range.from.is.greater.than.amount.range.to"); } } public boolean isFromPeriodGreaterThanToPeriod() { boolean isGreater = false; if (this.toPeriod != null && this.fromPeriod.compareTo(this.toPeriod) > 1) { isGreater = true; } return isGreater; } public boolean isAmountRangeFromGreaterThanTo() { boolean isGreater = false; if (this.amountRangeFrom != null && this.amountRangeTo != null && this.amountRangeFrom.compareTo(this.amountRangeTo) > 1) { isGreater = true; } return isGreater; } public Integer periodType() { return this.periodType; } public Integer fromPeriod() { return this.fromPeriod; } public Integer toPeriod() { return this.toPeriod; } public boolean isRateChartHasGap(final InterestRateChartSlabFields that, final boolean isPrimaryGroupingByAmount) { boolean isPeriodSame = isPeriodsSame(that); boolean isAmountSame = isAmountSame(that); boolean hasPeriods = this.fromPeriod != null || that.fromPeriod != null; boolean hasAmounts = this.amountRangeFrom != null || that.amountRangeFrom != null; if (isPrimaryGroupingByAmount) { if (isAmountSame) { if (hasPeriods) { if (this.toPeriod == null) { return true; } return isNotProperPeriodStart(that.fromPeriod); } } else { return isNotProperAmountStart(that.amountRangeFrom) || isNotProperPeriodStart(that); } } else { if (isPeriodSame) { if (hasAmounts) { if (this.amountRangeTo == null) { return true; } return isNotProperAmountStart(that.amountRangeFrom); } } else { return isNotProperPeriodStart(that.fromPeriod) || isNotProperAmountStart(that); } } return false; } public boolean isValidChart(boolean isPrimaryGroupingByAmount) { return (!isPrimaryGroupingByAmount && this.fromPeriod != null) || (isPrimaryGroupingByAmount && this.amountRangeFrom != null); } public boolean isNotProperChartStart() { return isNotProperPeriodStart(this) || isNotProperAmountStart(this); } public static boolean isNotProperAmountStart(final InterestRateChartSlabFields interestRateChartSlabFields) { return interestRateChartSlabFields.amountRangeFrom != null && (interestRateChartSlabFields.amountRangeFrom.compareTo(BigDecimal.ONE) != 0 && interestRateChartSlabFields.amountRangeFrom.compareTo(BigDecimal.ZERO) != 0); } private boolean isNotProperAmountStart(final BigDecimal amount) { return this.amountRangeTo == null || (amount != null && amount.compareTo(this.amountRangeTo.add(BigDecimal.ONE)) != 0); } private boolean isNotProperPeriodStart(final Integer period) { return this.toPeriod == null || (period != null && period.compareTo(this.toPeriod + 1) != 0); } public static boolean isNotProperPeriodStart(InterestRateChartSlabFields interestRateChartSlabFields) { return interestRateChartSlabFields.fromPeriod != null && !(interestRateChartSlabFields.fromPeriod.equals(1) || interestRateChartSlabFields.fromPeriod.equals(0)); } public boolean isNotProperPriodEnd() { return !(this.toPeriod == null && this.amountRangeTo == null); } public boolean isRateChartOverlapping(final InterestRateChartSlabFields that, final boolean isPrimaryGroupingByAmount) { boolean isPeriodOverLapping = isPeriodOverlapping(that); boolean isAmountOverLapping = isAmountOverlapping(that); boolean isPeriodSame = isPeriodsSame(that); boolean isAmountSame = isAmountSame(that); boolean isOverlapping = false; if (isPrimaryGroupingByAmount) { isOverlapping = (isAmountOverLapping && !isAmountSame) || (isPeriodOverLapping && isAmountSame); } else { isOverlapping = (isPeriodOverLapping && !isPeriodSame) || (isAmountOverLapping && isPeriodSame); } return isOverlapping; } private boolean isPeriodOverlapping(final InterestRateChartSlabFields that) { if (isIntegerSame(that.toPeriod, this.toPeriod)) { return true; } else if (isIntegerSame(that.fromPeriod, this.fromPeriod)) { return true; } else if (this.toPeriod == null) { return true; } else if (that.toPeriod == null) { return that.fromPeriod <= this.toPeriod; } return this.fromPeriod <= that.toPeriod && that.fromPeriod <= this.toPeriod; } private boolean isAmountOverlapping(final InterestRateChartSlabFields that) { if (isBigDecimalSame(that.amountRangeFrom, this.amountRangeFrom)) { return true; } else if (isBigDecimalSame(that.amountRangeTo, this.amountRangeTo)) { return true; } else if (this.amountRangeTo == null) { return true; } else if (that.amountRangeTo == null) { return that.amountRangeFrom.compareTo(this.amountRangeTo) < 1; } return this.amountRangeFrom.compareTo(that.amountRangeTo) < 1 && that.amountRangeFrom.compareTo(this.amountRangeTo) < 1; } public boolean isAmountSame(final InterestRateChartSlabFields that) { return isBigDecimalSame(this.amountRangeFrom, that.amountRangeFrom) && isBigDecimalSame(this.amountRangeTo, that.amountRangeTo); } public boolean isPeriodsSame(final InterestRateChartSlabFields that) { return isIntegerSame(this.fromPeriod, that.fromPeriod) && isIntegerSame(this.toPeriod, that.toPeriod); } public boolean isIntegerSame(final Integer obj1, final Integer obj2) { if (obj1 == null || obj2 == null) { if (obj1 == obj2) { return true; } return false; } return obj1.equals(obj2); } public boolean isBigDecimalSame(final BigDecimal obj1, final BigDecimal obj2) { if (obj1 == null || obj2 == null) { if (obj1 == obj2) { return true; } return false; } return obj1.compareTo(obj2) == 0; } public boolean isBetweenPeriod(final LocalDate periodStartDate, final LocalDate periodEndDate) { final Integer compare = depositPeriod(periodStartDate, periodEndDate); return isPeriodBetween(compare); } public boolean isAmountRangeProvided() { return (this.amountRangeFrom == null) ? false : true; } public BigDecimal annualInterestRate() { return this.annualInterestRate; } public Integer depositPeriod(final LocalDate periodStartDate, final LocalDate periodEndDate) { Integer actualDepositPeriod = 0; final SavingsPeriodFrequencyType periodFrequencyType = SavingsPeriodFrequencyType.fromInt(periodType()); switch (periodFrequencyType) { case DAYS: actualDepositPeriod = Days.daysBetween(periodStartDate, periodEndDate).getDays(); break; case WEEKS: actualDepositPeriod = Weeks.weeksBetween(periodStartDate, periodEndDate).getWeeks(); break; case MONTHS: actualDepositPeriod = Months.monthsBetween(periodStartDate, periodEndDate).getMonths(); break; case YEARS: actualDepositPeriod = Years.yearsBetween(periodStartDate, periodEndDate).getYears(); break; case INVALID: actualDepositPeriod = 0;// default value break; } return actualDepositPeriod; } public boolean isAmountBetween(final BigDecimal depositAmount) { boolean returnValue = true; if (amountRangeFrom != null && amountRangeTo != null) { returnValue = depositAmount.compareTo(amountRangeFrom) >= 0 && depositAmount.compareTo(amountRangeTo) <= 0; } else if (amountRangeFrom != null) { returnValue = depositAmount.compareTo(amountRangeFrom) >= 0; } return returnValue; } public boolean isPeriodBetween(final Integer periods) { boolean returnValue = true; if (fromPeriod != null && toPeriod != null) { returnValue = periods.compareTo(fromPeriod) >= 0 && periods.compareTo(toPeriod) <= 0; } else if (fromPeriod != null) { returnValue = periods.compareTo(fromPeriod) >= 0; } return returnValue; } }