ContainerSearchResultHelper.java

package com.tradecloud.dto.container;

import com.tradecloud.common.base.HibernateUtils;
import com.tradecloud.domain.base.utils.DateUtils;
import com.tradecloud.domain.base.utils.MathUtils;
import com.tradecloud.domain.comment.AddedComment;
import com.tradecloud.domain.container.ConsignmentContainer;
import com.tradecloud.domain.container.ContainerType;
import com.tradecloud.domain.container.ContainerTypeCode;
import com.tradecloud.domain.container.ShipmentContainer;
import com.tradecloud.domain.document.invoice.PlannedSettlementHelper;
import com.tradecloud.domain.event.EnumTypedEvent;
import com.tradecloud.domain.event.Event;
import com.tradecloud.domain.event.ShipmentEvent;
import com.tradecloud.domain.event.ShipmentEventType;
import com.tradecloud.domain.model.ordermanagement.PurchaseOrder;
import com.tradecloud.domain.model.payment.PaymentMethod;
import com.tradecloud.domain.model.shipment.ShippingMode;
import com.tradecloud.domain.party.ServiceProvider;
import com.tradecloud.domain.party.ServiceProviderType;
import com.tradecloud.domain.place.FinalDestination;
import com.tradecloud.domain.place.PlaceOfDischarge;
import com.tradecloud.domain.shipment.*;
import com.tradecloud.domain.state.Stateful;
import com.tradecloud.domain.supplier.AbstractSupplier;
import com.tradecloud.domain.supplier.CompleteType;
import com.tradecloud.dto.order.SearchResultHelper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.log4j.Logger;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

public class ContainerSearchResultHelper {

    private static final Logger log = Logger.getLogger(ContainerSearchResultHelper.class);

    private static final DateFormat DF = new SimpleDateFormat("dd-MM-yyyy");
    private static final SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
    public static final int ROUND_SCALE = 4;

    public static final int DEMURRAGE_DAYS = 10;

    public static <T> T getNonProxyObject(T potentialProxy) {
        if (potentialProxy instanceof HibernateProxy hibernateProxy) {
            LazyInitializer hibernateLazyInitializer = hibernateProxy.getHibernateLazyInitializer();

            if (!hibernateLazyInitializer.isUninitialized()) {
                return (T) hibernateLazyInitializer.getImplementation();
            }
        }
        return potentialProxy;
    }

    private static final List<String> costLineNames = new ArrayList<>();

