CompanyRepositoryImpl.java

package com.tradecloud.repository.company;

import com.tradecloud.domain.infrastructure.persistence.CriteriaBuilder;
import com.tradecloud.domain.party.Bank;
import com.tradecloud.domain.party.ServiceProvider;
import com.tradecloud.domain.party.ServiceProviderType;
import com.tradecloud.domain.party.base.Company;
import com.tradecloud.domain.search.SearchParams;
import com.tradecloud.domain.supplier.AbstractSupplier;
import com.tradecloud.domain.supplier.Supplier;
import com.tradecloud.dto.company.CompanySearch;
import com.tradecloud.dto.freetext.FreeTextSearch;
import com.tradecloud.repository.base.impl.RepositoryBaseImpl;
import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.hibernate.proxy.HibernateProxyHelper;
import org.hibernate.query.Query;
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.io.Serializable;
import java.util.List;

/**
 * @author pvzyl 11 Sep 2012
 */
@Repository(value = "companyRepository")
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public class CompanyRepositoryImpl extends RepositoryBaseImpl<Company, CompanySearch> implements CompanyRepository {

    private static final Logger log = Logger.getLogger(CompanyRepositoryImpl.class);
    private static final long serialVersionUID = 1L;

    private final static String NAME = "name";
    private final static String EXTERNAL_REFERENCE = "externalReference";

    private final static String LETTER_OF_CREDIT_PROVIDER = "letterOfCreditProvider";
    private final static String LETTER_OF_CREDIT_INTEGRATED = "lcDetails.templateIntegrated";

    @Override
    public Company findByName(String name) {
        return findByName(name, true);
    }

    @Override
    public Company findByName(String name, boolean caseSensitive) {
        Criteria searchCriteria = getSessionCustom().createCriteria(Company.class);
        if (caseSensitive) {
            searchCriteria.add(Restrictions.eq(NAME, name));
        } else {
            searchCriteria.add(Restrictions.ilike(NAME, name));
        }
        return (Company) searchCriteria.uniqueResult();
    }

    @Override
    public List<Supplier> findAllSupplierType(AbstractSupplier.Type type, SearchParams orderByNameActive) {
        Class<Supplier> clazz = Supplier.class;
        DetachedCriteria criteria = DetachedCriteria.forClass(clazz);
        criteria.add(Restrictions.eq("type", type));
        return findAll(orderByNameActive, criteria);
    }

    @Override
    public <X extends Company> X findByName(String name, Class<X> c) {
        Criteria searchCriteria = getSessionCustom().createCriteria(c);
        searchCriteria.add(Restrictions.eq(NAME, name != null ? name.trim() : name));
        return (X) searchCriteria.uniqueResult();
    }

    @Override
    public <X extends Company> List<X> findAllByName(String name, Class<X> c) {
        Criteria searchCriteria = getSessionCustom().createCriteria(c);
        searchCriteria.add(Restrictions.eq(NAME, name != null ? name.trim() : name));
        return (List<X>) searchCriteria.list();
    }

    @Override
    public <X extends Company> X findByReference(String reference, Class<X> c) {
        Criteria searchCriteria = getSessionCustom().createCriteria(c);
        searchCriteria.add(Restrictions.eq("externalReference", reference));
        return (X) searchCriteria.uniqueResult();
    }

    @Override
    public <X extends Company> List<X> search(CompanySearch search, Class<X> c) {
        log.debug("Searching for companies. " + search + ". Class '" + c + "'.");
        DetachedCriteria criteria = DetachedCriteria.forClass(c);

        CriteriaBuilder.addEqRestriction(criteria, "name", search.getName());
        CriteriaBuilder.addEqRestriction(criteria, "externalReference", search.getExternalReference());

        return criteria.getExecutableCriteria(getSessionCustom()).list();
    }

    private Criterion createFreeTextCriterion(FreeTextSearch search) {
        return Restrictions.or(
                Restrictions.eq(NAME, search.getText()),
                Restrictions.eq(EXTERNAL_REFERENCE, search.getText()));
    }

    @Override
    public <X extends Company> List<X> searchFreeText(FreeTextSearch search, Class<X> c) {
        DetachedCriteria criteria = DetachedCriteria.forClass(c);
        criteria.add(createFreeTextCriterion(search));
        return (List<X>) getExecutableCriteriaList(criteria, search.getSearchMetaParams());
    }

    @Override
    public <X extends Company> long countFreeText(FreeTextSearch search, Class<X> c) {
        DetachedCriteria criteria = DetachedCriteria.forClass(c);
        criteria.add(createFreeTextCriterion(search));
        return getExecutableCriteriaCount(criteria);
    }

    @Override
    public List<Bank> findAllLetterOfCreditProviderBanks(SearchParams searchParams) {
        DetachedCriteria criteria = DetachedCriteria.forClass(Bank.class);
        CriteriaBuilder.applySearchParams(criteria, searchParams);
        criteria.add(Restrictions.eq(LETTER_OF_CREDIT_PROVIDER, true));
        return criteria.getExecutableCriteria(getSessionCustom()).list();
    }

    @Override
    public List<Bank> findAllLetterOfCreditProviderBanks(SearchParams searchParams, boolean isLetterOfCreditIntegrated) {
        DetachedCriteria criteria = DetachedCriteria.forClass(Bank.class);
        CriteriaBuilder.applySearchParams(criteria, searchParams);
        criteria.add(Restrictions.eq(LETTER_OF_CREDIT_PROVIDER, true));
        criteria.add(Restrictions.eq(LETTER_OF_CREDIT_INTEGRATED, isLetterOfCreditIntegrated));
        return criteria.getExecutableCriteria(getSessionCustom()).list();
    }

    @Override
    public void save(Company company) {
        validatePBExternalReferences(company.getClass(), company.getExternalReferences(), null);
        super.save2(company);
    }

    @Override
    public Serializable save2(Company company) {
        validatePBExternalReferences(company.getClass(), company.getExternalReferences(), null);
        return super.save2(company);
    }

    @Override
    public void update(Company company) {
        validatePBExternalReferences(HibernateProxyHelper.getClassWithoutInitializingProxy(company), company.getExternalReferences(),
                company.getId());
        super.update(company);
    }

    @Override
    public List<ServiceProvider> findServiceProviders(ServiceProviderType type) {
        String hql = """
                 select distinct sp
                 from ServiceProvider sp
                 join fetch sp.serviceProviderTypes spt
                """;

        if (type != null) {
            hql = hql + " where spt = :type";
        }

        Query<ServiceProvider> query = getCurrentSession()
                .createQuery(hql, ServiceProvider.class);

        if (type != null) {
            query.setParameter("type", type);
        }

        return query.getResultList();
    }
}