BusinessDisplayNodeRepositoryImpl.java

package com.tradecloud.repository.impl;

import com.tradecloud.domain.costing.CostingContextType;
import com.tradecloud.domain.document.CommercialCreditNote;
import com.tradecloud.domain.document.ServiceProviderCreditNote;
import com.tradecloud.domain.document.invoice.CommercialInvoice;
import com.tradecloud.domain.document.invoice.ServiceProviderInvoice;
import com.tradecloud.domain.item.LineItem;
import com.tradecloud.domain.model.ordermanagement.*;
import com.tradecloud.domain.shipment.Shipment;
import com.tradecloud.dto.base.BusinessDisplayNode;
import com.tradecloud.repository.BusinessDisplayNodeRepository;
import com.tradecloud.repository.ConfigPropertyRepository;
import org.apache.commons.lang3.ArrayUtils;
import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;

/**
 * @author jon
 */
@Repository(value = "businessDisplayNodeRepository")
public class BusinessDisplayNodeRepositoryImpl extends GeneralRepositoryImpl implements BusinessDisplayNodeRepository {

    @Autowired
    private ConfigPropertyRepository configPropertyRepository;

    /**
     * The row will contain sets of 4. {id, reference, shippingReference, state,
     * type} for Order {id, reference, null, state} for Consignment/Shipment
     * {id, code, null, state} for LineItem
     *
     * @param row
     * @param offSet
     * @param c
     * @return
     */
    private BusinessDisplayNode createNode(Object row[], int offset, Class c) {
        Object shortDesc = row[offset + 2] != null ? row[offset + 2] : row[offset + 1];
        // Don't know how to select a null value, so using state as a dummy. Undoing the hack here.
        Object type = row[offset + 3] == row[offset + 4] ? null : row[offset + 4];
        return createNode(row[offset + 0], c, shortDesc, row[offset + 3], type);
    }

    private BusinessDisplayNode createNode(Object o1, Object o2, Object o3, Object o4, Object o5) {
        return new BusinessDisplayNode((Long) o1, (Class) o2, (String) o3, (Enum) o4, (Enum) o5);
    }

    @Override
    public BusinessDisplayNode getShipmentParents(Shipment shipment) {
        String queryString
                = "SELECT s.id, s.number, s.reference||'('||s.number||')', s.state, ssi.shippingMode "
                + "FROM Shipment s JOIN s.shippingInfo ssi "
                + "WHERE s=:shipment";

        Query query = getSessionCustom().createQuery(queryString);
        query.setParameter("shipment", shipment);
        query.setMaxResults(1);
        List list = query.list();
        // Only one row will be returned, with all our results in it
        Object row[] = (Object[]) list.get(0);

        BusinessDisplayNode shipmentNode;

        shipmentNode = createNode(row, 0, Shipment.class);

        return shipmentNode;
    }

    @Override
    public BusinessDisplayNode getConsignmentParents(Consignment consignment) {
        // Can't get the order type from the db easily.
        // Also can't select a null into a value easily, so using state as a hack.
        String queryString
                = "SELECT c.id, c.reference, c.reference, c.state, c.state, "
                + "s.id, s.number, s.reference||'('||s.number||')', s.state, ssi.shippingMode  "
                + "FROM Consignment c LEFT JOIN c.shipment s LEFT JOIN s.shippingInfo ssi "
                + "WHERE c=:consignment";

        Query query = getSessionCustom().createQuery(queryString);
        query.setParameter("consignment", consignment);
        List list = query.list();
        // Only one row will be returned, with all our results in it
        Object row[] = (Object[]) list.get(0);

        // Hardcoding the types for now
        BusinessDisplayNode consignmentNode = createNode(row, 0, Consignment.class);
        BusinessDisplayNode shipmentNode = createNode(row, 5, Shipment.class);

        shipmentNode.setChildren(new BusinessDisplayNode[]{consignmentNode});
        return shipmentNode;
    }

