CostFormulaRepositoryImpl.java

package com.tradecloud.repository.impl;

import com.tradecloud.domain.costing.CostFormula;
import com.tradecloud.domain.costing.CostLineTemplate;
import com.tradecloud.domain.costing.CostingContextType;
import com.tradecloud.domain.model.organisationalunit.OrganisationalUnit;
import com.tradecloud.dto.costing.costsetup.CostFormulaSearch;
import com.tradecloud.repository.CostFormulaRepository;
import com.tradecloud.repository.base.impl.RepositoryBaseImpl;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.DistinctRootEntityResultTransformer;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigInteger;
import java.util.*;

/**
 * Repository implementation for the CostFormula table.
 */
@Repository(value = "costFormulaRepository")
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public class CostFormulaRepositoryImpl extends RepositoryBaseImpl<CostFormula, CostFormulaSearch> implements CostFormulaRepository {

    private static final long serialVersionUID = 1L;

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

    @Override
    public List<CostFormula> findAll() {
        return super.findAll();
    }

    @Override
    public List<CostFormula> findAllMatchingAnyOrganisationalUnit(CostFormulaSearch search) {
        if (log.isDebugEnabled()) {
            log.debug(search);
        }
        Criteria searchCriteria = getSessionCustom().createCriteria(CostFormula.class);
        Set<OrganisationalUnit> organisationalUnits = Collections.EMPTY_SET;
        if (search.isFilteredByUserOrg()) {
            organisationalUnits = getUserOrganisationalUnits();
        } else if (search.getOrganisationalUnit() != null) {
            organisationalUnits = Collections.singleton(search.getOrganisationalUnit());

        } else if (!CollectionUtils.isEmpty(search.getOrganisationalUnits())) {
            organisationalUnits = new HashSet<>(search.getOrganisationalUnits());
        }

        if(organisationalUnits != null) {
            List<Long> organisationalUnitIds = new ArrayList<Long>();
            for (OrganisationalUnit organisationalUnit : organisationalUnits) {
                if (organisationalUnit != null) {
                    organisationalUnitIds.add(organisationalUnit.getId());
                }
            }
            if (!organisationalUnitIds.isEmpty()) {
                searchCriteria.createAlias("organisationalUnits", "organisationalUnit");
                searchCriteria.add(Restrictions.in("organisationalUnit.id", organisationalUnitIds));
            }
        }
        searchCriteriaExcludeOrgUnit(search, searchCriteria);

        // descending order - newest first
        if (search.isExactSearch()) {
            searchCriteria.addOrder(Order.asc("containerType"));
            searchCriteria.addOrder(Order.asc("freightForwarder"));
            searchCriteria.addOrder(Order.desc("effectiveDate"));

        } else {
            searchCriteria.addOrder(Order.desc("effectiveDate"));
        }

        searchCriteria.setResultTransformer(DistinctRootEntityResultTransformer.INSTANCE);
        return searchCriteria.list();
    }

    private void searchCriteriaExcludeOrgUnit(CostFormulaSearch search, Criteria searchCriteria) {
        // search if field matches or is null
        commonSearch(search, searchCriteria);
        if (search.getEffectiveDate() != null) {
            searchCriteria.add(Restrictions.disjunction()
                    .add(Restrictions.lt("effectiveDate", search.getEffectiveDate()))
                    .add(Restrictions.eq("effectiveDate", search.getEffectiveDate()))
                    .add(Restrictions.isNull("effectiveDate")));
        }

        if (search.getCostingContextType() != null) {

            searchCriteria.add(Restrictions.eq("costingContextType", search.getCostingContextType()));
        }
    }

    @Override
    public CostFormula findCostFormula(CostFormulaSearch search) {
        List<CostFormula> results = findAllMatchingAnyOrganisationalUnit(search);
        if (results != null && !results.isEmpty()) {
            // return first, most recent result
            return results.get(0);
        }
        return null;
    }

    @Override
    public List<CostLineTemplate> findCostLineTemplate(CostFormulaSearch search) {
        Criteria searchCriteria2 = getSessionCustom().createCriteria(CostFormula.class);
        searchCriteriaExcludeOrgUnit(search, searchCriteria2);
        searchCriteria2.setProjection(Projections.distinct(Projections.property("costLineTemplate")));
        return searchCriteria2.list();
    }

    @Override
    public List<CostFormula> findAllWithNoOrganisationalUnit(CostFormulaSearch search) {
        Criteria searchCriteria2 = getSessionCustom().createCriteria(CostFormula.class);

        searchCriteria2.add(Restrictions.isEmpty("organisationalUnits"));
        // search using the params or nulls
        commonSearch(search, searchCriteria2);
        if (search.getEffectiveDate() != null) {
            searchCriteria2.add(Restrictions.disjunction()
                    .add(Restrictions.lt("effectiveDate", search.getEffectiveDate()))
                    .add(Restrictions.eq("effectiveDate", search.getEffectiveDate()))
                    .add(Restrictions.isNull("effectiveDate")));
        }
        // descending order - newest first
        if (search.isExactSearch()) {
            searchCriteria2.addOrder(Order.asc("containerType"));
            searchCriteria2.addOrder(Order.asc("freightForwarder"));
            searchCriteria2.addOrder(Order.desc("effectiveDate"));

        } else {
            searchCriteria2.addOrder(Order.desc("effectiveDate"));
        }

        searchCriteria2.setResultTransformer(DistinctRootEntityResultTransformer.INSTANCE);
        return searchCriteria2.list();
    }

    private void commonSearch(CostFormulaSearch search, Criteria searchCriteria2) {
        if (search.getShippingMode() != null) {
            searchCriteria2.add(Restrictions.disjunction()
                    .add(Restrictions.eq("shippingMode", search.getShippingMode()))
                    .add(Restrictions.isNull("shippingMode")));
        }
        if (search.getIncoterm() != null) {
            searchCriteria2.add(Restrictions.disjunction()
                    .add(Restrictions.eq("incoterm", search.getIncoterm()))
                    .add(Restrictions.isNull("incoterm")));
        }
        if (search.getCostLineTemplate() != null) {
            searchCriteria2.add(Restrictions.disjunction()
                    .add(Restrictions.eq("costLineTemplate", search.getCostLineTemplate()))
                    .add(Restrictions.isNull("costLineTemplate")));
        }

        if (search.getContainerType() != null && search.getFreightForwarder() != null) {
            search.setExactSearch(true);
        } else {
            search.setExactSearch(false);
        }
        if (search.getContainerType() != null) {
            searchCriteria2.add(Restrictions.disjunction()
                    .add(Restrictions.eq("containerType", search.getContainerType()))
                    .add(Restrictions.isNull("containerType")));
        }
        if (search.getFreightForwarder() != null) {
            searchCriteria2.add(Restrictions.disjunction()
                    .add(Restrictions.eq("freightForwarder", search.getFreightForwarder()))
                    .add(Restrictions.isNull("freightForwarder")));
        }
    }

    @Override
    public List<CostFormula> findSortedLite(CostingContextType costingContextType) {
        Criteria crit = getSessionCustom().createCriteria(CostFormula.class);
        crit.add(Restrictions.eq("costingContextType", costingContextType));
        crit.addOrder(Order.asc("containerType"));
        crit.addOrder(Order.asc("freightForwarder"));
        crit.addOrder(Order.desc("effectiveDate"));

        return crit.list();
    }

    @Override
    public long countCostLineOrgUnitBased(String costlineCode, CostingContextType costingContextType) {
        String countOrgBased = """
                 select count(*)  from costformula f join costformula_organisationalunits forg on(forg.costformula_id=f.id) 
                 where costlinetemplate_code=:costlineCode and costingcontexttype=:costingcontexttype
                """;
        return  ((BigInteger)getCurrentSession().createNativeQuery(countOrgBased).setParameter("costlineCode", costlineCode)
                .setParameter("costingcontexttype", costingContextType.name()).uniqueResult()).intValue();

    }
}