OverstayAndStorageTransaction.java

package com.tradecloud.domain.demurrage;

import com.tradecloud.domain.base.utils.DateUtils;
import com.tradecloud.domain.base.utils.ObjectUtil;
import com.tradecloud.domain.comment.AddedComment;
import com.tradecloud.domain.comment.AddedCommentI;
import com.tradecloud.domain.comment.CommentType;
import com.tradecloud.domain.comment.Commentable;
import com.tradecloud.domain.event.Event;
import com.tradecloud.domain.event.OverstayTransactionEvent;
import com.tradecloud.domain.state.Stateful;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.ForeignKey;

import javax.persistence.*;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
 * https://connect.devstream.net/display/Dev/Overstay+and+Storage+Transaction.
 */
@Entity
@Table(name = "overstayandstoragetransaction")
public class OverstayAndStorageTransaction extends DemurrageTransaction implements Commentable,
        Stateful<DemurrageTransactionState, OverstayTransactionEvent> {

    @Temporal(TemporalType.DATE)
    private Date overstayFromDate;

    @Temporal(TemporalType.DATE)
    private Date overstayToDate;

    @Temporal(TemporalType.DATE)
    private Date portStorageFromDate;

    @Temporal(TemporalType.DATE)
    private Date portStorageToDate;

    @ElementCollection(fetch = FetchType.LAZY)
    @CollectionTable(name = "overstayandstoragetransaction_freetextcomments",
            joinColumns = {@JoinColumn(name = "overstayandstoragetransaction_id", unique = false)})
    @Column(name = "reason", unique = true)
    @ForeignKey(name = "fk_overstayandstoragetransaction")
    @Fetch(value = FetchMode.SUBSELECT)
    @XmlElementWrapper(name = "FreeTextComments")
    @XmlElement(name = "FreeTextComment")
    private List<AddedComment> comments = new ArrayList<AddedComment>();

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @Fetch(value = FetchMode.SUBSELECT)
    @ForeignKey(name = "fk_overstaytransaction", inverseName = "fk_overstaytxevent")
    @JoinTable(name = "overstaytx_overstayevent",
            joinColumns = @JoinColumn(name = "overstay_id"),
            inverseJoinColumns = @JoinColumn(name = "overstaytxevent_id"))
    @XmlElementWrapper(name = "OverstayAndStorageTransactionEvents")
    @XmlElement(name = "OverstayAndStorageTransactionEvent")
    @OrderBy("created DESC")
    private List<OverstayTransactionEvent> events = new LinkedList<OverstayTransactionEvent>();

    public Date getOverstayFromDate() {
        return overstayFromDate;
    }

    public void setOverstayFromDate(Date overstayFromDate) {
        this.overstayFromDate = overstayFromDate;
    }

    public Date getOverstayToDate() {
        return overstayToDate;
    }

    public void setOverstayToDate(Date overstayToDate) {
        this.overstayToDate = overstayToDate;
    }

    public Date getPortStorageFromDate() {
        return portStorageFromDate;
    }

    public void setPortStorageFromDate(Date portStorageFromDate) {
        this.portStorageFromDate = portStorageFromDate;
    }

    public Date getPortStorageToDate() {
        return portStorageToDate;
    }

    public void setPortStorageToDate(Date portStorageToDate) {
        this.portStorageToDate = portStorageToDate;
    }

    public int getDaysInOverstay() {
        return ObjectUtil.allNotNull(overstayFromDate, overstayToDate)
                ? (DateUtils.getDaysBetween(overstayFromDate, overstayToDate) + 1) : 0;
    }

    public int getDaysInPortStorage() {
        return ObjectUtil.allNotNull(portStorageFromDate, portStorageToDate)
                ? (DateUtils.getDaysBetween(portStorageFromDate, portStorageToDate) + 1) : 0;
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder()
                .appendSuper(super.hashCode())
                .append(overstayFromDate)
                .append(overstayToDate)
                .append(portStorageFromDate)
                .append(portStorageToDate)
                .toHashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final OverstayAndStorageTransaction other = (OverstayAndStorageTransaction) obj;
        return new EqualsBuilder()
                .appendSuper(super.equals(obj))
                .append(overstayFromDate, other.getOverstayFromDate())
                .append(overstayToDate, other.getOverstayToDate())
                .append(portStorageFromDate, other.getPortStorageFromDate())
                .append(portStorageToDate, other.getPortStorageToDate())
                .isEquals();
    }

    /**
     * @return the comments
     */
    @Override
    public List<AddedComment> getComments() {
        return comments;
    }

    /**
     * @param comments the comments to set
     */
    @Override
    public void setComments(List comments) {
        this.comments = comments;
    }

    private void appendIfNotNull(String stringToAdd, StringBuilder builder) {
        if (stringToAdd != null) {
            if (builder.length() > 0) {
                builder.append(", ");
            }
            builder.append(stringToAdd);
        }
    }

    public String prettyPrintComments() {
        StringBuilder builder = new StringBuilder();
        if (getComments() != null) {
            for (AddedComment co : comments) {
                appendIfNotNull(co.getReason(), builder);
            }
        }
        return builder.toString();
    }

    public void setEvents(List<OverstayTransactionEvent> events) {
        this.events = events;
    }

    @Override
    public OverstayTransactionEvent getLastEvent() {
        return Event.getLastEvent(events);
    }

    @Override
    public boolean inNonEditableState() {
        //editable only in unfinalised state
        return !getState().equals(DemurrageTransactionState.UNFINALISED);
    }

    @Override
    public List<OverstayTransactionEvent> getEvents() {
        return events;
    }

    @Override
    public String getCommentsAsString() {
        return AddedCommentI.commentsAsString(getComments());
    }

    @Override
    public CommentType getCommentType() {
        return CommentType.OVERSTAYANDSTORAGETRANSACTION;
    }
}