    @Override
    public BusinessDisplayNode getOrderParents(Order order) {
        // Can't get the order type from the db easily.
        String queryString
                = "SELECT o.id, o.orderReference, osi.shippingReference, o.state, o.state, "
                + "c.id, c.number, c.reference, c.state, c.state, "
                + "s.id, s.number, s.reference||'('||s.number||')', s.state, ssi.shippingMode "
                + "FROM Order o LEFT JOIN o.shippingInformation osi "
                + "LEFT JOIN o.consignment c "
                + "LEFT JOIN c.shipment s LEFT JOIN s.shippingInfo ssi "
                + "WHERE o=:order";

        Query query = getSessionCustom().createQuery(queryString);
        query.setParameter("order", order);
        List list = query.list();
        // Only one row will be returned, with all our results in it
        Object row[] = (Object[]) list.get(0);
        //
        String property = configPropertyRepository.getProperty("order.breadcrumb.orderReference");
        if (property != null && Boolean.valueOf(property)) {
            row[2] = null;
        }

        // Hardcoding the types for now
        BusinessDisplayNode orderNode = createNode(row, 0, PurchaseOrder.class);
        BusinessDisplayNode consignmentNode = createNode(row, 5, Consignment.class);
        BusinessDisplayNode shipmentNode = createNode(row, 10, Shipment.class);

        shipmentNode.setChildren(new BusinessDisplayNode[]{consignmentNode});
        consignmentNode.setChildren(new BusinessDisplayNode[]{orderNode});
        return shipmentNode;
    }

    @Override
    public BusinessDisplayNode getLineItemParents(LineItem lineItem) {
        // Can't get the order type from the db easily.
        String queryString
                = "SELECT i.id, i.code, i.code, i.state, i.state, "
                + "o.id, o.orderReference, osi.shippingReference, o.state, o.state, "
                + "c.id, c.number, c.reference, c.state, c.state, "
                + "s.id, s.number, s.reference||'('||s.number||')', s.state, ssi.shippingMode "
                + "FROM LineItem i "
                + "LEFT JOIN i.order o LEFT JOIN o.shippingInformation osi "
                + "LEFT JOIN o.consignment c "
                + "LEFT JOIN c.shipment s LEFT JOIN s.shippingInfo ssi "
                + "WHERE i=:lineItem";

        Query query = getSessionCustom().createQuery(queryString);
        query.setParameter("lineItem", lineItem);
        List list = query.list();
        // Only one row will be returned, with all our results in it
        Object row[] = (Object[]) list.get(0);

        // Hardcoding the types for now
        BusinessDisplayNode lineItemNode = createNode(row, 0, LineItem.class);
        BusinessDisplayNode orderNode = createNode(row, 5, PurchaseOrder.class);
        BusinessDisplayNode consignmentNode = createNode(row, 10, Consignment.class);
        BusinessDisplayNode shipmentNode = createNode(row, 15, Shipment.class);

        shipmentNode.setChildren(new BusinessDisplayNode[]{consignmentNode});
        consignmentNode.setChildren(new BusinessDisplayNode[]{orderNode});
        orderNode.setChildren(new BusinessDisplayNode[]{lineItemNode});
        return shipmentNode;
    }

    private BusinessDisplayNode[] getChildren(String queryString, String idName, long id, Class childClass) {
        Query query = getSessionCustom().createQuery(queryString);
        query.setParameter(idName, id);
        List list = query.list();
//        Collections.sort(list);
        List<BusinessDisplayNode> results = new ArrayList<BusinessDisplayNode>();
        for (Object o : list) {
            // Only one row will be returned, with all our results in it
            Object row[] = (Object[]) o;

            // Hardcoding the types for now
            BusinessDisplayNode node = createNode(row, 0, childClass);
            results.add(node);
        }
        return results.toArray(new BusinessDisplayNode[0]);
    }

    private BusinessDisplayNode[] getOrderLineItems(long orderId) {
        String queryString = "SELECT i.id, i.code, i.code, i.state, i.state "
                + "FROM LineItem i "
                + "WHERE i.order.id=:orderId AND i.state != 'DELETED' "
                + "Order by position,addedtoorderdate";
        return getChildren(queryString, "orderId", orderId, LineItem.class);
        /*
         Query query = getSession().createQuery(queryString);
         query.setParameter("orderId", orderId);
         List list = query.list();
         List<BusinessDisplayNode> results = new ArrayList<BusinessDisplayNode>();
         for (Object o : list) {
         // Only one row will be returned, with all our results in it
         Object row[] = (Object[]) o;

         // Hardcoding the types for now
         BusinessDisplayNode node = createNode(row, 0, LineItem.class);
         results.add(node);
         }
         return results.toArray(new BusinessDisplayNode[0]);
         */
    }