    public static void populateContainersAvailNotDelivSearchResult(ContainersAvailNotDelivToFDSearchResult result, PurchaseOrder order,
                                                                   ShipmentContainer container) {
        Calendar calendar = new GregorianCalendar();
        result.setId(order.getId() != null ? order.getId() : null);

        if (order.getShippingInformation() != null) {
            if (order.getShippingInformation().getShippingMode() != null) {
                result.setShippingMode(order.getShippingInformation().getShippingMode());
            }
            if (order.getShippingInformation().getMultiModalShippingMode() != null) {
                result.setMultiModalShippingMode(order.getShippingInformation().getMultiModalShippingMode());
            }
            result.setShippingReference(order.getShippingInformation().getShippingReference());
        }

        result.setEstimatedArrivalDateAtPlaceOfDischarge(null);
        result.setArrivalDateAtPlaceOfDischarge(null);

        if (order.getOrderDates() != null) {
            result.setRequiredOnSiteDate(order.getOrderDates().getRequiredOnSiteDate());
        }
        if (order.getConsignment() != null) {

            if (order.getConsignment().getComments() != null) {
                result.setConsignmentComments(SearchResultHelper.flattenComments(order.getConsignment()));
            }
            if (order.getConsignment().getShipment() != null) {
                if (order.getConsignment().getShipment().getReference() != null) {
                    result.setShipmentReference(order.getConsignment().getShipment().getReference());
                }
                if (order.getConsignment().getShipment().getNumber() != null) {
                    result.setShipmentNumber(order.getConsignment().getShipment().getNumber());
                }
                if (order.getConsignment().getShipment().getEstimatedArrivalDateAtPlaceOfDischarge() != null) {
                    result.setEstimatedArrivalDateAtPlaceOfDischarge(order.getConsignment().getShipment()
                            .getEstimatedArrivalDateAtPlaceOfDischarge());
                } else {
                    result.setEstimatedArrivalDateAtPlaceOfDischarge(null);
                }
                if (order.getConsignment().getShipment().getArrivalDateAtPlaceOfDischarge() != null) {
                    result.setArrivalDateAtPlaceOfDischarge(order.getConsignment().getShipment().getArrivalDateAtPlaceOfDischarge());
                }
                result.setShipmentId(order.getConsignment().getShipment().getId());
                if (order.getConsignment().getShipment().getShippingInfo().getPlaceOfLoading() != null) {
                    result.setCountry(order.getConsignment().getShipment().getShippingInfo().getPlaceOfLoading().getCountry().getName());
                }

                if (order.getConsignment().getShipment().getComments() != null) {
                    result.setShipmentComments(SearchResultHelper.flattenComments(order.getConsignment().getShipment()));
                }
                if (order.getConsignment().getShipment().getShippingInfo().getClearingAgent() != null) {
                    result.getClearingAgent().setName(order.getConsignment().getShipment().getShippingInfo().getClearingAgent().getName());
                }

                Shipment shipment = getNonProxyObject(order.getConsignment().getShipment());
                if (shipment instanceof SeaShipment) {
                    result.setVoyageNumber(((SeaShipment) shipment).getVoyageNumber());
                    result.setTransporterName(((SeaShipment) shipment).getShippingVessel());
                } else if (shipment instanceof AirShipment) {
                    result.setVoyageNumber(((AirShipment) shipment).getFlightNumber());
                    result.setTransporterName(((AirShipment) shipment).getAirlineName());
                }
            }

        }

        result.setOrderReference(order.getOrderReference() != null ? order.getOrderReference() : null);
        result.setBusinessState(order.getBusinessState() != null ? order.getBusinessState().name() : null);

        if (order.getSupplier() != null) {
            result.getSupplier().setName(order.getSupplier().getSupplier().getName());
        }

        if (order.getBuyer() != null) {
            result.getBuyer().setFirstName(order.getBuyer().getFirstName());
            result.getBuyer().setLastName(order.getBuyer().getLastName());
        }

        if (order.getOrganisationalUnit() != null) {
            result.setBusinessUnit(order.getOrganisationalUnit().getParent() != null ? order.getOrganisationalUnit().getParent() : null);
        }

        result.setDivision(order.getOrganisationalUnit() != null ? order.getOrganisationalUnit() : null);
        result.setSuppliersInvoiceValue(order.getTotalInvoiceValue() != null ? MathUtils.setScale(order.getTotalInvoiceValue(), ROUND_SCALE) : null);
        PlannedSettlementHelper plannedSettlementHelper = order.getPlannedSettlementHelper();
        if (plannedSettlementHelper != null) {
            result.setSuppliersInvoiceValueCC(MathUtils.setScale(plannedSettlementHelper.getCostingCurrencyTotalValue(), ROUND_SCALE));
        }
        result.setSuppliersInvoiceValueCurrency(order.getCurrency() != null ? order.getCurrency().getCode() : "");

        if (order.getComments() != null) {
            result.setOrderComments(SearchResultHelper.flattenComments(order));
        }
        result.setTotalOrderUnitQuantity(order.getOrderQuantity());
        result.setAtaAtFinalDestination(null);
        result.setEtaAtFinalDestination(null);
        result.setPickUpDate(null);
        result.setEtaAtDepot(null);
        result.setAtaAtDepot(null);
        result.setOverstayAndStorageFreePeriodEnd(null);
        result.setTurnInFreePeriodEnd(null);
        result.setTransporterAvailabliltyDate(null);

        if (container != null) {

            result.setContainerReference(container.getReference() != null ? container.getReference() : null);
            if (container.getContainerType() != null) {
                result.setContainerType(container.getContainerType());
            }
            result.setTotalWeight(container.getTotalContainerWeight());
            //result.setTotalVolume(container.getGrossVolume());
            result.setAtaAtFinalDestination(container.getContainerDates().getAtaAtFinalDestination());
            result.setEtaAtFinalDestination(container.getContainerDates().getEtaAtFinalDestination());
            result.setPickUpDate(container.getContainerDates().getPickUpDate());
            result.setEtaAtDepot(container.getContainerDates().getEtaAtDepot());
            result.setAtaAtDepot(container.getContainerDates().getAtaAtDepot());
            result.setOverstayAndStorageFreePeriodEnd(container.getOverstayAndStorageFreePeriodEnd());
            result.setTurnInFreePeriodEnd(container.getTurnInFreePeriodEnd());
            if (container.getContainerDates().getTransporterAvailabilityDate() != null) {
                result.setTransporterAvailabliltyDate(container.getContainerDates().getTransporterAvailabilityDate());
                Date date = container.getContainerDates().getTransporterAvailabilityDate();

                calendar.setTime(date);
                calendar.add(Calendar.DATE, DEMURRAGE_DAYS);

                result.setDemurrageDate(calendar.getTime());

            } else {
                result.setTransporterAvailabliltyDate(null);
            }
            result.setPlaceOfDischarge(container.getPlaceOfDischarge() != null ? container.getPlaceOfDischarge() : null);
            result.setClearingDepot(container.getClearingDepot() != null ? container.getClearingDepot() : null);
            result.setFinalDestination(container.getFinalDestination() != null ? container.getFinalDestination() : new FinalDestination("", ""));
            if (container.getTransporter() != null) {
                result.getTransporter().setName(container.getTransporter().getName());
            } else {
                result.getTransporter().setName("");
            }
            String transporterId = "";
            if (result.getShippingMode().toString() != null && !Objects.equals(result.getShippingMode().toString(), "")) {
                transporterId = transporterId + result.getShippingMode() + ":";
            }
            if (result.getTransporterName() != null && !Objects.equals(result.getTransporterName(), "")) {
                transporterId = transporterId + result.getTransporterName() + ",";
            }
            if (result.getVoyageNumber() != null && !Objects.equals(result.getVoyageNumber(), "")) {
                transporterId = transporterId + result.getVoyageNumber();
            }
            result.setTransporterID(transporterId);

            BigDecimal teu = container.getContainerType().getTeu();
            if (teu != null) {
                teu = teu.setScale(4, RoundingMode.HALF_UP);
                if (container.getContainerType().getCode().equals(ContainerTypeCode.LCL.name())) {
                    teu = BigDecimal.ONE.divide(teu, 4, RoundingMode.HALF_UP);
                }
                result.setTwentyFootEquivalentUnits("" + teu);
            } else {
                result.setTwentyFootEquivalentUnits("");
            }
        }
    }

