Shipment.java
package com.tradecloud.domain.shipment;
import com.tradecloud.common.base.HibernateUtils;
import com.tradecloud.common.base.PersistenceBase;
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.common.Currency;
import com.tradecloud.domain.common.Incoterm;
import com.tradecloud.domain.container.PackingList;
import com.tradecloud.domain.container.ShipmentContainer;
import com.tradecloud.domain.costing.Costable;
import com.tradecloud.domain.costing.CostableCostDefinition;
import com.tradecloud.domain.costing.CostableType;
import com.tradecloud.domain.costing.CostingContextType;
import com.tradecloud.domain.costing.clean.ActualShipment;
import com.tradecloud.domain.costing.clean.CostingVisitor;
import com.tradecloud.domain.dms.DocumentGroupState;
import com.tradecloud.domain.dms.DocumentManagementHardCoding;
import com.tradecloud.domain.document.CommercialCreditNote;
import com.tradecloud.domain.document.DeliveryNote;
import com.tradecloud.domain.document.DocumentState;
import com.tradecloud.domain.document.ServiceProviderCreditNote;
import com.tradecloud.domain.document.invoice.CommercialInvoice;
import com.tradecloud.domain.document.invoice.Invoiceable;
import com.tradecloud.domain.document.invoice.ServiceProviderInvoice;
import com.tradecloud.domain.event.Event;
import com.tradecloud.domain.event.ShipmentEvent;
import com.tradecloud.domain.event.ShipmentEventType;
import com.tradecloud.domain.item.LineItem;
import com.tradecloud.domain.model.DMSLinked;
import com.tradecloud.domain.model.ordermanagement.Consignment;
import com.tradecloud.domain.model.ordermanagement.Order;
import com.tradecloud.domain.model.organisationalunit.OrganisationalUnit;
import com.tradecloud.domain.model.shipment.ShipmentState;
import com.tradecloud.domain.place.City;
import com.tradecloud.domain.place.PlaceOfDischarge;
import com.tradecloud.domain.place.PlaceOfLoading;
import com.tradecloud.domain.shipment.clearing.CustomsDeclaration;
import com.tradecloud.domain.state.Stateful;
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.*;
import org.hibernate.annotations.ForeignKey;
import javax.persistence.*;
import javax.persistence.AccessType;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
/**
* https://connect.devstream.net/display/Dev/Shipment+Fields.
*/
@Entity
@Table(name = "shipment", uniqueConstraints = {@UniqueConstraint(columnNames = {"number"})})
@Inheritance(strategy = InheritanceType.JOINED)
@Access(AccessType.FIELD)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Shipment")
@XmlSeeAlso({AirShipment.class, SeaShipment.class})
@NamedQueries({
@NamedQuery(name = "findByIdWithConsignmentsLoaded",
query = "from Shipment shipment left join fetch shipment.consignments where shipment.id=:id"),
@NamedQuery(name = "findByIdWithEventsLoaded",
query = "from Shipment shipment left join fetch shipment.events where shipment.id=:id"),
@NamedQuery(name = "findByReferenceNotDeleted",
query = "SELECT shipment FROM Shipment shipment WHERE shipment.reference = :reference AND shipment.state NOT IN ('DELETED')")})
public abstract class Shipment extends PersistenceBase implements Commentable<AddedComment>, Costable,
Invoiceable, Stateful<ShipmentState, ShipmentEvent>,
ShipmentInterface, DMSLinked {
private static final long serialVersionUID = 1L;
public final static Collection<ShipmentState> NON_EDITABLE_STATES = Arrays.asList(ShipmentState.SIGNED_OFF, ShipmentState.DELETED,
ShipmentState.STOCK_FULLY_RECEIVED, ShipmentState.STOCK_PARTIALLY_RECEIVED, ShipmentState.COMPLETE);
public Shipment() {
}
public Shipment(String number, String reference) {
super();
this.number = number;
this.reference = reference;
}
public Shipment(String number, String reference, Set<Transhipment> transhipments) {
super();
this.number = number;
this.reference = reference;
this.transhipments = transhipments;
}
/**
* Our internal system assigned shipment number (this is unique in our
* system).
*/
@XmlAttribute
@NotNull(message = "Shipment number is required")
@Column(nullable = false)
@Size(max = 255)
private String number;
/**
* Third party or external system reference to this shipment.
*/
@XmlAttribute
@Column(nullable = false, unique = true)
@NotNull(message = "Shipment reference is required")
@Size(max = 255)
private String reference;
@NotNull
@XmlElement(name = "ShippingInfo")
@OneToOne(cascade = CascadeType.ALL)
@ForeignKey(name = "fk_shippingInfo")
private ShipmentShippingInfo shippingInfo = new ShipmentShippingInfo();
@XmlAttribute
@Size(max = 255)
private String signedOffBy;
@XmlAttribute
private BigDecimal grossWeight;
@XmlAttribute
private BigDecimal netWeight;
@XmlAttribute
private BigDecimal grossVolume;
@XmlAttribute
private BigDecimal netVolume;
@XmlAttribute
@Temporal(TemporalType.TIMESTAMP)
private Date entryDate;
@XmlAttribute
@Temporal(TemporalType.TIMESTAMP)
private Date actualDepartureDate;
@XmlAttribute
@Temporal(TemporalType.TIMESTAMP)
private Date shippedOnBoardDate;
@XmlAttribute
@Temporal(TemporalType.TIMESTAMP)
private Date warehouseDeliveryDate;
@XmlAttribute
@Temporal(TemporalType.TIMESTAMP)
private Date estimatedArrivalDateAtPlaceOfDischarge;
@XmlAttribute
@Temporal(TemporalType.TIMESTAMP)
private Date originalEstimatedArrivalDateAtPlaceOfDischarge;
@XmlAttribute
@Temporal(TemporalType.TIMESTAMP)
private Date arrivalDateAtPlaceOfDischarge;
@XmlAttribute
@Temporal(TemporalType.TIMESTAMP)
private Date carrierReleaseDate;
@XmlAttribute
@Temporal(TemporalType.TIMESTAMP)
private Date signedOffDate;
@XmlAttribute
@Temporal(TemporalType.TIMESTAMP)
private Date costedDate;
@XmlAttribute
@Temporal(TemporalType.TIMESTAMP)
private Date exFactoryDate;
@XmlAttribute
@Temporal(TemporalType.TIMESTAMP)
private Date scheduledDepartureDate;
@XmlAttribute
@Column
private Date originalDocumentsReceivedDate;
@XmlAttribute
@Column
private Date copyDocumentsReceivedDate;
private Date stateDate;
@XmlElement(name = "DeparturePlace")
@ManyToOne(fetch = FetchType.LAZY)
private PlaceOfLoading departurePlace;
@XmlElement(name = "ArrivalPlace")
@ManyToOne(fetch = FetchType.LAZY)
private PlaceOfDischarge arrivalPlace;
@XmlElementWrapper(name = "Consignments")
@XmlElement(name = "Consignment")
@OrderBy("addedToShipmentDate")
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "shipment", fetch = FetchType.LAZY)
private Set<Consignment> consignments = new LinkedHashSet<Consignment>();
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
@Fetch(value = FetchMode.SELECT)
@XmlElementWrapper(name = "Transhipments")
@XmlElement(name = "Transhipment")
private Set<Transhipment> transhipments = new HashSet<Transhipment>();
@XmlElementWrapper(name = "Containers")
@XmlElement(name = "Container")
@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}, orphanRemoval = true, fetch = FetchType.LAZY)
@Fetch(value = FetchMode.SELECT)
@OrderBy("created")
private Set<ShipmentContainer> containers = new LinkedHashSet<ShipmentContainer>();
@XmlElementWrapper(name = "CommercialInvoices")
@XmlElement(name = "CommercialInvoice")
@OneToMany(orphanRemoval = false, fetch = FetchType.LAZY)
private Set<CommercialInvoice> commercialInvoices = new LinkedHashSet<CommercialInvoice>();
@XmlElementWrapper(name = "CommercialCreditNotes")
@XmlElement(name = "CommercialCreditNotes")
@OneToMany(orphanRemoval = false, fetch = FetchType.LAZY)
private Set<CommercialCreditNote> commercialCreditNotes = new LinkedHashSet<CommercialCreditNote>();
@XmlElementWrapper(name = "ServiceProviderCreditNotes")
@XmlElement(name = "ServiceProviderCreditNotes")
@OneToMany(orphanRemoval = false, fetch = FetchType.LAZY)
private Set<ServiceProviderCreditNote> serviceProviderCreditNotes = new LinkedHashSet<ServiceProviderCreditNote>();
@XmlElementWrapper(name = "ServiceProviderInvoices")
@XmlElement(name = "ServiceProviderInvoice")
@OneToMany(orphanRemoval = false, fetch = FetchType.LAZY)
private Set<ServiceProviderInvoice> serviceProviderInvoices = new LinkedHashSet<ServiceProviderInvoice>();
private transient String shipmentReportUrl;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@OrderBy("created DESC")
private Set<CustomsDeclaration> customsDeclarations;
/**
* Delivery Notes.
*/
@XmlElementWrapper(name = "DeliveryNotes")
@XmlElement(name = "DeliveryNote")
@OneToMany
private Set<DeliveryNote> deliveryNotes = new HashSet<DeliveryNote>();
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "shipment_freetextcomments", joinColumns = {@JoinColumn(name = "shipment_id", unique = false)})
@Column(name = "reason", unique = true)
@ForeignKey(name = "fk_shipment")
@Fetch(value = FetchMode.SELECT)
@XmlElementWrapper(name = "FreeTextComments")
@XmlElement(name = "FreeTextComment")
private List<AddedComment> comments = new ArrayList<AddedComment>();
/**
* ShipmentState INITIALISED after object initialisation. (This is an
* internal state only).
*/
@NotNull
@XmlElement
@Enumerated(EnumType.STRING)
private ShipmentState state = ShipmentState.FINALISED;
/**
* The purchase order events, used to keep track of the history.
*/
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@Fetch(value = FetchMode.SELECT)
@XmlElementWrapper(name = "ShipmentEvents")
@XmlElement(name = "ShipmentEvent")
@OrderBy("createDateTime")
private List<ShipmentEvent> events = new LinkedList<ShipmentEvent>();
@OneToOne(cascade = CascadeType.ALL)
@ForeignKey(name = "fk_packinglist")
@XmlElement(name = "PackingList")
private PackingList packingList;
@OneToOne(cascade = {CascadeType.REMOVE, CascadeType.PERSIST, CascadeType.MERGE}, orphanRemoval = true)
@ForeignKey(name = "fk_costablecostdefinition")
@XmlElement(name = "ShipmentCostableCostDefinition")
private CostableCostDefinition costableCostDefinition;
@OneToOne(cascade = {CascadeType.REMOVE, CascadeType.PERSIST, CascadeType.MERGE}, orphanRemoval = true)
@ForeignKey(name = "fk_costablecostdefinition")
@XmlElement(name = "ShipmentCostableCostDefinition")
private CostableCostDefinition clearingCostableCostDefinition;
@XmlAttribute
@Column
private boolean integrated;
@XmlAttribute
@Column
private Date certificateOfOriginReceivedDate;
@Enumerated(EnumType.STRING)
private DocumentGroupState documentGroupStatus;
@Embedded
private PlaceAddress consolidationPoint;
private Date vesselBerthedDate;
private Date settlementDate;
@XmlElementWrapper(name = "SubShipments")
@XmlElement(name = "SubShipment")
@OneToMany(cascade = {CascadeType.ALL}, orphanRemoval = true, fetch = FetchType.LAZY)
@Fetch(value = FetchMode.SELECT)
@OrderBy("created")
private Set<SubShipment> subShipments = new LinkedHashSet<SubShipment>();
private transient Collection<ServiceProviderInvoice> splitInvoices;
@ManyToOne(fetch = FetchType.LAZY)
@JoinFormula("(SELECT MAX(shipment_shipmentevent.events_id) " +
"FROM shipment_shipmentevent left join shipmentevent on shipment_shipmentevent.events_id = shipmentevent.id " +
"WHERE shipment_shipmentevent.shipment_id = id and shipmentevent.eventtype = 'SIGNED_OFF')")
private ShipmentEvent lastSignedOff;
@Basic(fetch = FetchType.LAZY)
@Formula("(select COALESCE(string_agg(distinct(cd.lrnnumber), ', '),string_agg(distinct(lrn.number), ', ')) from shipment s " +
"left join costsinvoice inv on inv.shipment_id =s.id left join serviceproviderinvoice spi on spi.id= inv.id " +
"left join lrnnumbers lrn on spi.id = lrn.id left join shipment_customsdeclaration scd on (scd.shipment_id=s.id) " +
"left join customsdeclaration cd on (cd.id=scd.customsdeclarations_id) where s.id = id)")
private String lrnNumbers;
@Basic(fetch = FetchType.LAZY)
@Formula("(select COALESCE(string_agg(distinct(cd.mrnnumber), ', '),string_agg(distinct(mrn.number), ', ')) from shipment s " +
"left join costsinvoice inv on inv.shipment_id =s.id left join serviceproviderinvoice spi on spi.id= inv.id " +
"left join mrnnumbers mrn on spi.id = mrn.id left join shipment_customsdeclaration scd on (scd.shipment_id=s.id) " +
"left join customsdeclaration cd on (cd.id=scd.customsdeclarations_id) where s.id=id)")
private String mrnNumbers;
//actual structure, this does not keep costing
@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.REMOVE})
private ActualShipment actualShipment;
//used in a query
private Date lastTariffedDate;
private boolean imports = true;
@Basic(fetch = FetchType.LAZY)
@Formula("(select string_agg(cd.mrnnumber, ', ') from shipment_customsdeclaration scd " +
"left join customsdeclaration cd on cd.id = scd.customsdeclarations_id " +
"left join shipment on shipment.id = scd.shipment_id where shipment.id = id)")
private String clearingMrnNumbers;
@XmlAttribute
@Temporal(TemporalType.TIMESTAMP)
private Date telexReleaseDate;
private transient Date clearingInstructionSignedOffDate;
public ShipmentEvent getLastSignedOff() {
return this.lastSignedOff;
}
@Override
public PackingList getPackingList() {
return packingList;
}
public void setPackingList(PackingList packingList) {
this.packingList = packingList;
}
@Override
public Boolean getActive() {
return state != ShipmentState.DELETED;
}
public void addContainer(ShipmentContainer container) {
container.setShipment(this);
containers.add(container);
}
public void removeContainer(ShipmentContainer container) {
container.setShipment(null);
containers.remove(container);
}
public void addSubShipment(SubShipment subShipment) {
subShipment.setShipment(this);
subShipments.add(subShipment);
}
public void removeSubShipment(SubShipment subShipment) {
subShipment.setShipment(null);
subShipments.remove(subShipment);
}
/**
* Convenience method that adds the supplied service provider invoice into
* the member collection of invoices. The shipment reference is set onto
* this invoice also.
*
* @param serviceProviderInvoice The invoice to add to the member collection
*/
public void addServiceProviderInvoice(ServiceProviderInvoice serviceProviderInvoice) {
serviceProviderInvoice.setShipment(this);
serviceProviderInvoices.add(serviceProviderInvoice);
serviceProviderInvoice.setAddedToShipmentDate(new Date());
}
public void removeServiceProviderInvoiceWhenDeleted(ServiceProviderInvoice serviceProviderInvoice) {
serviceProviderInvoices.remove(serviceProviderInvoice);
}
public void removeServiceProviderCreditNoteWhenDeleted(ServiceProviderCreditNote serviceProviderCreditNote) {
serviceProviderCreditNotes.remove(serviceProviderCreditNote);
}
public void removeCommercialInvoiceWhenDeleted(CommercialInvoice commercialInvoice) {
commercialInvoices.remove(commercialInvoice);
}
public void removeCommercialCreditNoteWhenDeleted(CommercialCreditNote commercialCreditNote) {
commercialCreditNotes.remove(commercialCreditNote);
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getReference() {
return reference;
}
public void setReference(String reference) {
this.reference = reference;
}
public String getSignedOffBy() {
return signedOffBy;
}
public void setSignedOffBy(String signedOffBy) {
this.signedOffBy = signedOffBy;
}
/**
* Returns the supply cost currency.
*
* @return supply cost currency from the first commercial invoice in the list of commercial invoices. If no commercial invoices exist then
* return null
*/
@Transient
public Currency getSupplyCostCurrency() {
if (!commercialInvoices.isEmpty()) {
return commercialInvoices.iterator().next().getCurrency();
}
return null;
}
public BigDecimal getGrossWeight() {
return grossWeight;
}
public void setGrossWeight(BigDecimal grossWeight) {
this.grossWeight = grossWeight;
}
public BigDecimal getNetWeight() {
return netWeight;
}
public void setNetWeight(BigDecimal netWeight) {
this.netWeight = netWeight;
}
public BigDecimal getGrossVolume() {
return grossVolume;
}
public void setGrossVolume(BigDecimal grossVolume) {
this.grossVolume = grossVolume;
}
public BigDecimal getNetVolume() {
return netVolume;
}
public void setNetVolume(BigDecimal netVolume) {
this.netVolume = netVolume;
}
public Date getEntryDate() {
return entryDate;
}
public void setEntryDate(Date entryDate) {
this.entryDate = entryDate;
}
public Date getActualDepartureDate() {
return actualDepartureDate;
}
public void setActualDepartureDate(Date actualDepartureDate) {
this.actualDepartureDate = actualDepartureDate;
}
public Date getWarehouseDeliveryDate() {
return warehouseDeliveryDate;
}
public void setWarehouseDeliveryDate(Date warehouseDeliveryDate) {
this.warehouseDeliveryDate = warehouseDeliveryDate;
}
public Date getCarrierReleaseDate() {
return carrierReleaseDate;
}
public void setCarrierReleaseDate(Date carrierReleaseDate) {
this.carrierReleaseDate = carrierReleaseDate;
}
public Date getSignedOffDate() {
return signedOffDate;
}
public void setSignedOffDate(Date signedOffDate) {
this.signedOffDate = signedOffDate;
}
public Date getCostedDate() {
return costedDate;
}
public void setCostedDate(Date costedDate) {
this.costedDate = costedDate;
}
public Date getExFactoryDate() {
return this.exFactoryDate;
}
public void setExFactoryDate(Date exFactoryDate) {
this.exFactoryDate = exFactoryDate;
}
public Date getScheduledDepartureDate() {
return this.scheduledDepartureDate;
}
public void setScheduledDepartureDate(Date scheduledDepartureDate) {
this.scheduledDepartureDate = scheduledDepartureDate;
}
public Date getOriginalDocumentsReceivedDate() {
return originalDocumentsReceivedDate;
}
public void setOriginalDocumentsReceivedDate(Date originalDocumentsReceivedDate) {
this.originalDocumentsReceivedDate = originalDocumentsReceivedDate;
}
public Date getCopyDocumentsReceivedDate() {
return copyDocumentsReceivedDate;
}
public void setCopyDocumentsReceivedDate(Date copyDocumentsReceivedDate) {
this.copyDocumentsReceivedDate = copyDocumentsReceivedDate;
}
public Set<Transhipment> getTranshipments() {
return transhipments;
}
public void setTranshipments(Set<Transhipment> transhipments) {
this.transhipments = transhipments;
}
public Set<Transhipment> updateTranshipments(Set<Transhipment> transhipments) {
if (this.transhipments == null) {
this.transhipments = transhipments;
} else {
this.transhipments.clear();
this.transhipments.addAll(transhipments);
}
return this.transhipments;
}
/**
* This will return the same result as getActiveCommercialInvoices(),
* the shipment should not have inactive invoices on it.
*
* @return
*/
@Override
public Set<CommercialInvoice> getCommercialInvoices() {
return commercialInvoices;
}
@Override
public Set<CommercialCreditNote> getCommercialCreditNotes() {
return commercialCreditNotes;
}
public Set<ServiceProviderCreditNote> getServiceProviderCreditNotes() {
return serviceProviderCreditNotes;
}
public void setServiceProviderCreditNotes(Set<ServiceProviderCreditNote> serviceProviderCreditNotes) {
this.serviceProviderCreditNotes = serviceProviderCreditNotes;
}
@Override
public void setCommercialInvoices(Set<CommercialInvoice> commercialInvoices) {
this.commercialInvoices = commercialInvoices;
}
@Override
public void setCommercialCreditNotes(Set<CommercialCreditNote> commercialCreditNotes) {
this.commercialCreditNotes = commercialCreditNotes;
}
public List<CommercialInvoice> getActiveCommercialInvoices() {
return PersistenceBase.getActiveList(commercialInvoices);
}
public List<CommercialCreditNote> getActiveCommercialCreditNotes() {
return PersistenceBase.getActiveList(commercialCreditNotes);
}
/**
* This will return the same result as getActiveServiceProviderInvoices(),
* the shipment should not have inactive invoices on it.
*
* @return
*/
@Override
public Set<ServiceProviderInvoice> getServiceProviderInvoices() {
return serviceProviderInvoices;
}
@Override
public void setServiceProviderInvoices(Set<ServiceProviderInvoice> serviceProviderInvoices) {
this.serviceProviderInvoices = serviceProviderInvoices;
}
public List<ServiceProviderInvoice> getActiveServiceProviderInvoices() {
return PersistenceBase.getActiveList(serviceProviderInvoices);
}
public List<ServiceProviderCreditNote> getActiveServiceProviderCreditNotes() {
return PersistenceBase.getActiveList(serviceProviderCreditNotes);
}
public Set<DeliveryNote> getDeliveryNotes() {
return deliveryNotes;
}
public void setDeliveryNotes(Set<DeliveryNote> deliveryNotes) {
this.deliveryNotes = deliveryNotes;
}
@Override
public List<AddedComment> getComments() {
return comments;
}
@Override
public void setComments(List<AddedComment> Comments) {
this.comments = Comments;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
public Set<Consignment> getConsignments() {
return Collections.unmodifiableSet(consignments);
}
public void setConsignments(Set<Consignment> consignments) {
this.consignments = consignments;
}
public List<Consignment> getActiveConsignments() {
return PersistenceBase.getActiveList(consignments);
}
public void addConsignment(Consignment consignment) {
consignments.add(consignment);
consignment.setShipment(this);
// To workaround the copy case
if (consignment.getAddedToShipmentDate() == null) {
consignment.setAddedToShipmentDate(new Date());
}
}
public void removeConsignment(Consignment consignment) {
consignment.setShipment(null);
consignment.setAddedToShipmentDate(null);
consignments.remove(consignment);
}
//use shippinginfo
@Deprecated
public PlaceOfLoading getDeparturePlace() {
return departurePlace;
}
//use shippinginfo
@Deprecated
public void setDeparturePlace(PlaceOfLoading departurePlace) {
this.departurePlace = departurePlace;
}
//use shippinginfo
@Deprecated
public PlaceOfDischarge getArrivalPlace() {
return arrivalPlace;
}
//use shippinginfo
@Deprecated
public void setArrivalPlace(PlaceOfDischarge arrivalPlace) {
this.arrivalPlace = arrivalPlace;
}
@Override
public CostableType getCostableType() {
return CostableType.SHIPMENT;
}
@Override
public Set<ShipmentContainer> getContainers() {
return containers;
}
public void setContainers(Set<ShipmentContainer> containers) {
this.containers = containers;
}
@Override
public Date getArrivalDateAtPlaceOfDischarge() {
return arrivalDateAtPlaceOfDischarge;
}
public void setArrivalDateAtPlaceOfDischarge(Date arrivalDateAtPlaceOfDischarge) {
this.arrivalDateAtPlaceOfDischarge = arrivalDateAtPlaceOfDischarge;
}
@Override
public List<LineItem> getLineItems() {
List<LineItem> lineItems = new ArrayList<>();
for (Consignment consignment : consignments) {
lineItems.addAll(consignment.getLineItems());
}
return lineItems;
}
@Override
public List<Order> getOrders() {
List<Order> orders = new ArrayList<>();
for (Consignment consignment : consignments) {
orders.addAll(consignment.getActiveOrders());
}
return orders;
}
@Override
public ShipmentState getState() {
return state;
}
@Override
public void setState(ShipmentState state) {
this.state = state;
}
@Override
public List<ShipmentEvent> getEvents() {
return events;
}
public void setEvents(List<ShipmentEvent> events) {
this.events = events;
}
@Override
public ShipmentEvent getLastEvent() {
return Event.getLastEvent(events);
}
@Override
public Date getEstimatedArrivalDateAtPlaceOfDischarge() {
return estimatedArrivalDateAtPlaceOfDischarge;
}
public void setEstimatedArrivalDateAtPlaceOfDischarge(Date estimatedArrivalDateAtPlaceOfDischarge) {
this.estimatedArrivalDateAtPlaceOfDischarge = estimatedArrivalDateAtPlaceOfDischarge;
if (this.originalEstimatedArrivalDateAtPlaceOfDischarge == null && estimatedArrivalDateAtPlaceOfDischarge != null) {
this.originalEstimatedArrivalDateAtPlaceOfDischarge = estimatedArrivalDateAtPlaceOfDischarge;
}
}
public Date getOriginalEstimatedArrivalDateAtPlaceOfDischarge() {
return originalEstimatedArrivalDateAtPlaceOfDischarge;
}
public void setOriginalEstimatedArrivalDateAtPlaceOfDischarge(Date originalEstimatedArrivalDateAtPlaceOfDischarge) {
if (this.originalEstimatedArrivalDateAtPlaceOfDischarge == null) {
this.originalEstimatedArrivalDateAtPlaceOfDischarge = originalEstimatedArrivalDateAtPlaceOfDischarge;
}
}
@Override
public OrganisationalUnit getOrganisationalUnit() {
if (consignments.isEmpty()) {
return null;
} else {
for (int i = 0; i < consignments.size(); i++) {
if (consignments.iterator().next().getOrdersList().size() >= 1) {
return consignments.iterator().next().getOrdersList().get(0).getOrganisationalUnit();
}
}
}
return null;
}
@Override
public void accept(CostingVisitor costingVisitor) {
for (CommercialInvoice commercialInvoice : getActiveCommercialInvoices()) {
commercialInvoice.accept(costingVisitor);
}
for (CommercialCreditNote commercialCreditNote : getActiveCommercialCreditNotes()) {
commercialCreditNote.accept(costingVisitor);
}
for (ServiceProviderInvoice serviceProviderInvoice : getActiveServiceProviderInvoices()) {
serviceProviderInvoice.accept(costingVisitor);
}
for (ServiceProviderCreditNote serviceProviderCreditNote : getActiveServiceProviderCreditNotes()) {
serviceProviderCreditNote.accept(costingVisitor);
}
costingVisitor.visit(this);
}
public void acceptSignedOff(CostingVisitor costingVisitor) {
for (CommercialInvoice commercialInvoice : getSignedOffCommercialInvoices()) {
commercialInvoice.accept(costingVisitor);
}
for (CommercialCreditNote commercialCreditNote : getSignedOffCommercialCreditNotes()) {
commercialCreditNote.accept(costingVisitor);
}
for (ServiceProviderInvoice serviceProviderInvoice : getSignedOffServiceProviderInvoices()) {
serviceProviderInvoice.accept(costingVisitor);
}
for (ServiceProviderCreditNote serviceProviderCreditNote : getSignedOffServiceProviderCreditNotes()) {
serviceProviderCreditNote.accept(costingVisitor);
}
costingVisitor.visit(this);
}
public void addCommercialInvoice(CommercialInvoice commercialInvoice) {
commercialInvoice.setShipment(this);
commercialInvoices.add(commercialInvoice);
commercialInvoice.setAddedToShipmentDate(new Date());
}
public void addCommercialCreditNote(CommercialCreditNote commercialCreditNote) {
commercialCreditNote.setShipment(this);
commercialCreditNotes.add(commercialCreditNote);
}
public void addServiceProviderCreditNote(ServiceProviderCreditNote creditNote) {
creditNote.setShipment(this);
serviceProviderCreditNotes.add(creditNote);
}
@Override
public int hashCode() {
return new HashCodeBuilder()
.append(number)
.append(reference)
.append(state)
.toHashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
// Do not use class.equals. This can return false for proxy objects
if (!HibernateUtils.proxyClassEquals(this, obj)) {
return false;
}
Shipment other = (Shipment) obj;
return new EqualsBuilder()
.append(number, other.getNumber())
.append(reference, other.getReference())
.append(state, other.getState())
.isEquals();
}
@Override
public String toString() {
return new ToStringBuilder(this).append(number).append(reference).append(signedOffBy).append(grossWeight).append(netWeight).append
(grossVolume).append(netVolume).append(entryDate).append(warehouseDeliveryDate).append(carrierReleaseDate)
.append(signedOffDate)
.append(costedDate).append(shippingInfo).append(departurePlace).append(arrivalPlace).append(actualDepartureDate).
append(certificateOfOriginReceivedDate).toString();
}
public void clearConsignments() {
consignments.clear();
}
@Override
public Incoterm getIncoterm() {
return shippingInfo.getIncoterm();
}
@Override
public ShipmentShippingInfo getShippingInfo() {
return shippingInfo;
}
public void setShippingInfo(ShipmentShippingInfo shippingInfo) {
this.shippingInfo = shippingInfo;
}
/**
* Helper method for the view tier. If the shipment is in any of these states then we will not
* allow editing of certain fields.
*
* @return
*/
@Deprecated
public boolean disabled() {
return inNonEditableState();
}
@Override
public boolean inNonEditableState() {
return NON_EDITABLE_STATES.contains(state);
}
@Override
public CostableCostDefinition getCostableCostDefinition() {
return costableCostDefinition;
}
@Override
public void setCostableCostDefinition(CostableCostDefinition costableCostDefinition) {
this.costableCostDefinition = costableCostDefinition;
costableCostDefinition.setShipment(this);
}
public CostableCostDefinition getClearingCostableCostDefinition() {
return clearingCostableCostDefinition;
}
public void setClearingCostableCostDefinition(CostableCostDefinition clearingCostableCostDefinition) {
this.clearingCostableCostDefinition = clearingCostableCostDefinition;
clearingCostableCostDefinition.setShipment(this);
}
@Override
public String getKey() {
return new StringBuilder(getClass().getCanonicalName()).append(toString()).append(hashCode()).toString();
}
public String getDMSKey() {
return getReference();
}
public boolean isPacked() {
return packingList != null && packingList.isPacked();
}
public abstract Date getBillOfLadingDate();
/*
public boolean match(ActualShipment actualShipment) {
return this.getReference().equals(actualShipment.getReference()) && this.getNumber().equals(actualShipment.getNumber());
}
*/
public boolean isDeleted() {
return this.getState().equals(ShipmentState.DELETED);
}
public boolean isVerified() {
return this.getState().equals(ShipmentState.VERIFIED);
}
public boolean isFinalised() {
return this.getState().equals(ShipmentState.FINALISED);
}
public boolean isSignedOff() {
return this.getState().equals(ShipmentState.SIGNED_OFF);
}
@Override
public String getCommentsAsString() {
return AddedCommentI.commentsAsString(getComments());
}
@Override
public CostingContextType getCostingContextType() {
CostingContextType toReturn = CostingContextType.IMPORT;
if (!isImports())
toReturn = CostingContextType.EXPORT;
Set<Consignment> consignments = getConsignments();
if (!consignments.isEmpty()) {
Consignment consignment = consignments.iterator().next();
toReturn = consignment.getCostingContextType();
}
return toReturn;
}
public boolean isIntegrated() {
return integrated;
}
public void setIntegrated(boolean integrated) {
this.integrated = integrated;
}
public String getShipmentReportUrl() {
return shipmentReportUrl;
}
public void setShipmentReportUrl(String shipmentReportUrl) {
this.shipmentReportUrl = shipmentReportUrl;
}
public Date getCertificateOfOriginReceivedDate() {
return certificateOfOriginReceivedDate;
}
public void setCertificateOfOriginReceivedDate(Date certificateOfOriginReceivedDate) {
this.certificateOfOriginReceivedDate = certificateOfOriginReceivedDate;
}
public DocumentGroupState getDocumentGroupStatus() {
return documentGroupStatus;
}
public void setDocumentGroupStatus(DocumentGroupState documentGroupStatus) {
this.documentGroupStatus = documentGroupStatus;
}
public PlaceAddress getConsolidationPoint() {
return consolidationPoint;
}
public void setConsolidationPoint(PlaceAddress consolidationPoint) {
this.consolidationPoint = consolidationPoint;
}
@Override
public boolean hasServiceProviderInvoice() {
return !this.getActiveServiceProviderInvoices().isEmpty();
}
public boolean hasCommercialInvoice() {
return !this.getActiveCommercialInvoices().isEmpty();
}
@Override
public Date getVesselBerthedDate() {
return vesselBerthedDate;
}
public void setVesselBerthedDate(Date vesselBerthedDate) {
this.vesselBerthedDate = vesselBerthedDate;
}
@Override
public Set<SubShipment> getSubShipments() {
return subShipments;
}
public void setSubShipments(Set<SubShipment> subShipments) {
this.subShipments = subShipments;
}
@Override
public Shipment initialize() {
Shipment initialize = (Shipment) super.initialize();
HibernateUtils.initializeAndUnproxy(initialize.getServiceProviderInvoices());
HibernateUtils.initializeAndUnproxy(initialize.getCommercialInvoices());
HibernateUtils.initializeAndUnproxy(initialize.getCommercialCreditNotes());
HibernateUtils.initializeAndUnproxy(initialize.getConsignments());
HibernateUtils.initializeAndUnproxy(initialize.getContainers());
HibernateUtils.initializeAndUnproxy(initialize.getServiceProviderCreditNotes());
HibernateUtils.initializeAndUnproxy(initialize.getPackingList());
HibernateUtils.initializeAndUnproxy(initialize.getSubShipments());
if (initialize.getPackingList() != null) {
HibernateUtils.initializeAndUnproxy(initialize.getPackingList().getContainers());
}
HibernateUtils.initializeAndUnproxy(initialize.getShippingInfo());
HibernateUtils.initializeAndUnproxy(initialize.getShippingInfo().getPlaceOfDischarge());
HibernateUtils.initializeAndUnproxy(initialize.getShippingInfo().getPlaceOfLoading());
HibernateUtils.initializeAndUnproxy(initialize.getShippingInfo().getFreightForwarder());
return initialize;
}
@Override
public CommentType getCommentType() {
return CommentType.SHIPMENT;
}
public Date getSettlementDate() {
return settlementDate;
}
public void setSettlementDate(Date settlementDate) {
this.settlementDate = settlementDate;
}
public Collection<ServiceProviderInvoice> getSplitInvoices() {
return splitInvoices;
}
public void setSplitInvoices(Collection<ServiceProviderInvoice> splitInvoices) {
this.splitInvoices = splitInvoices;
}
public void validateTransitionToCustomReleased() {
Set<CommercialInvoice> invoices = getCommercialInvoices();
invoices.stream().forEach(invoice -> {
if (!(invoice.getState() == DocumentState.PAYMENT_INITIATED ||
invoice.getState() == DocumentState.SIGNED_OFF ||
invoice.getState() == DocumentState.SETTLED ||
invoice.getState() == DocumentState.COMPLETE
)) {
throw new IllegalStateException(String.format("Invoice state %s is incorrect to transition" +
" to CUSTOMS_RELEASED, Expected invoice states [PAYMENT_INITIATED,SIGNED_OFF,SETTLED,COMPLETE]",
invoice.getState(), invoice.getReference()));
}
});
}
public Set<CustomsDeclaration> getCustomsDeclarations() {
if (customsDeclarations == null) {
customsDeclarations = new HashSet();
}
return customsDeclarations;
}
public Set<CustomsDeclaration> getActiveCustomsDeclarations() {
return new HashSet<>(PersistenceBase.getActiveList(getCustomsDeclarations()));
}
public void setCustomsDeclarations(Set<CustomsDeclaration> customsDeclarations) {
this.customsDeclarations = customsDeclarations;
}
public void addCustomsDeclaration(CustomsDeclaration customsDeclaration) {
customsDeclaration.setShipment(this);
getCustomsDeclarations().add(customsDeclaration);
}
public Date getStateDate() {
return stateDate;
}
public void setStateDate(Date stateDate) {
this.stateDate = stateDate;
}
public ActualShipment getActualShipment() {
return actualShipment;
}
public void setActualShipment(ActualShipment actualShipment) {
this.actualShipment = actualShipment;
}
public Date getShippedOnBoardDate() {
return shippedOnBoardDate;
}
public void setShippedOnBoardDate(Date shippedOnBoardDate) {
this.shippedOnBoardDate = shippedOnBoardDate;
}
public abstract City getBillPlaceOfIssue();
public abstract void setBillPlaceOfIssue(City billPlaceOfIssue);
public String getLrnNumbers() {
return lrnNumbers;
}
public String getMrnNumbers() {
return mrnNumbers;
}
@Override
public String getDocumentGroupName() {
switch (getShippingMode()) {
case AIR:
return DocumentManagementHardCoding.SHIPMENT_AIR.getDocumentManagementHardCodedName();
case SEA:
return DocumentManagementHardCoding.SHIPMENT_SEA.getDocumentManagementHardCodedName();
default:
return null;
}
}
public Date getLastTariffedDate() {
return lastTariffedDate;
}
public void setLastTariffedDate(Date lastTariffedDate) {
this.lastTariffedDate = lastTariffedDate;
}
public ShipmentEvent getFirstEvent(ShipmentEventType eventType) {
return Event.getFirstEvent(events, eventType);
}
public List<CommercialInvoice> getSignedOffCommercialInvoices() {
List<CommercialInvoice> activeCommercialInvoices = getActiveCommercialInvoices();
if (activeCommercialInvoices != null)
return activeCommercialInvoices.stream().filter(ci -> ci.isPostSignOffState()).collect(Collectors.toList());
else return Collections.EMPTY_LIST;
}
public List<ServiceProviderInvoice> getSignedOffServiceProviderInvoices() {
List<ServiceProviderInvoice> serviceProviderInvoices = getActiveServiceProviderInvoices();
if (serviceProviderInvoices != null)
return serviceProviderInvoices.stream().filter(ci -> ci.isPostSignOffState()).collect(Collectors.toList());
else return Collections.EMPTY_LIST;
}
public List<CommercialCreditNote> getSignedOffCommercialCreditNotes() {
List<CommercialCreditNote> activeCommercialCreditNotes = getActiveCommercialCreditNotes();
if (activeCommercialCreditNotes != null)
return activeCommercialCreditNotes.stream().filter(ci -> ci.getCommercialInvoice().isPostSignOffState()).collect(Collectors.toList());
else return Collections.EMPTY_LIST;
}
public List<ServiceProviderCreditNote> getSignedOffServiceProviderCreditNotes() {
List<ServiceProviderCreditNote> activeServiceProviderCreditNotes = getActiveServiceProviderCreditNotes();
if (activeServiceProviderCreditNotes != null)
return activeServiceProviderCreditNotes.stream().filter(ci -> ci.getServiceProviderInvoice()
.isPostSignOffState()).collect(Collectors.toList());
else return Collections.EMPTY_LIST;
}
public boolean recalculateCosts() {
return getState() == ShipmentState.FINALISED || getState() == ShipmentState.VERIFIED ||
getState() == ShipmentState.CUSTOMS_RELEASED;
}
public String getClearingMrnNumbers() {
return clearingMrnNumbers;
}
public abstract BigDecimal getBillOfLadingSpotRate();
public abstract void setBillOfLadingSpotRate(BigDecimal billOfLadingSpotRate);
public boolean isImports() {
return imports;
}
public void setImports(boolean imports) {
this.imports = imports;
}
public Date getTelexReleaseDate() {
return telexReleaseDate;
}
public Date getClearingInstructionSignedOffDate() {
return clearingInstructionSignedOffDate;
}
public void setClearingInstructionSignedOffDate(Date clearingInstructionSignedOffDate) {
this.clearingInstructionSignedOffDate = clearingInstructionSignedOffDate;
}
public void setTelexReleaseDate(Date telexReleaseDate) {
this.telexReleaseDate = telexReleaseDate;
}
}