SearchResultHelper.java

package com.tradecloud.dto.order;

import com.tradecloud.common.base.HibernateUtils;
import com.tradecloud.domain.base.utils.MathUtils;
import com.tradecloud.domain.comment.AddedComment;
import com.tradecloud.domain.comment.Commentable;
import com.tradecloud.domain.container.ConsignmentContainer;
import com.tradecloud.domain.container.ContainerType;
import com.tradecloud.domain.event.*;
import com.tradecloud.domain.item.LineItem;
import com.tradecloud.domain.model.ordermanagement.Consignment;
import com.tradecloud.domain.model.ordermanagement.Order;
import com.tradecloud.domain.model.ordermanagement.PurchaseOrder;
import com.tradecloud.domain.shipment.Shipment;
import com.tradecloud.domain.state.Stateful;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 *
 */
public class SearchResultHelper {
    private final static Logger log = Logger.getLogger(SearchResultHelper.class);

    private static final String FLATTEN_SEP = " ";
    private static final int ROUND_SCALE_4 = 4;

    private static final int ROUND_SCALE_2 = 2;

    private static String flattenComments(Collection<AddedComment> comments) {
        String s = "";
        for (AddedComment comment : comments) {
            s += comment.getReason() + FLATTEN_SEP;
        }
        return StringUtils.removeEnd(s, FLATTEN_SEP);
    }

    public static String flattenComments(Commentable commentable) {
        String s = "";
        s += flattenComments(commentable.getComments());
        return s;
    }

    public static String flattenComments(List<AddedComment> commentList, String delimeter) {
        boolean isFirstIteration = true;
        StringBuilder stringBuilder = new StringBuilder();

        for (AddedComment addedComment : commentList) {
            if (isFirstIteration) {
                isFirstIteration = false;

                stringBuilder.append(addedComment.getReason());
            } else {
                stringBuilder.append(delimeter).append(addedComment.getReason());
            }
        }

        return stringBuilder.toString();
    }

    public static void populateOrdersNotPackedSearchResult(OrderAwaitingStateSearchResult result, Order order) {
        Shipment shipment = order.getConsignment().getShipment();

        result.setOrderId(order.getId());
        result.setOrderType(order.getType());
        result.setPurchaseOrderNumber(order.getNumber());
        result.setOrderReference(order.getOrderReference());
        result.setShipmentType(shipment.getShippingMode().name());
        result.setShipmentId(shipment.getId());
        result.setShipmentNumber(shipment.getNumber());
        result.setShipmentReference(shipment.getReference());
        result.setShipmentCreatedDate(shipment.getCreated());
        result.setFreightForwarder(order.getShippingInformation().getFreightForwarder().getName());
    }