    private BusinessDisplayNode[] getConsignmentOrders(long consignmentId, CostingContextType costingContextType) {
        String queryString = "SELECT o.id, o.orderReference, osi.shippingReference, o.state, o.state "
                + "FROM Order o JOIN o.shippingInformation osi "
                + "WHERE o.consignment.id=:consignmentId AND o.state != 'DELETED' ORDER BY o.addedToConsignmentDate";
        Class childClass = PurchaseOrder.class;
        if (costingContextType == CostingContextType.EXPORT) {
            childClass = SalesOrder.class;
        }
        return getChildren(queryString, "consignmentId", consignmentId, childClass);
    }

    private BusinessDisplayNode[] getConsignmentCommercialInvoices(long consignmentId) {
        String queryString = "SELECT i.id, i.reference, i.reference, i.state, i.state "
                + "FROM CommercialInvoice i "
                + "WHERE i.consignment.id=:consignmentId AND i.state != 'DELETED'";
        return getChildren(queryString, "consignmentId", consignmentId, CommercialInvoice.class);
    }

    private BusinessDisplayNode[] getConsignmentServiceProviderInvoices(long consignmentId) {
        String queryString = "SELECT i.id, i.reference, i.reference, i.state, i.state "
                + "FROM ServiceProviderInvoice i "
                + "WHERE i.consignment.id=:consignmentId AND i.state != 'DELETED'";
        return getChildren(queryString, "consignmentId", consignmentId, ServiceProviderInvoice.class);
    }

    private BusinessDisplayNode[] getShipmentConsignments(long shipmentId) {
        String queryString = "SELECT c.id, c.reference, c.reference, c.state, c.state "
                + "FROM Consignment c "
                + "WHERE c.shipment.id=:shipmentId AND c.state != 'DELETED' ORDER BY c.addedToShipmentDate";
        return getChildren(queryString, "shipmentId", shipmentId, Consignment.class);
    }

    private BusinessDisplayNode[] getShipmentCommercialInvoices(long shipmentId) {
        String queryString = "SELECT i.id, i.reference, i.reference, i.state, i.state "
                + "FROM CommercialInvoice i "
                + "WHERE i.shipment.id=:shipmentId AND i.state != 'DELETED'";
        return getChildren(queryString, "shipmentId", shipmentId, CommercialInvoice.class);
    }

    private BusinessDisplayNode[] getShipmentCommercialCreditNotes(long shipmentId) {
        String queryString = "SELECT i.id, i.reference, i.reference, i.state, i.state "
                + "FROM CommercialCreditNote i "
                + "WHERE i.shipment.id=:shipmentId AND i.state != 'DELETED'";
        return getChildren(queryString, "shipmentId", shipmentId, CommercialInvoice.class);
    }

    private BusinessDisplayNode[] getShipmentServiceProviderInvoices(long shipmentId) {
        String queryString = "SELECT i.id, i.reference, i.reference, i.state, i.state "
                + "FROM ServiceProviderInvoice i "
                + "WHERE i.shipment.id=:shipmentId AND i.state != 'DELETED'";
        return getChildren(queryString, "shipmentId", shipmentId, ServiceProviderInvoice.class);
    }

    private BusinessDisplayNode[] getShipmentServiceProviderCreditNotes(long shipmentId) {
        String queryString = "SELECT i.id, i.reference, i.reference, i.state, i.state "
                + "FROM ServiceProviderCreditNote i "
                + "WHERE i.shipment.id=:shipmentId AND i.state != 'DELETED'";
        return getChildren(queryString, "shipmentId", shipmentId, ServiceProviderInvoice.class);
    }

    @Override
    public BusinessDisplayNode getLineItemChildren(LineItem lineItem) {
        // Probably not really necessary. But neat.
        String queryString = "SELECT i.id, i.code, i.code, i.state, i.state "
                + "FROM LineItem i WHERE i=:lineItem ORDER BY addedToOrderDate";

        Query query = getSessionCustom().createQuery(queryString);
        query.setParameter("lineItem", lineItem);
        List list = query.list();
        // Only one row will be returned, with all our results in it
        Object row[] = (Object[]) list.get(0);

        // Hardcoding the types for now
        BusinessDisplayNode node = createNode(row, 0, LineItem.class);

        return node;
    }

