InternalProvisionsRateRepositoryImpl.java

package com.tradecloud.repository.rate.impl;

import com.tradecloud.domain.infrastructure.persistence.CriteriaBuilder;
import com.tradecloud.domain.party.Employee;
import com.tradecloud.domain.rate.InternalProvisionsRate;
import com.tradecloud.domain.rate.InternalProvisionsRateCosting;
import com.tradecloud.dto.rate.InternalProvisionsRateSearch;
import com.tradecloud.repository.rate.InternalProvisionsRateRepository;
import com.tradecloud.repository.utils.CriteriaBuilder2;
import org.hibernate.Query;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.transform.AliasToBeanResultTransformer;
import org.springframework.stereotype.Repository;

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

@Repository(value = "internalProvisionsRateRepository")
public class InternalProvisionsRateRepositoryImpl extends BaseRateRepository<InternalProvisionsRate, InternalProvisionsRateSearch> implements
        InternalProvisionsRateRepository {

    private DetachedCriteria buildBaseCriteria(InternalProvisionsRateSearch search) {
        DetachedCriteria criteria = DetachedCriteria.forClass(InternalProvisionsRate.class);

        if (search.isSpecificSearch()) {
            CriteriaBuilder.addExactMatch(criteria, "organisationalUnit", search.getOrganisationalUnit());
            CriteriaBuilder.addExactMatch(criteria, "buyer", search.getBuyer());
            CriteriaBuilder.addExactMatch(criteria, "supplier", search.getSupplier());
            CriteriaBuilder.addExactMatch(criteria, "paymentMethod", search.getPaymentMethod());
            CriteriaBuilder.addExactMatch(criteria, "paymentTerm", search.getPaymentTerm());
            CriteriaBuilder.addExactMatch(criteria, "containerType", search.getContainerType());
            CriteriaBuilder.addExactMatch(criteria, "placeOfDischarge", search.getPlaceOfDischarge());
            CriteriaBuilder.addExactMatch(criteria, "finalDestination", search.getFinalDestination());
            CriteriaBuilder.addExactMatch(criteria, "itemCategory", search.getItemCategory());
            CriteriaBuilder.addExactMatch(criteria, "company", search.getCompany());
            CriteriaBuilder.addExactMatch(criteria, "costLine", search.getCostLine());
            CriteriaBuilder.addExactMatch(criteria, "costingType", search.getCostingType());
            CriteriaBuilder.addExactMatch(criteria, "currency", search.getCurrency());
            CriteriaBuilder.addExactMatch(criteria, "rateUnit", search.getRateUnit());
        } else {
            CriteriaBuilder.addEqRestriction(criteria, "organisationalUnit", search.getOrganisationalUnit());
            CriteriaBuilder.addEqRestriction(criteria, "buyer", search.getBuyer());
            CriteriaBuilder.addEqRestriction(criteria, "supplier", search.getSupplier());
            CriteriaBuilder.addEqRestriction(criteria, "paymentMethod", search.getPaymentMethod());
            CriteriaBuilder.addEqRestriction(criteria, "paymentTerm", search.getPaymentTerm());
            CriteriaBuilder.addEqRestriction(criteria, "containerType", search.getContainerType());
            CriteriaBuilder.addEqRestriction(criteria, "placeOfDischarge", search.getPlaceOfDischarge());
            CriteriaBuilder.addEqRestriction(criteria, "finalDestination", search.getFinalDestination());
            CriteriaBuilder.addEqRestriction(criteria, "itemCategory", search.getItemCategory());
            CriteriaBuilder.addEqRestriction(criteria, "company", search.getCompany());
            CriteriaBuilder.addEqRestriction(criteria, "costLine", search.getCostLine());
            CriteriaBuilder.addEqRestriction(criteria, "costingType", search.getCostingType());
            CriteriaBuilder.addEqRestriction(criteria, "currency", search.getCurrency());
            CriteriaBuilder.addEqRestriction(criteria, "rateUnit", search.getRateUnit());
        }
        CriteriaBuilder.addEqRestriction(criteria, "costCompareOnly", search.isCostCompareOnly());
        return criteria;
    }

    @Override
    public List<InternalProvisionsRate> search(InternalProvisionsRateSearch search) {

        DetachedCriteria criteria = buildBaseCriteria(search);

        CriteriaBuilder.addDateGreaterOrEqualRangeCriteria(criteria, "effectiveDate", search.getEffectiveDateLower());
        CriteriaBuilder.addDateLessOrEqualRangeCriteria(criteria, "effectiveDate", search.getEffectiveDateUpper());
        // criteria.addOrder(Order.desc("updated"));
        criteria.addOrder(Order.desc("costLine")).addOrder(Order.desc("effectiveDate")).addOrder(Order.asc("id"));
        // criteria.addOrder(Order.desc("costLine")).addOrder(Order.desc("effectiveDate"));

        //@SuppressWarnings("unchecked") List<InternalProvisionsRate> results = criteria.getExecutableCriteria(getSessionCustom()).list();
        //return results;
        return getExecutableCriteriaList(criteria, search.getSearchMetaParams());
    }

    @Override
    public long count(InternalProvisionsRateSearch search) {

        DetachedCriteria criteria = buildBaseCriteria(search);

        CriteriaBuilder.addDateGreaterOrEqualRangeCriteria(criteria, "effectiveDate", search.getEffectiveDateLower());
        CriteriaBuilder.addDateLessOrEqualRangeCriteria(criteria, "effectiveDate", search.getEffectiveDateUpper());

        return getExecutableCriteriaCount(criteria);
    }

    @Override
    public List<InternalProvisionsRate> searchByClosestEffectiveDate(InternalProvisionsRateSearch search) {

        DetachedCriteria criteria = DetachedCriteria.forClass(InternalProvisionsRate.class);

        CriteriaBuilder.addEqRestriction(criteria, "organisationalUnit", search.getOrganisationalUnit());
        CriteriaBuilder.addEqRestriction(criteria, "supplier", search.getSupplier());
        CriteriaBuilder.addEqRestriction(criteria, "containerType", search.getContainerType());
        CriteriaBuilder.addEqRestriction(criteria, "placeOfDischarge", search.getPlaceOfDischarge());
        CriteriaBuilder.addEqRestriction(criteria, "finalDestination", search.getFinalDestination());
        CriteriaBuilder.addEqRestriction(criteria, "itemCategory", search.getItemCategory());
        CriteriaBuilder.addEqRestriction(criteria, "company", search.getCompany());
        CriteriaBuilder.addEqRestriction(criteria, "costLine", search.getCostLine());
        CriteriaBuilder.addEqRestriction(criteria, "costingType", search.getCostingType());
        CriteriaBuilder.addEqRestriction(criteria, "currency", search.getCurrency());
        CriteriaBuilder.addEqRestriction(criteria, "costCompareOnly", search.isCostCompareOnly());
        CriteriaBuilder.addDateLessOrEqualRangeCriteria(criteria, "effectiveDate", search.getEffectiveDateLower());
        criteria.addOrder(org.hibernate.criterion.Order.desc("effectiveDate"));

        //@SuppressWarnings("unchecked") 
        //List<InternalProvisionsRate> results = criteria.getExecutableCriteria(getSessionFlushMode()).list();
        List<InternalProvisionsRate> results = getExecutableCriteriaList(criteria, null);

        if (results.size() > 1) {
            List<InternalProvisionsRate> list = new ArrayList<InternalProvisionsRate>();
            list.add(results.get(0));
            return list;
        }
        return results;
    }

    @Override
    public void save(InternalProvisionsRate internalProvisionsRate) {
        super.save(internalProvisionsRate);
    }

    @Override
    public InternalProvisionsRate searchByOrderOfPriority(InternalProvisionsRateSearch search) {

        DetachedCriteria criteria = DetachedCriteria.forClass(InternalProvisionsRate.class);
        return searchByOrderOfPriority(search, criteria);
    }

    @Override
    public InternalProvisionsRate searchByOrderOfPriorityCosting(InternalProvisionsRateSearch search) {
        DetachedCriteria criteria = DetachedCriteria.forClass(InternalProvisionsRate.class);
        setCostingProjections(criteria);
        return searchByOrderOfPriority(search, criteria);
    }

    //DO not return heavy objects here, if you must then return id or list of ids.
    private void setCostingProjections(DetachedCriteria criteria) {

        ProjectionList projections = costingProjectionsCommon();
        projections.add(Projections.property("brand"), "brand");

        criteria.setProjection(projections);

        criteria.setResultTransformer(new AliasToBeanResultTransformer(InternalProvisionsRateCosting.class));
    }

    private InternalProvisionsRate searchByOrderOfPriority(InternalProvisionsRateSearch search, DetachedCriteria criteria) {
        if (search.getCostLine() == null) {
            throw new RuntimeException("Rate search must contain CostLine");
        }
        CriteriaBuilder.addEqRestriction(criteria, "costLine", search.getCostLine());
        CriteriaBuilder.addEqRestriction(criteria, "costingType", search.getCostingType());
        CriteriaBuilder.addEqRestriction(criteria, "costCompareOnly", search.isCostCompareOnly());
        CriteriaBuilder.addDateLessOrEqualRangeCriteria(criteria, "effectiveDate", search.getEffectiveDateLower());
        CriteriaBuilder.addDisjunctionIn(criteria, "organisationalUnit", findApplicableOrgs(search));
        CriteriaBuilder.addDisjunction(criteria, "buyer", search.getBuyer());
        CriteriaBuilder.addDisjunction(criteria, "supplier", search.getSupplier());
        CriteriaBuilder.addDisjunction(criteria, "paymentMethod", search.getPaymentMethod());
        CriteriaBuilder.addDisjunction(criteria, "paymentTerm", search.getPaymentTerm());
        CriteriaBuilder.addDisjunction(criteria, "containerType", search.getContainerType());
        CriteriaBuilder.addDisjunction(criteria, "placeOfDischarge", search.getPlaceOfDischarge());
        CriteriaBuilder.addDisjunction(criteria, "finalDestination", search.getFinalDestination());
        CriteriaBuilder.addDisjunction(criteria, "itemCategory", search.getItemCategory());
        CriteriaBuilder.addDisjunction(criteria, "company", search.getCompany());
        CriteriaBuilder.addDisjunction(criteria, "brand", search.getBrand());
        setRateUnitAndCurrency(search, criteria);
        DetachedCriteria tierCriteria = findOrgTierCriteria(search, criteria);

        CriteriaBuilder2.addRateOrderOfPriority(criteria, search, null, tierCriteria);

        List<InternalProvisionsRate> results = criteria.getExecutableCriteria(getSessionCustom()).list();
        return results.size() == 0 ? null : results.get(0);
    }

    public List<InternalProvisionsRate> searchByEmployee(Employee employee) {
        String hql = "from InternalProvisionsRate s where s.buyer = :employee";
        Query query = getSessionCustom().createQuery(hql);
        query.setParameter("employee", employee);
        return query.list();
    }
}