SummaryActualReportRepositoryImpl.java

package com.tradecloud.repository.costingdocument.impl;

import com.tradecloud.domain.event.ShipmentEventType;
import com.tradecloud.domain.model.ordermanagement.PurchaseOrder;
import com.tradecloud.domain.model.organisationalunit.OrganisationalUnit;
import com.tradecloud.domain.model.shipment.ShipmentState;
import com.tradecloud.domain.shipment.Shipment;
import com.tradecloud.dto.invoice.SummaryActualReportSearch;
import com.tradecloud.repository.base.impl.RepositoryBaseImpl;
import com.tradecloud.repository.costingdocument.SummaryActualReportRepository;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: ds
 * Date: 2014/05/12
 * Time: 8:55 AM
 * To change this template use File | Settings | File Templates.
 */
@Repository(value = "summaryActualReportRepository")
public class SummaryActualReportRepositoryImpl extends RepositoryBaseImpl<Shipment,
        SummaryActualReportSearch> implements SummaryActualReportRepository {

    private static Logger log = Logger.getLogger(SummaryActualReportRepositoryImpl.class);

    @Override
    public List<PurchaseOrder> summaryActualSearch(SummaryActualReportSearch search) {
        Criteria criteria = getSessionCustom().createCriteria(PurchaseOrder.class);

        Criteria criteria1 = criteria.createCriteria("consignment", "c").createCriteria("shipment", "sh");
        criteria1.createAlias("shippingInfo","si");
        criteria1.createCriteria("events", "ev")
            .add(Restrictions.ge("ev.createDateTime",search.getShipmentSignedOffDateFrom()))
            .add(Restrictions.le("ev.createDateTime", search.getShipmentSignedOffDateTo()));
        criteria.add(Restrictions.eq("ev.eventType", ShipmentEventType.SIGNED_OFF));
        criteria.add(Restrictions.in("sh.state", new ShipmentState [] {ShipmentState.SIGNED_OFF, ShipmentState.COMPLETE}));
        log.debug("setting the ShipmentSignedOffDate criteria");

        Collection<OrganisationalUnit> organisationalUnits = null;
        if (search.getOrganisationalUnits2() != null) {
            organisationalUnits =search.getOrganisationalUnits2();
        }

        if(search.isFilteredByUserOrg() && (CollectionUtils.isEmpty(organisationalUnits))){
            organisationalUnits = getUserOrganisationalUnits();
        }

        if (CollectionUtils.isNotEmpty(organisationalUnits)) {
            criteria.add(Restrictions.in("organisationalUnit", organisationalUnits));
        }

        if (search.getOrganisationalUnit() != null) {
            criteria.add(Restrictions.eq("organisationalUnit", search.getOrganisationalUnit()))
                .add(Restrictions.isNotNull("c.reference"));

            if (search.getBuyer() != null && search.getSupplier() != null) {
                criteria.add(Restrictions.and(Restrictions.and(Restrictions.eq("buyer", search.getBuyer()),
                    Restrictions.eq("supplier", search.getSupplier())),
                    Restrictions.isNotNull("c.reference")));
            } else if (search.getBuyer() != null) {
                criteria.add(Restrictions.and(Restrictions.eq("buyer", search.getBuyer()),
                    Restrictions.isNotNull("c.reference")));
            } else if (search.getSupplier() != null) {
                criteria.add(Restrictions.and(Restrictions.eq("supplier", search.getSupplier()),
                    Restrictions.isNotNull("c.reference")));
            } else {
                log.debug("Buyer is null");
                log.debug("Supplier is null");
            }

        } else if (search.getBuyer() != null && search.getSupplier() != null) {
            criteria.add(Restrictions.and(Restrictions.eq("buyer", search.getBuyer()),
                Restrictions.eq("supplier", search.getSupplier()))).
                add(Restrictions.isNotNull("c.reference"));

        } else if (search.getSupplier() != null) {
            criteria.add(Restrictions.eq("supplier", search.getSupplier())).
                add(Restrictions.isNotNull("c.reference"));
        } else if (search.getBuyer() != null) {
            criteria.add(Restrictions.eq("buyer", search.getBuyer())).
                add(Restrictions.isNotNull("c.reference"));
        } else if (search.getOrderReference() != null) {
            //criteria.add(Restrictions.eq("orderReference", search.getOrderReference()));
            criteria.add(Restrictions.ilike("orderReference", search.getOrderReference(), MatchMode.ANYWHERE));
        }
        if (search.getShippingMode() != null) {
            criteria.add(Restrictions.eq("si.shippingMode", search.getShippingMode()));
        }
        if(search.getFreightForwarder()!=null){
            criteria.add(Restrictions.eq("si.freightForwarder", search.getFreightForwarder()));
        }

        criteria.addOrder(Order.asc("ev.createDateTime"));
        criteria.setProjection(Projections.property("id"));
       //first get list of order ids. this  work around  is to avoid "target lists can have at most 1664 entries" error.
        List list = criteria.list();
        //now get PO
        if (!list.isEmpty()) {
            Criteria criteria2 = getSessionCustom().createCriteria(PurchaseOrder.class);
            criteria2.add(Restrictions.in("id", list));

            return criteria2.list();
        } else {
            return Collections.EMPTY_LIST;
        }
    }

    @Override
    public long countByCriteria(SummaryActualReportSearch search) {
        return summaryActualSearch(search).size();
    }

}