    // -----------------------------------------------------------

    public static void populateContainersShippedNotAvailSearchResult(ContainersShippedNotAvailSearchResult result, PurchaseOrder order,
                                                                     ShipmentContainer container, int documentsDue, int customsEntryDue,
                                                                     int actualCostingDue) {
        String transporterId = "";
        result.setId(order.getId() != null ? order.getId() : null);
        if (order.getShippingInformation() != null) {
            result.getTransporter().setName("");
            result.getClearingAgent().setName("");
            result.getFreightForwarder().setName("");
            result.setShippingReference(order.getShippingInformation().getShippingReference());

            if (order.getShippingInformation().getClearingDepot() != null) {
                result.setClearingDepot(order.getShippingInformation().getClearingDepot());
            }
            result.setShippingMode(null);
        }

        result.setIncoterm(null);
        result.getSupplier().setIncoterm(null);

        result.setScheduledDepartureDate(null);
        result.setActualDepartureDate(null);
        result.setOriginalEstimatedArrivalDateAtPlaceOfDischarge(null);
        result.setEstimatedArrivalDateAtPlaceOfDischarge(null);
        result.setArrivalDateAtPlaceOfDischarge(null);
        result.setDocumentsDueDate(null);
        result.setDocumentsReceivedDate(null);
        result.setCopyDocumentsReceivedDate(null);
        result.setOriginalDocumentsReceivedDate(null);
        result.setCustomsEntryDueDate(null);
        result.setCustomsEntryDate(null);
        result.setCustomsExitDate(null);
        result.setCarrierReleaseDate(null);
        result.setActualCostingDueDate(null);
        result.setActualCostingCompleteDate(null);
        result.setOverstay(null);
        result.setCertificateOfOriginReceivedDate(null);
        result.setCountry(null);
        if (order.getOrderDates() != null) {
            result.setRequiredOnSiteDate(order.getOrderDates().getRequiredOnSiteDate());
        }
        if (order.getConsignment() != null) {
            if (order.getConsignment().getArrivalDateAtPlaceOfDischarge() != null) {
                result.setArrivalDateAtPlaceOfDischarge(order.getConsignment().getArrivalDateAtPlaceOfDischarge());
            } else {
                result.setArrivalDateAtPlaceOfDischarge(null);
            }
            Shipment shipment1 = order.getConsignment().getShipment();
            if (null != shipment1) {
                if (shipment1.getReference() != null) {
                    result.setShipmentReference(shipment1.getReference());
                }
                if (shipment1.getNumber() != null) {
                    result.setShipmentNumber(shipment1.getNumber());
                }
                result.setShipmentId(shipment1.getId());

                if (shipment1.getShippingMode() != null) {
                    result.setShippingMode(shipment1.getShippingMode());
                }
                if (shipment1.getMultiModalShippingMode() != null) {
                    result.setMultiModalShippingMode(shipment1.getMultiModalShippingMode());
                }
                if (shipment1.getComments() != null) {
                    result.setShipmentsComments(SearchResultHelper.flattenComments(shipment1));
                }
                if (shipment1.getShippingInfo().getPlaceOfLoading() != null) {
                    result.setPlaceOfLoading(shipment1.getShippingInfo().getPlaceOfLoading());
                    result.setCountry(shipment1.getShippingInfo().getPlaceOfLoading().getCountry().getName());
                }

                if (shipment1.getIncoterm() != null) {
                    result.setIncoterm(shipment1.getIncoterm().getCode());
                    result.getSupplier().setIncoterm(shipment1.getIncoterm());
                }

                Date signedOffDate = null;
                List<ShipmentEvent> events = shipment1.getEvents();
                for (ShipmentEvent event : events) {
                    if (event.getEventType().equals(ShipmentEventType.SIGNED_OFF)) {
                        signedOffDate = event.getCreated();
                    } else if (event.getEventType().equals(ShipmentEventType.UNSIGNED_OFF)) {
                        if (event.getCreateDateTime().after(signedOffDate)) {
                            signedOffDate = null;
                        }
                    }
                }
                result.setActualCostingCompleteDate(signedOffDate);

                result.setCopyDocumentsReceivedDate(shipment1.getCopyDocumentsReceivedDate());
                result.setOriginalDocumentsReceivedDate(shipment1.getOriginalDocumentsReceivedDate());
                if (shipment1.getShippingInfo().getFreightForwarder() != null) {
                    result.getFreightForwarder().setName(shipment1.getShippingInfo().getFreightForwarder().getName());
                }
                if (shipment1.getShippingInfo().getClearingAgent() != null) {
                    result.getClearingAgent().setName(shipment1.getShippingInfo().getClearingAgent().getName());
                }

                result.setBillOfLadingSpotROE(shipment1.getBillOfLadingSpotRate());

                if (getNonProxyObject(shipment1) instanceof SeaShipment seaShipment) {

                    if (seaShipment.getVoyageNumber() != null) {
                        result.setVoyageNumber(seaShipment.getVoyageNumber());
                    }
                    if (seaShipment.getShippingVessel() != null) {
//                        result.setTransporterName(seaShipment.getShippingVessel());
//                        result.getTransporter().setName(seaShipment.getShippingVessel());
                    }
                    result.setShippingVesselName(seaShipment.getShippingVessel());
                    result.setTransportDocumentNumber(seaShipment.getBillOfLadingReference());
                    result.getCarrier().setName(seaShipment.getCarrier() != null ? seaShipment.getCarrier().getName() : "");
                } else if (getNonProxyObject(shipment1) instanceof AirShipment airShipment) {
                    result.setVoyageNumber(airShipment.getFlightNumber());
                    result.setTransporterName(airShipment.getAirlineName());
                    result.setTransportDocumentNumber(airShipment.getMasterAirwayBillNumber());
                }

                if (shipment1.getActualDepartureDate() != null && shipment1.getEstimatedArrivalDateAtPlaceOfDischarge() != null) {
                    result.setActualDepartureDate(shipment1.getActualDepartureDate());
                    result.setEstimatedArrivalDateAtPlaceOfDischarge(shipment1.getEstimatedArrivalDateAtPlaceOfDischarge());
                    result.setOriginalEstimatedArrivalDateAtPlaceOfDischarge(shipment1.getOriginalEstimatedArrivalDateAtPlaceOfDischarge());
                    // calculations
                    Calendar cal = Calendar.getInstance();
                    cal.setTime(result.getActualDepartureDate());

                    cal.add(Calendar.DATE, documentsDue);
                    result.setDocumentsDueDate(cal.getTime());

                    Calendar cal2 = Calendar.getInstance();
                    cal2.setTime(result.getEstimatedArrivalDateAtPlaceOfDischarge());
                    cal2.add(Calendar.DATE, customsEntryDue);
                    result.setCustomsEntryDueDate(cal2.getTime());

                    Calendar cal3 = Calendar.getInstance();
                    cal3.setTime(result.getEstimatedArrivalDateAtPlaceOfDischarge());
                    cal3.add(Calendar.DATE, actualCostingDue);

                    result.setActualCostingDueDate(cal3.getTime());
                }
                result.setArrivalDateAtPlaceOfDischarge(shipment1.getArrivalDateAtPlaceOfDischarge());
                result.setEstimatedArrivalDateAtPlaceOfDischarge(shipment1.getEstimatedArrivalDateAtPlaceOfDischarge());
                result.setOriginalEstimatedArrivalDateAtPlaceOfDischarge(shipment1.getOriginalEstimatedArrivalDateAtPlaceOfDischarge());
                result.setScheduledDepartureDate(shipment1.getScheduledDepartureDate());

                if (shipment1.getCertificateOfOriginReceivedDate() != null) {
                    result.setCertificateOfOriginReceivedDate(shipment1.getCertificateOfOriginReceivedDate());
                }

                Set<Transhipment> transhipmentSet = shipment1.getTranshipments();
                if (null != transhipmentSet && !transhipmentSet.isEmpty()) {
                    Transhipment transhipment = transhipmentSet.iterator().next();
                    result.setFeederVoyageNumber(transhipment.getVoyageNumber());
                    result.setFeederTransporterName(transhipment.getVesselName());
                    result.setFeederPlaceOfLoading(transhipment.getPlaceOfLoading());
                    result.setFeederPlaceOfDischarge(transhipment.getPlaceOfLoadingTo());
                    result.setFeederActualDepartureDate(transhipment.getActualDateOfDeparture());
                    result.setFeederEstimateDepartureDate(transhipment.getEstimatedDepartureDate());
                    result.setEstimateArrivalDateatTranshipmentPort(transhipment.getEstimatedArrivalDateAtTranshipmentPort());
                    result.setActualArrivalDateatTranshipmentPort(transhipment.getActualArrivalDateAtTransshipmentPort());
                }
            }
        }

        result.setDocumentsReceivedDate(order.getOriginalDocumentsReceivedDate());

        result.setOrderReference(order.getOrderReference() != null ? order.getOrderReference() : "");
        result.setBusinessState(order.getBusinessState() != null ? order.getBusinessState().name() : "");
        result.getSupplier().setName(order.getSupplier().getSupplier() != null ? order.getSupplier().getSupplier().getName() : "");

        if (order.getBuyer() != null) {
            result.getBuyer().setFirstName(order.getBuyer().getFirstName());
            result.getBuyer().setLastName(order.getBuyer().getLastName());
        }
        result.setBusinessUnit(order.getOrganisationalUnit().getParent() != null ? order.getOrganisationalUnit().getParent() : null);
        result.setDivision(order.getOrganisationalUnit() != null ? order.getOrganisationalUnit().getName() : null);
        result.setSuppliersInvoiceValue(order.getTotalInvoiceValue() != null ? MathUtils.setScale(order.getTotalInvoiceValue(), ROUND_SCALE) : null);

        PlannedSettlementHelper plannedSettlementHelper = order.getPlannedSettlementHelper();
        if (plannedSettlementHelper != null) {
            result.setSuppliersInvoiceValueCC(MathUtils.setScale(plannedSettlementHelper.getCostingCurrencyTotalValue(), ROUND_SCALE));
        }
        result.setSuppliersInvoiceValueCurrency(order.getCurrency() != null ? order.getCurrency().getCode() : "");

        PaymentMethod paymentMethod = order.getPaymentMethod();
        if (paymentMethod != null) {
            // consult TTG-315
            if ("Telegraphic Transfer".equals(paymentMethod.getName())) {
                paymentMethod.setName("TT");
            }
            result.setPaymentMethod(paymentMethod);
            result.getSupplier().setPaymentMethod(paymentMethod);
        }
        if (order.getPaymentTerm() != null) {
            result.setPaymentTerm(order.getPaymentTerm());
            result.getSupplier().setPaymentTerm(order.getPaymentTerm());
        }

        if (container != null) {
            result.setContainerReference(container.getReference() != null ? container.getReference() : "");
            result.setCarrierReleaseDate(container.getContainerDates().getCarrierReleaseDate());
            result.setCustomsEntryDate(container.getContainerDates().getCustomsEntryDate());
            result.setCustomsExitDate(container.getContainerDates().getCustomsExitDate());
            result.setTotalWeight(container.getTotalContainerWeight());
            result.setTotalVolume(container.getGrossVolume());
            if (container.getTransporter() != null) {
                result.setTransporterName(container.getTransporter().getName());
                result.getTransporter().setName(container.getTransporter().getName());
            } else {
                result.setTransporterName("");
                result.getTransporter().setName("");
            }

            boolean stoppedByCustoms = container.isStoppedByCustoms();
            if (stoppedByCustoms) {
                result.setStoppedByCustoms("YES");
            } else {
                result.setStoppedByCustoms("NO");
            }

            result.setFinalDestination(container.getFinalDestination() != null ? container.getFinalDestination() : new FinalDestination("", ""));
            result.setContainerType(container.getContainerType() != null ? container.getContainerType() : new ContainerType("", ""));
            result.setPlaceOfDischarge(container.getPlaceOfDischarge() != null ? container.getPlaceOfDischarge() : new PlaceOfDischarge("", ""));

            if (container.getContainerDates() != null) {
                result.setOverstay(container.getOverstayAndStorageFreePeriodEnd());
            }

            BigDecimal teu = container.getContainerType().getTeu();
            if (teu != null) {
                teu = teu.setScale(4, RoundingMode.HALF_UP);
                if (container.getContainerType().getCode().equals(ContainerTypeCode.LCL.name())) {
                    teu = BigDecimal.ONE.divide(teu, 4, RoundingMode.HALF_UP);
                }
                result.setTwentyFootEquivalentUnits("" + teu);
            } else {
                result.setTwentyFootEquivalentUnits("");
            }
            if (result.getShippingMode() != null) {
                transporterId = transporterId + result.getShippingMode().toString() + ":";
            }
            if (result.getTransporterName() != null && !Objects.equals(result.getTransporterName(), "")) {
                transporterId = transporterId + result.getTransporterName() + ",";
            }
            if (result.getVoyageNumber() != null && !Objects.equals(result.getVoyageNumber(), "")) {
                transporterId = transporterId + result.getVoyageNumber();
            }
            result.setTransporterID(transporterId);
        }
    }

