PlannedSettlementDetail.java

package com.tradecloud.domain.settlement;

import com.tradecloud.common.base.PersistenceBase;
import com.tradecloud.domain.base.utils.MathUtils;
import com.tradecloud.domain.common.Currency;
import com.tradecloud.domain.document.PaymentState;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.hibernate.annotations.ForeignKey;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import java.math.BigDecimal;
import java.util.Date;

/**
 * Holds common details about planned settlements.
 */
@MappedSuperclass
public class PlannedSettlementDetail extends PersistenceBase implements PlannedSettlementCommon {

    private static final long serialVersionUID = 1L;

    @NotNull
    @XmlAttribute
    protected BigDecimal amount;

    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @XmlElement(name = "Currency", required = true)
    @NotNull
    @ForeignKey(name = "fk_currency")
    protected Currency currency;

    @NotNull
    @XmlAttribute
    protected BigDecimal forwardRate;

    @NotNull
    @XmlElement
    protected boolean overriddenForwardRate;

    @NotNull
    @XmlAttribute
    protected BigDecimal spotRate;

    @NotNull
    @XmlElement
    protected boolean overriddenSpotRate;

    @NotNull
    protected boolean overriddenAmount;

    @NotNull
    protected boolean overriddenSettlementDate;

    @NotNull
    @XmlAttribute
    protected Date settlementDate;

    private String number;

    private BigDecimal percentage;

    protected boolean overriddenPercentage;

    @Enumerated(EnumType.STRING)
    private SettlementSplitPaymentType splitPaymentType = SettlementSplitPaymentType.NO_SPLIT_PAYMENT;

    public PlannedSettlementDetail() {
    }

    public PlannedSettlementDetail(PlannedSettlementDetail detail) {
        this.amount = detail.getAmount();
        this.currency = detail.getCurrency();
        this.spotRate = detail.getSpotRate();
        this.settlementDate = detail.getSettlementDate();
        this.forwardRate = detail.getForwardRate();
        this.number = detail.getNumber();
        this.percentage = detail.percentage;
    }

    @Override
    public BigDecimal getAmount() {
        return amount;
    }

    public void setAmount(BigDecimal amount) {
        this.amount = amount;
    }

    @Override
    public Currency getCurrency() {
        return currency;
    }

    public void setCurrency(Currency currency) {
        this.currency = currency;
    }

    @Override
    public BigDecimal getForwardRate() {
        return forwardRate;
    }

    public void setForwardRate(BigDecimal forwardRate) {
        this.forwardRate = forwardRate;
    }

    @Override
    public BigDecimal getSpotRate() {
        return spotRate;
    }

    public void setSpotRate(BigDecimal spotRate) {
        this.spotRate = spotRate;
    }

    @Override
    public Date getSettlementDate() {
        return settlementDate;
    }

    public void setSettlementDate(Date settlementDate) {
        this.settlementDate = settlementDate;
    }

    @Transient
    @Override
    public String getReference() {
        // Default impl of this so that sub-classes can choose to ignore
        return null;
    }

    public SettlementSplitPaymentType getSplitPaymentType() {
        return splitPaymentType;
    }

    public void setSplitPaymentType(SettlementSplitPaymentType splitPaymentType) {
        this.splitPaymentType = splitPaymentType;
    }

    /**
     * Derives the amount in the costing currency by multiplying the amount by the forwarding rate.
     *
     * @return the derived amount of BigDecimal.ZERO if the amount or forward rate are null
     */
    @Transient
    @Override
    public BigDecimal getAmountInCostingCurrency() {
        if (amount == null || forwardRate == null) {
            return BigDecimal.ZERO;
        }
        return MathUtils.multiply(amount, getForwardRate());
    }

    public boolean isSplitPayment() {
        return getSplitPaymentType() == SettlementSplitPaymentType.SPLIT_PAYMENT_TYPE_1 ||
                getSplitPaymentType() == SettlementSplitPaymentType.SPLIT_PAYMENT_TYPE_2;
    }

    @Override
    public Integer getDays() {
        // Not relevant to all base classes so return null and let the subclasses provide a value if required. Isn't great but saves having to create
        // a new interface with just this method
        return null;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof PlannedSettlementDetail)) {
            return false;
        }
        PlannedSettlementDetail other = (PlannedSettlementDetail) obj;
        return new EqualsBuilder().append(amount, other.amount).append(currency, other.currency).append(spotRate, other.spotRate)
                .append(forwardRate, other.forwardRate).append(settlementDate, other.settlementDate).append(created, other.getCreated()).isEquals();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(amount).append(currency).append(spotRate).append(forwardRate)
                .append(settlementDate).append(created).toHashCode();
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this).append(amount).append(currency).append(spotRate).append(forwardRate).append(settlementDate).toString();
    }

    public boolean isOverriddenForwardRate() {
        return overriddenForwardRate;
    }

    public void setOverriddenForwardRate(boolean overriddenForwardRate) {
        this.overriddenForwardRate = overriddenForwardRate;
    }

    public boolean isOverriddenSpotRate() {
        return overriddenSpotRate;
    }

    @Override
    public PaymentState getPaymentState() {
        return null;
    }

    public void setOverriddenSpotRate(boolean overriddenSpotRate) {
        this.overriddenSpotRate = overriddenSpotRate;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public boolean isOverriddenAmount() {
        return overriddenAmount;
    }

    public void setOverriddenAmount(boolean overriddenAmount) {
        this.overriddenAmount = overriddenAmount;
    }

    public boolean isOverriddenSettlementDate() {
        return overriddenSettlementDate;
    }

    public void setOverriddenSettlementDate(boolean overriddenSettlementDate) {
        this.overriddenSettlementDate = overriddenSettlementDate;
    }

    public BigDecimal getPercentage() {
        return percentage;
    }

    public void setPercentage(BigDecimal percentage) {
        this.percentage = percentage;
    }

    public boolean isOverriddenPercentage() {
        return overriddenPercentage;
    }

    public void setOverriddenPercentage(boolean overriddenPercentage) {
        this.overriddenPercentage = overriddenPercentage;
    }
}