    @Override
    public BusinessDisplayNode getOrderChildren(Order order) {
        // Probably not really necessary. But neat.
        String queryString = "SELECT o.id, o.orderReference, osi.shippingReference, o.state, o.state "
                + "FROM Order o JOIN o.shippingInformation osi "
                + "WHERE o=:order";

        Query query = getSessionCustom().createQuery(queryString);
        query.setParameter("order", order);
        List list = query.list();
        // Only one row will be returned, with all our results in it
        Object row[] = (Object[]) list.get(0);

        // Hardcoding the types for now
        BusinessDisplayNode node = createNode(row, 0, PurchaseOrder.class);

        node.setChildren(getOrderLineItems(node.getId()));

        return node;
    }

    @Override
    public BusinessDisplayNode getConsignmentChildren(Consignment consignment) {
        // Probably not really necessary. But neat.
        String queryString
                = "SELECT c.id, c.reference, c.reference, c.state, c.state "
                + "FROM Consignment c "
                + "WHERE c=:consignment";

        Query query = getSessionCustom().createQuery(queryString);
        query.setParameter("consignment", consignment);
        List list = query.list();
        // Only one row will be returned, with all our results in it
        Object row[] = (Object[]) list.get(0);

        Class c = Consignment.class;
        if (consignment.getCostingContextType() == CostingContextType.EXPORT) {
            c = ExportConsignment.class;
        }
        BusinessDisplayNode node = createNode(row, 0, c);
        // Hardcoding the types for now
        BusinessDisplayNode orderNodes[] = getConsignmentOrders(node.getId(), consignment.getCostingContextType());

        // This loop is not great, can probably combine queries, but it okay for now.
        for (BusinessDisplayNode bdn : orderNodes) {
            bdn.setChildren(getOrderLineItems(bdn.getId()));
        }

        BusinessDisplayNode invoiceNodes[] = ArrayUtils.addAll(getConsignmentCommercialInvoices(node.getId()),
                getConsignmentServiceProviderInvoices(node.getId()));

        node.setChildren(ArrayUtils.addAll(orderNodes, invoiceNodes));

        return node;
    }

    @Override
    public BusinessDisplayNode getShipmentChildren(Shipment shipment) {
        // Probably not really necessary. But neat.
        String queryString
                = "SELECT s.id, s.reference, s.reference||'('||s.number||')', s.state, ssi.shippingMode "
                + "FROM Shipment s LEFT JOIN s.shippingInfo ssi "
                + "WHERE s=:shipment";

        Query query = getSessionCustom().createQuery(queryString);
        query.setParameter("shipment", shipment);
        List list = query.list();
        // Only one row will be returned, with all our results in it
        Object row[] = (Object[]) list.get(0);

        // Hardcoding the types for now
        BusinessDisplayNode node = createNode(row, 0, Shipment.class);

        BusinessDisplayNode[] shipmentServiceProviderInvoices = getShipmentServiceProviderInvoices(node.getId());
        BusinessDisplayNode[] shipmentCommercialInvoices = getShipmentCommercialInvoices(node.getId());
        BusinessDisplayNode[] shipmentCommercialCreditNotes = getShipmentCommercialCreditNotes(node.getId());
        BusinessDisplayNode invoiceNodes[] = ArrayUtils.addAll(shipmentCommercialInvoices, shipmentCommercialCreditNotes);
        invoiceNodes = ArrayUtils.addAll(invoiceNodes, shipmentServiceProviderInvoices);
        BusinessDisplayNode[] shipmentServiceProviderCreditNotes = getShipmentServiceProviderCreditNotes(node.getId());
        invoiceNodes = ArrayUtils.addAll(invoiceNodes, shipmentServiceProviderCreditNotes);

        BusinessDisplayNode consignmentNodes[] = getShipmentConsignments(node.getId());

        // This loop is not great, can probably combine queries, but it okay for now.
        for (BusinessDisplayNode consignmentBdn : consignmentNodes) {
            consignmentBdn.setChildren(getConsignmentOrders(consignmentBdn.getId(),
                    shipment.isImports() ? CostingContextType.IMPORT : CostingContextType.EXPORT));
            for (BusinessDisplayNode orderBdn : consignmentBdn.getChildren()) {
                orderBdn.setChildren(getOrderLineItems(orderBdn.getId()));
            }
        }

        node.setChildren(ArrayUtils.addAll(invoiceNodes, consignmentNodes));

        return node;
    }

