TransporterCosting.java

package com.tradecloud.domain.transporter;

import com.tradecloud.common.base.PersistenceBase;
import com.tradecloud.domain.common.Currency;
import com.tradecloud.domain.event.Event;
import com.tradecloud.domain.state.Stateful;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;

@Entity
@Table(name = "transporter_costing", uniqueConstraints = {
        @UniqueConstraint(columnNames = {"reference"})})
@Access(AccessType.FIELD)
public class TransporterCosting extends PersistenceBase implements Serializable, Stateful<TransporterState, TransporterEvent> {

    private static final long serialVersionUID = 1L;
    private String reference;
    @ManyToOne
    private Currency currency;

    @NotNull(message = "Date created is required")
    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
    protected Date dateCreated;
    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
    protected Date dateReceived;

    private BigDecimal forwardRate = BigDecimal.ONE;
    private BigDecimal netValue;
    private BigDecimal grossValue;
    private BigDecimal vat;


    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name = "transporter_container_costing", joinColumns = {@JoinColumn(name = "transporter_Costing_id")},
            inverseJoinColumns = {@JoinColumn(name = "Transporter_Container_id")})
    private List<TransporterContainer> transporterContainers;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name = "transporter_costing_costline", joinColumns = {@JoinColumn(name = "transporter_Costing_id")},
            inverseJoinColumns = {@JoinColumn(name = "Transporter_Costline_id")})
    private List<TransporterCostline> transporterCostlines;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @Fetch(value = FetchMode.SUBSELECT)
    @OrderBy("createDateTime")
    private List<TransporterEvent> events = new LinkedList<>();

    @Enumerated(EnumType.STRING)
    private TransporterState state;

    public String getReference() {
        return reference;
    }

    public void setReference(String reference) {
        this.reference = reference;
    }

    public Currency getCurrency() {
        return currency;
    }

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

    public Date getDateCreated() {
        return dateCreated;
    }

    public void setDateCreated(Date dateCreated) {
        this.dateCreated = dateCreated;
    }

    public Date getDateReceived() {
        return dateReceived;
    }

    public void setDateReceived(Date dateReceived) {
        this.dateReceived = dateReceived;
    }

    public BigDecimal getForwardRate() {
        return forwardRate;
    }

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

    public BigDecimal getNetValue() {
        return netValue;
    }

    public void setNetValue(BigDecimal netValue) {
        this.netValue = netValue;
    }

    public BigDecimal getGrossValue() {
        return grossValue;
    }

    public void setGrossValue(BigDecimal grossValue) {
        this.grossValue = grossValue;
    }

    public BigDecimal getVat() {
        return vat;
    }

    public void setVat(BigDecimal vat) {
        this.vat = vat;
    }

    public List<TransporterContainer> getTransporterContainers() {
        return transporterContainers;
    }

    public void setTransporterContainers(List<TransporterContainer> transporterContainers) {
        this.transporterContainers = transporterContainers;
    }

    public List<TransporterCostline> getTransporterCostlines() {
        return transporterCostlines;
    }

    public void setTransporterCostlines(List<TransporterCostline> transporterCostlines) {
        this.transporterCostlines = transporterCostlines;
    }

    public void addTransportContainer(TransporterContainer transporterContainer) {
        transporterContainer.setTransporterCosting(this);
        if (getTransporterContainers() == null) {
            transporterContainers = new ArrayList<>();
        }
        transporterContainers.add(transporterContainer);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof TransporterCosting that)) return false;
        return Objects.equals(getReference(), that.getReference());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getReference());
    }

    public TransporterCosting copy() {
        TransporterCosting copy = new TransporterCosting();
        copy.setReference(this.reference);
        copy.setCurrency(this.currency);

        copy.setDateCreated(this.dateCreated != null ? new Date(this.dateCreated.getTime()) : null);
        copy.setDateReceived(this.dateReceived != null ? new Date(this.dateReceived.getTime()) : null);

        copy.setForwardRate(this.forwardRate != null ? this.forwardRate : BigDecimal.ZERO);
        copy.setNetValue(this.netValue);
        copy.setGrossValue(this.grossValue);
        copy.setVat(this.vat);


        return copy;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this)
                .append("reference", reference)
                .append("netValue", netValue)
                .append("grossValue", grossValue)
                .append("vat", vat)
                .toString();
    }

    public List<TransporterEvent> getEvents() {
        return events;
    }

    @Override
    public boolean inNonEditableState() {
        return false;
    }

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

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

    public TransporterEvent getLastEvent(TransporterEventType eventType) {
        List<TransporterEvent> copyEvents = new ArrayList(events);
        Collections.reverse(copyEvents);
        return Event.getFirstEvent(copyEvents, eventType);
    }

    @Override
    public TransporterState getState() {
        return state;
    }

    @Override
    public void setState(TransporterState state) {
        this.state = state;
    }
}