    public static void populateLogisticsSummarySearchResult(LogisticsSummarySearchResult result, PurchaseOrder order, ShipmentContainer container) {
        Shipment shipment1 = order.getConsignment().getShipment();
        result.setId(order.getId() != null ? order.getId() : null);
        if (order.getShippingInformation() != null) {
            ShippingInformation shippingInformation = order.getShippingInformation();

            result.setShippingReference(shippingInformation.getShippingReference());
            if (shippingInformation.getTransporter() != null) {
                result.setTransporter(shippingInformation.getTransporter());
            }

            if (shippingInformation.getClearingDepot() != null) {
                result.setClearingDepot(shippingInformation.getClearingDepot());
            }
            if (shippingInformation.getShippingMode() != null) {
                result.setShippingMode(shippingInformation.getShippingMode());
            }
            if (shippingInformation.getMultiModalShippingMode() != null) {
                result.setMultiModalShippingMode(shippingInformation.getMultiModalShippingMode());
            }
            if (order.getOrderDates().getAvailabilityDate() != null) {
                result.setAvailabilityDate(order.getOrderDates().getAvailabilityDate());
            }
            if (order.getOrderDates().getFreightReceivedDate() != null) {
                result.setFreightReceivedDate(order.getOrderDates().getFreightReceivedDate());
            }
            if (order.getOrderDates().getBookingDate() != null) {
                result.setBookingDate(order.getOrderDates().getBookingDate());
            }
            if (order.getOrderDates().getRequiredOnSiteDate() != null) {
                result.setRequiredAtDCDate(order.getOrderDates().getRequiredOnSiteDate());
            }
            result.setIncoterm(shippingInformation.getIncoterm());
            if (shippingInformation.getFreightForwarder() != null) {
                result.setFreightForwarder(shippingInformation.getFreightForwarder());
            }
            result.setPlaceOfLoading(shippingInformation.getPlaceOfLoading());
            result.setPlaceOfDischarge(shippingInformation.getPlaceOfDischarge());
            if (shippingInformation.getCountryOfOrigin() != null) {
                result.setCountry(shippingInformation.getCountryOfOrigin().getCode());
            }

            result.setFinalDestination(shippingInformation.getFinalDestination() != null ? shippingInformation.getFinalDestination() :
                    new FinalDestination("", ""));
        }
        if (container == null) {
            Set<ConsignmentContainer> containers = order.getConsignment().getContainers();
            if (containers != null && !containers.isEmpty()) {
                result.setContainerTypes(containers.stream().map(c -> c.getContainerType().getName()).collect(Collectors.joining(",")));
             //   result.setShippingTypes(containers.stream().map(c -> c.getShippingType().getName()).collect(Collectors.joining(",")));
            }
        }

        result.setActualDepartureDate(null);
        if (order.getConsignment() != null) {
            if (order.getConsignment().getArrivalDateAtPlaceOfDischarge() != null) {
                result.setArrivalDateAtPlaceOfDischarge(order.getConsignment().getArrivalDateAtPlaceOfDischarge());
            }

            if (shipment1 != null) {

                if (shipment1 instanceof SeaShipment) {
                    SeaShipment seaShipment = (SeaShipment) shipment1;
                    result.setBerthingDateAndTime(seaShipment.getBerthingDateTime() != null ?
                            seaShipment.getBerthingDateTime() : null);
                }
                if (shipment1.getReference() != null) {
                    result.setShipmentReference(shipment1.getReference());
                }
                if (shipment1.getNumber() != null) {
                    result.setShipmentNumber(shipment1.getNumber());
                }
                if (shipment1.getOriginalDocumentsReceivedDate() != null) {
                    result.setOriginalDocumentsReceivedDate(shipment1.getOriginalDocumentsReceivedDate());
                }
                if (shipment1.getEstimatedArrivalDateAtPlaceOfDischarge() != null) {
                    result.setEstimatedArrivalDateAtPlaceOfDischarge(shipment1
                            .getEstimatedArrivalDateAtPlaceOfDischarge());
                }
                result.setShipmentId(shipment1.getId());
                if (shipment1.getScheduledDepartureDate() != null) {
                    result.setScheduledDepartureDate(shipment1.getScheduledDepartureDate());
                }

                if (shipment1.getShippedOnBoardDate() != null) {
                    result.setShippedOnBoardDate(shipment1.getShippedOnBoardDate());
                }
                result.setOriginalEstimateArrivalDate(shipment1.getOriginalEstimatedArrivalDateAtPlaceOfDischarge());
                result.setPlaceOfLoading(shipment1.getShippingInfo().getPlaceOfLoading());

                if (shipment1.getShippingInfo().getFreightForwarder() != null) {
                    result.setFreightForwarder(shipment1.getShippingInfo().getFreightForwarder());
                }
                if (shipment1.getShippingInfo().getClearingAgent() != null) {
                    result.setClearingAgent(shipment1.getShippingInfo().getClearingAgent());
                }
                if (shipment1.getActualDepartureDate() != null) {
                    result.setActualDepartureDate(shipment1.getActualDepartureDate());
                }
                if (shipment1.getIncoterm() != null) {
                    result.setIncoterm(shipment1.getIncoterm());
                }
                if (!result.isClearingIntegrationEnabled()) {
                    result.setMrnNumber(shipment1.getMrnNumbers());
                } else if (result.isClearingIntegrationEnabled()) {
                    result.setMrnNumber(shipment1.getClearingMrnNumbers());
                }
                if (shipment1.getLrnNumbers() != null) {
                    result.setLrnNumber(shipment1.getLrnNumbers());
                }
                result.setBillOfLadingDate(shipment1.getBillOfLadingDate());
                if (shipment1.getShippingMode() == ShippingMode.SEA) {
                    SeaShipment seaShipment = (SeaShipment) HibernateUtils.initializeAndUnproxy(shipment1);
                    result.setVoyageNumber(seaShipment.getVoyageNumber());
                    result.setTransporterName(seaShipment.getShippingVessel());
                    result.setTransportDocumentNumber(seaShipment.getMasterBillOfLadingReference());
                    result.setMasterBillDate(seaShipment.getMasterBillOfLadingDate());
                    result.setHouseBillNumber(seaShipment.getBillOfLadingReference());
                    setCarrier(seaShipment.getCarrier(), result);

                } else if (shipment1.getShippingMode() == ShippingMode.AIR) {
                    AirShipment airShipment = (AirShipment) HibernateUtils.initializeAndUnproxy(shipment1);
                    result.setVoyageNumber(airShipment.getFlightNumber());
                    result.setTransporterName(airShipment.getAirlineName());
                    result.setTransportDocumentNumber(airShipment.getMasterAirwayBillNumber());
                    result.setMasterBillDate(airShipment.getMasterAirwayBillIssueDate());
                    result.setHouseBillNumber(airShipment.getHouseAirwayBillNumber());
                    setCarrier(airShipment.getCarrier(), result);

                    if (airShipment.getCarrier() != null) {
                        Set<ServiceProviderType> serviceProviderTypes =
                                airShipment.getCarrier().getServiceProviderTypes();
                        if (CollectionUtils.isNotEmpty(serviceProviderTypes)) {
                            for (ServiceProviderType serviceProviderType : serviceProviderTypes) {
                                if (serviceProviderType.equals(ServiceProviderType.MASTER_CARRIER)) {
                                    //result.getCarrier().setName(airShipment.getCarrier().getName());
                                    result.setCarrier(airShipment.getCarrier());
                                }
                            }
                        }
                    }
                }

                if (container != null) {
                    if (container.getContainerDates().getCarrierReleaseDate() == null) {
                        result.setCarrierReleaseDate(null);
                    } else {
                        result.setCarrierReleaseDate(container.getContainerDates().getCarrierReleaseDate());
                    }
                    if (container.getTransporter() != null) {
                        result.setDestinationTransporter(container.getTransporter().getName());
                    }
                }
                StringBuilder shipmentComments = new StringBuilder();
                if (shipment1.getComments() != null) {
                    for (AddedComment addedComment : shipment1.getComments()) {
                        shipmentComments.append(addedComment.getReason());
                        shipmentComments.append(" ");
                    }
                    result.setShipmentComments(shipmentComments.toString());
                }
                Set<Transhipment> transhipmentSet = shipment1.getTranshipments();
                if (null != transhipmentSet && !transhipmentSet.isEmpty()) {
                    Transhipment transhipment = transhipmentSet.iterator().next();
                    result.setFeederVoyageNumber(transhipment.getVoyageNumber());
                    result.setFeederTransporterName(transhipment.getVesselName());
                    result.setFeederPlaceOfLoading(transhipment.getPlaceOfLoading());
                    result.setFeederPlaceOfDischarge(transhipment.getPlaceOfLoadingTo());
                    result.setFeederActualDepartureDate(transhipment.getActualDateOfDeparture());
                    result.setFeederEstimateDepartureDate(transhipment.getEstimatedDepartureDate());
                    result.setEstimateArrivalDateatTranshipmentPort(transhipment.getEstimatedArrivalDateAtTranshipmentPort());
                    result.setActualArrivalDateatTranshipmentPort(transhipment.getActualArrivalDateAtTransshipmentPort());
                }
                if (shipment1.getShippingInfo().getPlaceOfLoading().getCountry().getName() != null) {
                    result.setCountry(shipment1.getShippingInfo().getPlaceOfLoading().getCountry().getName());
                }
                if (getLastEventDate(shipment1, ShipmentEventType.SIGNED_OFF) != null) {
                    result.setActualCostingCompleteDate(getLastEventDate(shipment1, ShipmentEventType.SIGNED_OFF));
                }
                if (shipment1.getArrivalDateAtPlaceOfDischarge() != null) {
                    result.setActualArrivalAtPOD(shipment1.getArrivalDateAtPlaceOfDischarge());
                }
                if (shipment1.getEstimatedArrivalDateAtPlaceOfDischarge() != null) {
                    result.setEstimatedArrivalAtPOD(shipment1.getEstimatedArrivalDateAtPlaceOfDischarge());
                }
            }
        }

        result.setOrderReference(order.getOrderReference() != null ? order.getOrderReference() : "");

        result.setOrderState(order.getState());
        result.setBusinessState(order.getBusinessState() != null ? order.getBusinessState().name() : "");

        if (order.getSupplier() != null)
            result.setSupplier(order.getSupplier().getSupplier());
        result.setGoodsReceivedDate(order.getOrderDates().getGoodsReceivedDate() != null ? order.getOrderDates().getGoodsReceivedDate() : null);

        if (order.getBuyer() != null) {
            result.setBuyer(order.getBuyer());
        }
        result.setBusinessUnit(order.getOrganisationalUnit().getParent() != null ? order.getOrganisationalUnit().getParent() : null);
        result.setDivision(order.getOrganisationalUnit() != null ? order.getOrganisationalUnit() : null);
        result.setSuppliersInvoiceValue(order.getTotalInvoiceValue() != null ? order.getTotalInvoiceValue() : null);
        result.setLastestShipmentDate(order.getOrderDates().getLatestShipmentDate());
        result.setOrderEstArrivalAtPODDate(order.getOrderDates().getArrivalAtPlaceOfDischargeDate());
        result.setOrderDescription(order.getDescription());
        result.setShippingReference(order.getShippingInformation().getShippingReference());

        if (container != null) {
            logisticsContainer(result, container);
        }
        setLogisticsDates(result);
    }