    @Override
    public BusinessDisplayNode getShipmentCommercialInvoiceParents(CommercialInvoice commercialInvoice) {
        // Can't get the order type from the db easily.
        String queryString
                = "SELECT ci.id, ci.reference, ci.reference, ci.state, ci.state, "
                + "s.id, s.number, s.reference||'('||s.number||')', s.state, ssi.shippingMode "
                + "FROM CommercialInvoice ci "
                + "LEFT JOIN ci.shipment s LEFT JOIN s.shippingInfo ssi "
                + "WHERE ci=:commercialInvoice";

        Query query = getSessionCustom().createQuery(queryString);
        query.setParameter("commercialInvoice", commercialInvoice);
        List list = query.list();
        // Only one row will be returned, with all our results in it
        Object row[] = (Object[]) list.get(0);

        // Hardcoding the types for now
        BusinessDisplayNode ciNode = createNode(row, 0, CommercialInvoice.class);
        BusinessDisplayNode shipmentNode = createNode(row, 5, Shipment.class);

        shipmentNode.setChildren(new BusinessDisplayNode[]{ciNode});
        return shipmentNode;
    }

    @Override
    public BusinessDisplayNode getShipmentServiceProviderInvoiceParents(ServiceProviderInvoice serviceProviderInvoice) {
        // Can't get the order type from the db easily.
        String queryString
                = "SELECT spi.id, spi.reference, spi.reference, spi.state, spi.state, "
                + "s.id, s.number, s.reference||'('||s.number||')', s.state, ssi.shippingMode "
                + "FROM ServiceProviderInvoice spi "
                + "LEFT JOIN spi.shipment s LEFT JOIN s.shippingInfo ssi "
                + "WHERE spi=:serviceProviderInvoice";

        Query query = getSessionCustom().createQuery(queryString);
        query.setParameter("serviceProviderInvoice", serviceProviderInvoice);
        List list = query.list();
        // Only one row will be returned, with all our results in it
        Object row[] = (Object[]) list.get(0);

        // Hardcoding the types for now
        BusinessDisplayNode spiNode = createNode(row, 0, ServiceProviderInvoice.class);
        BusinessDisplayNode shipmentNode = createNode(row, 5, Shipment.class);

        shipmentNode.setChildren(new BusinessDisplayNode[]{spiNode});
        return shipmentNode;
    }

    @Override
    public BusinessDisplayNode getShipmentServiceProviderCreditNoteParents(ServiceProviderCreditNote serviceProviderCreditNote) {
        String queryString
                = "SELECT spi.id, spi.reference, spi.reference, spi.state, spi.state, "
                + "s.id, s.number, s.reference||'('||s.number||')', s.state, ssi.shippingMode "
                + "FROM ServiceProviderCreditNote spi "
                + "LEFT JOIN spi.shipment s LEFT JOIN s.shippingInfo ssi "
                + "WHERE spi=:serviceProviderCreditNote";

        Query query = getSessionCustom().createQuery(queryString);
        query.setParameter("serviceProviderCreditNote", serviceProviderCreditNote);
        List list = query.list();
        // Only one row will be returned, with all our results in it
        Object row[] = (Object[]) list.get(0);

        // Hardcoding the types for now
        BusinessDisplayNode spiNode = createNode(row, 0, ServiceProviderInvoice.class);
        BusinessDisplayNode shipmentNode = createNode(row, 5, Shipment.class);

        shipmentNode.setChildren(new BusinessDisplayNode[]{spiNode});
        return shipmentNode;
    }

