PackingList.java

package com.tradecloud.domain.container;

import com.tradecloud.common.base.PersistenceBase;
import com.tradecloud.domain.event.Event;
import com.tradecloud.domain.event.PackingListEvent;
import com.tradecloud.domain.model.shipment.PackingListState;
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.validation.constraints.NotNull;
import javax.xml.bind.annotation.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "packinglist")
@Access(AccessType.FIELD)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "PackingList")
@NamedQueries({
        @NamedQuery(name = "packingList.findByShipmentReference", query = "from PackingList pl where pl.shipmentReference = :shipmentReference"),
        @NamedQuery(name = "packingList.findByShipmentId", query = "from PackingList pl where pl.shipmentId = :shipmentId")})
public class PackingList extends PersistenceBase implements Serializable, Stateful<PackingListState, PackingListEvent> {

    private static final long serialVersionUID = 1L;

    @XmlAttribute
    @Column(nullable = false)
    private String shipmentReference;

    // TODO. proper foreign key? Also, not null?
    @XmlAttribute
    private long shipmentId;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "packingList", orphanRemoval = true, fetch = FetchType.LAZY)
    @XmlElementWrapper(name = "PackingListContainers")
    @XmlElement(name = "PackingListContainer")
    @ForeignKey(name = "fk_packinglist")
    @OrderBy("created")
    private List<PackingListContainer> containers = new ArrayList<PackingListContainer>();

    @NotNull
    @XmlElement
    @Enumerated(EnumType.STRING)
    private PackingListState state = PackingListState.UNSIGNED_OFF;
    @OneToMany(
            cascade = {CascadeType.ALL},
            fetch = FetchType.LAZY
    )
    @Fetch(FetchMode.SUBSELECT)
    @XmlElementWrapper(
            name = "PackingListEvents"
    )
    @XmlElement(
            name = "PackingListEvent"
    )
    @OrderBy("createDateTime")
    private List<PackingListEvent> events;

    public String getShipmentReference() {
        return shipmentReference;
    }

    public void setShipmentReference(String shipmentReference) {
        this.shipmentReference = shipmentReference;
    }

    public List<PackingListContainer> getContainers() {
        return containers;
    }

    public void setContainers(List<PackingListContainer> containers) {
        this.containers = containers;
    }

    public void addContainer(PackingListContainer container) {
        container.setPackingList(this);
        containers.add(container);
    }

    public void removeContainer(PackingListContainer container) {
        container.setPackingList(null);
        containers.remove(container);
    }

    public long getShipmentId() {
        return shipmentId;
    }

    public void setShipmentId(long shipmentId) {
        this.shipmentId = shipmentId;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof PackingList)) {
            return false;
        }
        PackingList other = (PackingList) obj;
        return new EqualsBuilder().append(shipmentReference, other.shipmentReference).isEquals();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(shipmentReference).toHashCode();
    }

    public Long getKey() {
        return getId() + PackingList.class.hashCode();
    }

    public boolean isPacked() {
        if (containers != null && !containers.isEmpty()) {
            for (PackingListContainer container : containers) {
                if (container.isPacked()) {
                    return true;
                }
            }
        }
        return false;
    }

    public PackingListState getState() {
        return state;
    }

    public void setState(PackingListState state) {
        this.state = state;
    }

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

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

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

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