    private static void setCarrier(ServiceProvider serviceProvider, LogisticsSummarySearchResult result) {
        if (serviceProvider != null) {
            Set<ServiceProviderType> serviceProviderTypes =
                    serviceProvider.getServiceProviderTypes();
            if (CollectionUtils.isNotEmpty(serviceProviderTypes)) {
                for (ServiceProviderType serviceProviderType : serviceProviderTypes) {
                    if (serviceProviderType.equals(ServiceProviderType.MASTER_CARRIER)) {
                        result.setCarrier(serviceProvider);
                    }
                }
            }
        }
    }

    private static void setLogisticsDates(LogisticsSummarySearchResult result) {
        result.setFreightReceivedDays(DateUtils.getDaysBetweenObject(result.getAvailabilityDate(), result.getFreightReceivedDate()));
        if (result.getActualDepartureDate() != null) {
            result.setDepartureDays(DateUtils.getDaysBetweenObject(result.getLastestShipmentDate(), result.getActualDepartureDate()));
        } else {
            result.setDepartureDays(DateUtils.getDaysBetweenObject(result.getLastestShipmentDate(), result.getScheduledDepartureDate()));
        }
        if (result.getActualDepartureDate() != null) {
            result.setArrivalAtPortDays(DateUtils.getDaysBetweenObject(result.getOrderEstArrivalAtPODDate(), result.getActualArrivalAtPOD()));
        } else {
            result.setArrivalAtPortDays(DateUtils.getDaysBetweenObject(result.getOrderEstArrivalAtPODDate(), result.getEstimatedArrivalAtPOD()));
        }

        if (result.getActualDepartureDate() != null) {
            result.setArrivalAtFDDays(DateUtils.getDaysBetweenObject(result.getRequiredAtDCDate(), result.getAtaAtFinalDestination()));
        } else {
            result.setArrivalAtFDDays(DateUtils.getDaysBetweenObject(result.getRequiredAtDCDate(), result.getEtaAtFinalDestination()));
        }
    }