    public static void populateOrderAwaitingStateSearchResult(OrderAwaitingStateSearchResult result, Order order) {
        Consignment consignment = order.getConsignment();

        if (consignment != null) {
            result.setConsignmentId(consignment.getId());
            result.setConsignmentReference(consignment.getReference());
            result.setConsignmentState(consignment.getState().name());
            List<AddedComment> consignmentCommentList = consignment.getComments();
            String flattenedConsignmentComments = "";
            if (consignmentCommentList.size() > 0) {
                flattenedConsignmentComments = flattenComments(consignment.getComments());
            }
            result.setConsignmentComments(flattenedConsignmentComments);

            // Now done from the caller
            BigDecimal teu = getTEUCount(consignment);
            result.setTeuCount( MathUtils.setScale(teu, MathUtils.SCALE_FOUR) );
        } else {
            //set default values to conform to xml well formedness
            result.setConsignmentId(new Long(0));
            result.setConsignmentReference("");
            result.setConsignmentState("");
            result.setConsignmentComments("");
        }

        result.setOrderId(order.getId());
        result.setOrderType(order.getType());
        result.setOrderReference(order.getOrderReference());
        result.setPurchaseOrderNumber(order.getNumber());
        result.setProFormaReference(order.getProFormaReference() == null ? "" : order.getProFormaReference());
        result.setConfirmed(order.isConfirmed() == true ? "CONFIRMED" : "UNCONFIRMED");
        if (order.isPurchaseOrder()) {
            order= HibernateUtils.initializeAndUnproxy(order);
            PurchaseOrder pOrder = (PurchaseOrder) order;
            result.setSupplier(pOrder.getSupplier());
            result.setSupplierName(pOrder.getSupplier().getSupplier().getName());
            if (order.getBuyer() != null) {
                result.setBuyer(pOrder.getBuyer());
                result.setBuyerFullName(pOrder.getBuyer().getFullName());
            }
        }
        if(null != order.getLineItems() && order.getLineItems().size() > 0){
            Set<LineItem> lineItems = order.getLineItems();
            String styleReference = "";
            String styleDescription = "";
            String materialComposition = "";
            Set<String> referenceSet = new HashSet<>();
            Set<String> descriptionSet = new HashSet<>();
            Set<String> compositionSet = new HashSet<>();
            for (LineItem lineItem : lineItems) {
                if(lineItem.getStyleReference() != null && !referenceSet.contains(lineItem.getStyleReference().trim())){
                    styleReference = styleReference + (lineItem.getStyleReference() == null ? "" : lineItem.getStyleReference().trim() + " ,");
                    referenceSet.add(lineItem.getStyleReference().trim());
                }
                if(lineItem.getStyleDescription() != null && !descriptionSet.contains(lineItem.getStyleDescription().trim())){
                    styleDescription =
                            styleDescription + (lineItem.getStyleDescription() == null ? "" : lineItem.getStyleDescription().trim() + " ,");
                    descriptionSet.add(lineItem.getStyleDescription().trim());
                }
                if(lineItem.getMaterialComposition() != null && !compositionSet.contains(lineItem.getMaterialComposition().trim())){
                    materialComposition =
                            materialComposition + (lineItem.getMaterialComposition() == null ? "" : lineItem.getMaterialComposition().trim() + " ,");
                    compositionSet.add(lineItem.getMaterialComposition().trim());
                }
            }
            styleReference = styleReference.length() > 0 ? styleReference.substring(0, styleReference.lastIndexOf(",")).trim() : styleReference;
            styleDescription =
                    styleDescription.length() > 0 ? styleDescription.substring(0, styleDescription.lastIndexOf(",")).trim() : styleDescription;
            materialComposition =
                    materialComposition.length() > 0 ? materialComposition.substring(0, materialComposition.lastIndexOf(",")).trim()
                            : styleReference;
            result.setStyleReference(styleReference);
            result.setStyleDescription(styleDescription);
            result.setMaterialComposition(materialComposition);
        }

        result.setLatestShipmentDate(order.getOrderDates().getLatestShipmentDate());
        result.setFinalDestination(order.getShippingInformation().getFinalDestination());
        result.setPlaceOfLoading(order.getShippingInformation().getPlaceOfLoading());
        result.setOrganisationalUnit(order.getOrganisationalUnit());
        result.setOrgUnitName(order.getOrderOrganisationalUnit().getName().replace(",", " "));
        result.setOrderComments(flattenComments(order.getComments()));

        //String orderUnsignoffReason = getOrderUnsignoffReason((PurchaseOrder) order) == null ? "" : getOrderUnsignoffReason((PurchaseOrder) order);
        result.setOrderUnsignoffReason( getStatesAsString(order, OrderEventType.UNSIGNED_OFF));
        //SEE CALLING METHOD FOR BELLOW TAL SUPPLIERS INVOICE VALUE
        //result.setTotalSuppliersInvoice("0.00");
        result.setTotalSuppliersInvoiceCurrency(order.getCurrency().getCode());
        result.setOrderStateName(order.getState().name());
        result.setProformaReceivedDate(order.getOrderDates().getProformaReceivedDate());
    }

    public static void populateOrderAwaitingStateSearchResult(OrderAwaitingStateSearchResult result, LineItem lineItem) {
        Order order = lineItem.getOrder();
        populateOrderAwaitingStateSearchResult(result, order);
        result.setShippingReference(order.getShippingInformation().getShippingReference());
        result.setItemId(lineItem.getId());
        result.setItemReference(lineItem.getCode());
        result.setItemStyleReference(lineItem.getStyleReference());
        result.setItemStyleDescription(lineItem.getStyleDescription());
        result.setItemMaterialComposition(lineItem.getMaterialComposition());
        result.setItemDescription(lineItem.getDescription());
    }

    public static void populateOrderDeletedSearchResult(OrderDeletedSearchResult result, Order order) {
        result.setOrderId(order.getId());
        result.setOrderType(order.getType());
        result.setOrderReference(order.getOrderReference());
        result.setProFormaReference(order.getProFormaReference());
        if (order.isPurchaseOrder()) {
            result.setSupplier(((PurchaseOrder) order).getSupplier());
            result.setBuyer(((PurchaseOrder) order).getBuyer());
        }
        result.setShippingReference(order.getShippingInformation().getShippingReference());
        result.setLatestShipmentDate(order.getOrderDates().getLatestShipmentDate());
        result.setOrganisationalUnit(order.getOrganisationalUnit());
    }

