com.gst.portfolio.interestratechart.domain.InterestRateChartSlabFields.java Source code

Java tutorial

Introduction

Here is the source code for com.gst.portfolio.interestratechart.domain.InterestRateChartSlabFields.java

Source

/**
 * 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;
    }

}