    @Override
    public BusinessDisplayNode getShipmentCommercialCreditNoteParents(CommercialCreditNote commercialCreditNote) {
        // Can't get the order type from the db easily.
        String queryString
                = "SELECT ccn.id, ccn.reference, ccn.reference, ccn.state, ccn.state, "
                + "s.id, s.number, s.reference||'('||s.number||')', s.state, ssi.shippingMode "
                + "FROM CommercialCreditNote ccn "
                + "LEFT JOIN ccn.shipment s LEFT JOIN s.shippingInfo ssi "
                + "WHERE ccn=:commercialCreditNote";

        Query query = getSessionCustom().createQuery(queryString);
        query.setParameter("commercialCreditNote", commercialCreditNote);
        List list = query.list();
        // Only one row will be returned, with all our results in it
        Object row[] = (Object[]) list.get(0);

        // Hardcoding the types for now
        BusinessDisplayNode spiNode = createNode(row, 0, CommercialCreditNote.class);
        BusinessDisplayNode shipmentNode = createNode(row, 5, Shipment.class);

        shipmentNode.setChildren(new BusinessDisplayNode[]{spiNode});
        return shipmentNode;
    }

    @Override
    public BusinessDisplayNode getFullStructure(Shipment shipment) {
        return getShipmentChildren(shipment);
    }

    @Override
    public BusinessDisplayNode getFullStructure(Consignment consignment) {
        // TODO. Make queries
        if (consignment.getShipment() != null) {
            return getShipmentChildren(consignment.getShipment());
        } else {
            return getConsignmentChildren(consignment);
        }
    }

    @Override
    public BusinessDisplayNode getFullStructure(Order order) {
        if (order.getConsignment() != null) {
            return getFullStructure(order.getConsignment());
        } else {
            return getOrderChildren(order);
        }
    }

    @Override
    public BusinessDisplayNode getFullStructure(LineItem lineItem) {
        if (lineItem.getOrder() != null) {
            return getFullStructure(lineItem.getOrder());
        } else {
            return getLineItemChildren(lineItem);
        }
    }

    @Override
    public BusinessDisplayNode getConsignmentCommercialInvoiceParents(CommercialInvoice commercialInvoice) {
        String queryString
                = "SELECT ci.id, ci.reference, ci.reference, ci.state, ci.state, "
                + "c.id, c.number, c.reference, c.state, c.state, "
                + "s.id, s.number, s.reference||'('||s.number||')', s.state, ssi.shippingMode "
                + "FROM CommercialInvoice ci "
                + "LEFT JOIN ci.consignment c "
                + "LEFT JOIN c.shipment s LEFT JOIN s.shippingInfo ssi "
                + "WHERE ci=:commercialInvoice";

        Query query = getSessionCustom().createQuery(queryString);
        query.setParameter("commercialInvoice", commercialInvoice);
        List list = query.list();
        // Only one row will be returned, with all our results in it
        Object row[] = (Object[]) list.get(0);

        // Hardcoding the types for now
        BusinessDisplayNode ciNode = createNode(row, 0, CommercialInvoice.class);
        BusinessDisplayNode consignmentNode = createNode(row, 5, Consignment.class);
        BusinessDisplayNode shipmentNode = createNode(row, 10, Shipment.class);

        shipmentNode.setChildren(new BusinessDisplayNode[]{consignmentNode});
        consignmentNode.setChildren(new BusinessDisplayNode[]{ciNode});
        return shipmentNode;
    }

    @Override
    public BusinessDisplayNode getConsignmentServiceProviderInvoiceParents(ServiceProviderInvoice serviceProviderInvoice) {
        String queryString
                = "SELECT ci.id, ci.reference, ci.reference, ci.state, ci.state, "
                + "c.id, c.number, c.reference, c.state, c.state, "
                + "s.id, s.number, s.reference||'('||s.number||')', s.state, ssi.shippingMode "
                + "FROM ServiceProviderInvoice spi "
                + "LEFT JOIN spi.consignment c "
                + "LEFT JOIN c.shipment s LEFT JOIN s.shippingInfo ssi "
                + "WHERE spi=:serviceProviderInvoice";

        Query query = getSessionCustom().createQuery(queryString);
        query.setParameter("serviceProviderInvoice", serviceProviderInvoice);
        List list = query.list();
        // Only one row will be returned, with all our results in it
        Object row[] = (Object[]) list.get(0);

        // Hardcoding the types for now
        BusinessDisplayNode ciNode = createNode(row, 0, ServiceProviderInvoice.class);
        BusinessDisplayNode shipmentNode = createNode(row, 5, Shipment.class);

        shipmentNode.setChildren(new BusinessDisplayNode[]{ciNode});
        return shipmentNode;
    }

}