    private static void logisticsContainer(LogisticsSummarySearchResult result, ShipmentContainer container) {
        result.setContainerReference(container.getReference() != null ? container.getReference() : "");
        result.setFinalDestination(container.getFinalDestination() != null ? container.getFinalDestination() : new FinalDestination("", ""));
//            result.setContainerType(container.getContainerType() != null ? container.getContainerType() : new ContainerType("", ""));
        result.setContainerTypes(container.getContainerType() != null ? container.getContainerType().getName() : "");
        result.setShippingTypes(container.getShippingType() != null ? container.getShippingType().getName() : "");
        result.setPlaceOfDischarge(container.getPlaceOfDischarge() != null ? container.getPlaceOfDischarge() : new PlaceOfDischarge("", ""));
        result.setSealReference(container.getSealReference());
        result.setCustomsStopFlag(container.isStoppedByCustoms() ? "Yes" : "No");
        result.setCustomsStopUnpacked(container.isCustomsStopUnpacked() ? "Yes" : "No");
        if (container.getContainerDates() != null) {
            if (container.getContainerDates().getDischargeDate() != null)
                result.setDischargeDate(container.getContainerDates().getDischargeDate());
            result.setCustomsEntryDate(container.getContainerDates().getCustomsEntryDate());
            result.setCustomsExitDate(container.getContainerDates().getCustomsExitDate());
            if (container.getContainerDates().getPickUpDate() != null) {
                result.setPickUpDate(container.getContainerDates().getPickUpDate());
            }
            if (container.getContainerDates().getEtaAtFinalDestination() != null) {
                result.setEtaAtFinalDestination(container.getContainerDates().getEtaAtFinalDestination());
            }
            if (container.getContainerDates().getAtaAtFinalDestination() != null) {
                result.setAtaAtFinalDestination(container.getContainerDates().getAtaAtFinalDestination());
            }
        }
    }

    public static void populateSupplierSummarySearchResult(SupplierSummarySearchResult result, AbstractSupplier supplier, String organisationalUnit) {

        result.setName(supplier.getName());
        result.setReference(supplier.getExternalReference());
        result.setCountry(supplier.getPhysicalAddress().getCountry());
        result.setComplete((supplier.getComplete() ? CompleteType.COMPLETE : CompleteType.INCOMPLETE));
        result.setState(supplier.getState());
        result.setCreatedFrom(supplier.getCreated());
        result.setCurrency(supplier.getCurrency());
        result.setOrganisationalUnit(organisationalUnit);
    }

    public static <S extends Enum<?>, X extends Event> Date getLastEventDate(Stateful<S, X> stateful, Enum e) {
        Date date = null;
        for (Event event : stateful.getEvents()) {
            // Should always be true
            if (event instanceof EnumTypedEvent) {
                if (((EnumTypedEvent) event).getEventType() == e) {
                    date = event.getCreateDateTime();
                }
            }
        }
        return date;
    }
}