    /*public static List<OrderConfirmationSearchResult> createAndPopulateOrderConfirmationSearchResultList(Order order) {
        List<OrderConfirmationSearchResult> resultList = new ArrayList<OrderConfirmationSearchResult>();

        for (LineItem lineItem : order.getLineItems()) {
            OrderConfirmationSearchResult result = new OrderConfirmationSearchResult();
            result.setOrderId(order.getId());
            result.setConsignmentReference(order.getConsignment().getReference());
            result.setOrderReference(order.getOrderReference());
            result.setShippingReference(order.getShippingInformation().getShippingReference());
            result.setSupplierName(((PurchaseOrder) order).getSupplier().getName());
            result.setLatestShipmentDate(order.getOrderDates().getLatestShipmentDate());
            result.setDivisionName(order.getOrganisationalUnit().getName());
            result.setBusinessUnitName(order.getOrganisationalUnit().getParent().getName());
            result.setBuyer(((PurchaseOrder) order).getBuyer().getFullName());
            result.setFreightForwarder(order.getShippingInformation().getFreightForwarder().getName());
            result.setLspBookingReference(order.getLspBookingReference() == null ? "" : order.getLspBookingReference());
            result.setStatus(order.getState().name());
            List<OrdersEvent> events = order.getEvents();
            for (OrdersEvent event : events) {
                if (event.getEventType().equals(OrderEventType.LSP_REJECTED_SIGNOFF) ||
                  event.getEventType().equals(OrderEventType.LSP_REJECTED_UNSIGNOFF)) {
                    result.setRejectReason(event.getReason());
                }
            }

            if (result.getRejectReason() == null) {
                result.setRejectReason("");
            }
            result.setItemReference(lineItem.getCode());
            result.setItemQuantity(MathUtils.setScale(lineItem.getUnitQuantity(), ROUND_SCALE_2));
//            result.setItemInvoiceValue(lineItem.getTotalCostInclVat().doubleValue());//to be set by calling method.


            result.setItemInvoiceValue(MathUtils.setScale(lineItem.getTotalCostInclVat(), ROUND_SCALE_4));//to be set by calling method.



            result.setInvoiceCurrency(order.getCurrency().getCode());

            resultList.add(result);
        }

        return resultList;
    }*/



    // Use the query in OrderRepository
    @Deprecated
    public static BigDecimal getTEUCount(Consignment consignment) {
        if (consignment == null) {
            return BigDecimal.ZERO;//failing on tests, to look at
        }
        if (consignment.getContainers() == null) {
            return BigDecimal.ZERO;//failing on tests, to look at
        }

        double containerCount = 0;
        for (ConsignmentContainer container : consignment.getContainers()) {
            // TODO. Use containerType.getTeu
            ContainerType containerType = container.getContainerType();
            if (containerType.getName().contains("20") || containerType.isLCL()) {
                containerCount += container.getQuantity().doubleValue();
            } else {
                containerCount += (container.getQuantity().doubleValue() * 2);
            }
        }
        return BigDecimal.valueOf(containerCount);
    }

    public static <S extends Enum<?>, X extends Event> String getStatesAsString(Stateful<S,X> stateful, EventType ...eventType) {
        DateFormat df = new SimpleDateFormat("yyyy/MM/dd");
        List<String> s = new ArrayList<>();
        // If there are no states listed, get all of them
        if ( eventType.length == 0 ) {
            for ( X event : stateful.getEvents()) {
                s.add(df.format(event.getCreateDateTime()) + " - " + event.getReason());
            }
        } else {
            Collection<EventType> eventTypeCol = Arrays.asList(eventType);
            for ( X event : stateful.getEvents()) {
                // Stupid legacy stuff
                if ( event instanceof EnumTypedEvent ) {
                    EnumTypedEvent ee = (EnumTypedEvent)event;
                    if ( eventTypeCol.contains(ee.getEventType()) ) {
                        s.add(df.format(event.getCreateDateTime()) + " - " + event.getReason());
                    }
                }
            }
        }
        return StringUtils.join(s, ";");
    }

    // Use getStateAsString(order, OrderEventType.UNSIGN_OFF
    @Deprecated
    public static String getOrderUnsignoffReason(PurchaseOrder order) {
        String unsignOffReason = "";
        List<OrdersEvent> events = order.getEvents();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyy/MM/dd");
        for (OrdersEvent event : reverseListOrder(events)) {
            if (event.getEventType().equals(OrderEventType.UNSIGNED_OFF)) {
                unsignOffReason = dateFormat.format(event.getCreated())+" - "+event.getReason();
                break;
            }
        }

        return unsignOffReason;
    }

    private static List<OrdersEvent> reverseListOrder(List<OrdersEvent> events) {
        if(events != null && events.size() > 1) {
            OrdersEvent firstOrderEvent = events.get(0);
            OrdersEvent lastEvent = events.get(events.size() - 1);

            if(firstOrderEvent.getCreated().before(lastEvent.getCreated())) {
                Collections.reverse(events);
                return events;
            }
        }

        return events;
    }
}