OrganisationalUnitSupplierRepositoryImpl.java
package com.tradecloud.repository.company;
import com.tradecloud.authentication.MultiTenantUtil;
import com.tradecloud.common.externalreference.ExternalReference;
import com.tradecloud.domain.base.utils.ObjectUtil;
import com.tradecloud.domain.infrastructure.persistence.CriteriaBuilder;
import com.tradecloud.domain.model.organisationalunit.OrganisationalUnit;
import com.tradecloud.domain.supplier.*;
import com.tradecloud.dto.company.OrganisationalUnitSupplierSearch;
import com.tradecloud.dto.freetext.FreeTextSearch;
import com.tradecloud.repository.base.impl.RepositoryBaseImpl;
import org.apache.commons.collections.CollectionUtils;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.*;
import org.hibernate.transform.BasicTransformerAdapter;
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.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@Repository(value = "organisationalUnitSupplierRepository")
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public class OrganisationalUnitSupplierRepositoryImpl extends RepositoryBaseImpl<OrganisationalUnitSupplier, OrganisationalUnitSupplierSearch>
implements OrganisationalUnitSupplierRepository {
private static final long serialVersionUID = 1L;
private final static String NAME = "s.name";
private final static String EXTERNAL_REFERENCE = "s.externalReference";
@Override
public OrganisationalUnitSupplier findByName(String name) {
List<OrganisationalUnitSupplier> all = super.findAll();
for (OrganisationalUnitSupplier organisationalUnitSupplier : all) {
if (organisationalUnitSupplier.getSupplier().getName().equals(name)) {
return organisationalUnitSupplier;
}
}
return null;
}
@Override
public List<OrganisationalUnitSupplier> search(OrganisationalUnitSupplierSearch search) {
DetachedCriteria criteria = DetachedCriteria.forClass(getPersistentClass());
addSearchRestrictions(criteria, search);
return getExecutableCriteriaList(criteria, search.getSearchMetaParams());
}
@Override
public long count(OrganisationalUnitSupplierSearch search) {
DetachedCriteria criteria = DetachedCriteria.forClass(getPersistentClass());
addSearchRestrictions(criteria, search);
return getExecutableCriteriaCount(criteria);
}
private void addSearchRestrictions(DetachedCriteria criteria, OrganisationalUnitSupplierSearch search) {
DetachedCriteria supplier = criteria.createCriteria("supplier");
if (search.getState() != null) {
supplier.add(Restrictions.eq("state", search.getState()));
}
if (search.getComplete() != null) {
// Active will be true by default in the search.
if (CompleteType.COMPLETE.equals(search.getComplete())) {
supplier.add(Restrictions.eq("complete", true));
} else {
supplier.add(Restrictions.eq("complete", false));
}
}
if (search.getSupplierState() != null) {
supplier.add(Restrictions.eq("state", search.getSupplierState()));
}
if (search.getIntegrated() != null) {
// Integrated will be true by default in the search.
if (IntegratedType.INTEGRATED.equals(search.getIntegrated())) {
supplier.add(Restrictions.eq("integrated", true));
} else {
supplier.add(Restrictions.eq("integrated", false));
}
}
if (search.getTypes() != null && !search.getTypes().isEmpty()) {
supplier.add(Restrictions.in("type", search.getTypes()));
} else {
supplier.add(Restrictions.eq("type", AbstractSupplier.Type.FULL));
}
if (search.getName() != null) {
supplier.add(Restrictions.ilike("name", LIKE + search.getName() + LIKE));
}
if (search.getReference() != null) {
if (!search.isUnique()) {
supplier.add(Restrictions.ilike("externalReference", LIKE + search.getReference() + LIKE));
} else {
supplier.add(Expression.eq("externalReference", search.getReference()).ignoreCase());
}
}
if (search.getCreatedFrom() != null && search.getCreatedTo() != null) {
supplier.add(Restrictions.between("created", search.getCreatedFrom(), search.getCreatedTo()));
}
if (search.getCountry() != null) {
DetachedCriteria eventCrit = supplier.createCriteria("physicalAddress").add(Restrictions.eq("country", search.getCountry()));
eventCrit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
}
if (search.getCurrency() != null) {
supplier.add(Restrictions.eq("currency", search.getCurrency()));
}
if (search.getSupplier() != null) {
criteria.add(Restrictions.eq("supplier", search.getSupplier()));
}
if (CollectionUtils.isNotEmpty(search.getOrganisationalUnitList())) {
criteria.add(Restrictions.in("organisationalUnit", search.getOrganisationalUnitList()));
} else if (search.getOrganisationalUnit() != null) {
if (search.isLiteSearch()) {
Junction conditionGroup = Restrictions.disjunction();
for (OrganisationalUnit organisationalUnit : search.getOrganisationalUnit().getChildren()) {
conditionGroup.add(Restrictions.eq("organisationalUnit", organisationalUnit));
}
conditionGroup.add(Restrictions.eq("organisationalUnit", search.getOrganisationalUnit()));
if (search.getOrganisationalUnit().getParent() != null) {
conditionGroup.add(Restrictions.eq("organisationalUnit", search.getOrganisationalUnit().getParent()));
}
criteria.add(conditionGroup);
} else {
criteria.add(Restrictions.eq("organisationalUnit", search.getOrganisationalUnit()));
}
}
}
@Override
public OrganisationalUnitSupplier findByIdOrgUnitAndSupplier(OrganisationalUnit orgUnit, Supplier supplier) {
List<OrganisationalUnitSupplier> organisationalUnitSuppliers = (List<OrganisationalUnitSupplier>)
findByNamedQueryAndNamedParam("findByIdOrgUnitAndSupplier",
new String[]{"organisationalUnit", "supplier"}, new Object[]{orgUnit, supplier});
return ObjectUtil.first(organisationalUnitSuppliers);
}
@Override
public OrganisationalUnitSupplier findByIdOrgUnitAndSupplierAllowNull(OrganisationalUnit organisationalUnit, Supplier supplier) {
List<OrganisationalUnitSupplier> organisationalUnitSuppliers = (List<OrganisationalUnitSupplier>)
findByNamedQueryAndNamedParam("findByIdOrgUnitAndSupplierWhereNullAllowed",
new String[]{"organisationalUnit", "supplier"}, new Object[]{organisationalUnit, supplier});
return ObjectUtil.first(organisationalUnitSuppliers);
}
private Criterion createFreeTextCriterion(FreeTextSearch search) {
return Restrictions.or(Restrictions.like(NAME, search.getText()), Restrictions.like(EXTERNAL_REFERENCE, search.getText()));
}
@Override
public List<OrganisationalUnitSupplier> findBySupplier(Supplier supplier) {
return findBySupplier(supplier, false);
}
@Override
public List<OrganisationalUnitSupplier> findBySupplier(Supplier supplier, boolean includeInactive) {
return findBySupplier(supplier, includeInactive, false);
}
@Override
public List<OrganisationalUnitSupplier> findBySupplier(Supplier supplier, boolean includeInactive, boolean includeSuspended) {
DetachedCriteria criteriaOrgUnitSupplier = DetachedCriteria.forClass(OrganisationalUnitSupplier.class);
DetachedCriteria criteriaOrgUnit = criteriaOrgUnitSupplier.createCriteria("organisationalUnit");
DetachedCriteria criteriaSupplier = criteriaOrgUnitSupplier.createCriteria("supplier");
CriteriaBuilder.addExactMatch(criteriaOrgUnitSupplier, "supplier", supplier);
addSupplierStateRestriction(criteriaSupplier, includeInactive, includeSuspended);
List<OrganisationalUnitSupplier> results = criteriaOrgUnitSupplier.getExecutableCriteria(getSession()).list();
return results;
}
@Override
public List<OrganisationalUnitSupplier> searchFreeText(FreeTextSearch search) {
DetachedCriteria criteria = DetachedCriteria.forClass(OrganisationalUnitSupplier.class);
criteria.createAlias("supplier", "s");
criteria.add(createFreeTextCriterion(search));
return getExecutableCriteriaList(criteria, search.getSearchMetaParams());
}
@Override
public long countFreeText(FreeTextSearch search) {
DetachedCriteria criteria = DetachedCriteria.forClass(OrganisationalUnitSupplier.class);
criteria.add(createFreeTextCriterion(search));
return getExecutableCriteriaCount(criteria);
}
@Override
public List<OrganisationalUnitSupplier> getAllUsedOrgUnitSuppliersByCommercialInvoice() {
String queryString = "from OrganisationalUnitSupplier ous where ous.id in (select ci.supplier.id from CommercialInvoice ci)";
Query query = getCurrentSession().createQuery(queryString);
return (List<OrganisationalUnitSupplier>) query.list();
}
@Override
public List<OrganisationalUnitSupplier> getAllUsedOrgUnitSuppliersByCreditNote() {
String queryString = "from OrganisationalUnitSupplier ous where ous.id in (select ccn.supplier.id from CommercialCreditNote ccn)";
Query query = getCurrentSession().createQuery(queryString);
return (List<OrganisationalUnitSupplier>) query.list();
}
@Override
public List<OrganisationalUnitSupplier> findByOrganisationalUnit(OrganisationalUnit organisationalUnit) {
return findByOrganisationalUnit(organisationalUnit, false);
}
@Override
public List<OrganisationalUnitSupplier> findByOrganisationalUnit(OrganisationalUnit organisationalUnit, boolean includeInactive) {
return findByOrganisationalUnit(organisationalUnit, includeInactive, false);
}
@Override
public List<OrganisationalUnitSupplier> findByOrganisationalUnit(OrganisationalUnit organisationalUnit,
boolean includeInactive,
boolean includeSuspended) {
DetachedCriteria criteriaOrgUnitSupplier = DetachedCriteria.forClass(OrganisationalUnitSupplier.class);
DetachedCriteria criteriaOrgUnit = criteriaOrgUnitSupplier.createCriteria("organisationalUnit");
DetachedCriteria criteriaSupplier = criteriaOrgUnitSupplier.createCriteria("supplier");
CriteriaBuilder.addEqRestriction(criteriaOrgUnit, "code", organisationalUnit.getCode());
addSupplierStateRestriction(criteriaSupplier, includeInactive, includeSuspended);
List<OrganisationalUnitSupplier> results = criteriaOrgUnitSupplier.getExecutableCriteria(getSession()).list();
return results;
}
@Override
public List<OrganisationalUnitSupplier> findAll() {
return findAll(false);
}
@Override
public List<OrganisationalUnitSupplier> findAll(boolean includeInactive) {
return findAll(includeInactive, false);
}
@Override
public List<OrganisationalUnitSupplier> findAll(boolean includeInactive, boolean includeSuspended) {
DetachedCriteria criteriaOrgUnitSupplier = DetachedCriteria.forClass(OrganisationalUnitSupplier.class);
DetachedCriteria criteriaSupplier = criteriaOrgUnitSupplier.createCriteria("supplier");
addSupplierStateRestriction(criteriaSupplier, includeInactive, includeSuspended);
List<OrganisationalUnitSupplier> results = criteriaOrgUnitSupplier.getExecutableCriteria(getSession()).list();
return results;
}
@Override
public OrganisationalUnitSupplier findByOrgUnitCodeAndSupplierName(String orgUnitCode, String supplierName, String externalRef) {
return findByOrgUnitCodeAndSupplierName(orgUnitCode, supplierName, externalRef, false, false);
}
@Override
public OrganisationalUnitSupplier findByOrgUnitCodeAndSupplierName(String orgUnitCode, String supplierName,
String externalRef, boolean includeInactive, boolean includeSuspended) {
return findByOrgUnitCodeAndSupplierNameOrReference(orgUnitCode, supplierName, externalRef, includeInactive, includeSuspended);
}
@Override
public OrganisationalUnitSupplier findByOrgUnitCodeAndSupplierReference(String orgUnitCode, String supplierReference, boolean includeInactive) {
return findByOrgUnitCodeAndSupplierNameOrReference(orgUnitCode, null, supplierReference, includeInactive, false);
}
@Override
public OrganisationalUnitSupplier findByOrgUnitCodeAndSupplierNameOrReference(String orgUnitCode, String supplierName, String supplierReference,
boolean includeInactive, boolean includeSuspended) {
DetachedCriteria criteriaOrgUnitSupplier = DetachedCriteria.forClass(OrganisationalUnitSupplier.class);
DetachedCriteria criteriaOrgUnit = criteriaOrgUnitSupplier.createCriteria("organisationalUnit");
DetachedCriteria criteriaSupplier = criteriaOrgUnitSupplier.createCriteria("supplier");
if (MultiTenantUtil.getActiveUser().getIntegratedSystem() != null) {
DetachedCriteria eventCrit = criteriaOrgUnit.createCriteria("externalReferences")
.add(Restrictions.eq("integratedSystem", MultiTenantUtil.getActiveUser().getIntegratedSystem()))
.add(Restrictions.eq("referenceValue", orgUnitCode));
} else {
CriteriaBuilder.addEqRestriction(criteriaOrgUnit, "code", orgUnitCode);
CriteriaBuilder.addDisjunction(criteriaOrgUnit, "code", orgUnitCode);
}
if (supplierName != null) {
CriteriaBuilder.addEqRestriction(criteriaSupplier, "name", supplierName);
}
if (supplierReference != null) {
CriteriaBuilder.addEqRestriction(criteriaSupplier, "externalReference", supplierReference);
}
addSupplierStateRestriction(criteriaSupplier, includeInactive, includeSuspended);
List<OrganisationalUnitSupplier> results = criteriaOrgUnitSupplier.getExecutableCriteria(getSession()).list();
if (results != null && results.size() > 1)
throw new RuntimeException("only one org with code and supplier name should exist.");
return (results != null && !results.isEmpty()) ? results.get(0) : null;
}
private void addSupplierStateRestriction(DetachedCriteria criteriaSupplier, boolean includeInactive, boolean includeSuspended) {
List<SupplierState> supplierStates = new ArrayList<SupplierState>();
supplierStates.addAll(Arrays.asList(SupplierState.values()));
if (!includeInactive) {
supplierStates.remove(SupplierState.INACTIVE);
supplierStates.remove(SupplierState.LIQUIDATED);
supplierStates.remove(SupplierState.SUSPENDED);
CriteriaBuilder.addEqRestriction(criteriaSupplier, "complete", true);
}
if (!includeSuspended) {
if (supplierStates.contains(SupplierState.SUSPENDED)) {
supplierStates.remove(SupplierState.SUSPENDED);
}
} else {
if (!supplierStates.contains(SupplierState.SUSPENDED)) {
supplierStates.add(SupplierState.SUSPENDED);
}
}
if (!supplierStates.isEmpty()) {
CriteriaBuilder.addDisjunctionIn(criteriaSupplier, "state", supplierStates);
}
}
@Override
public List<OrganisationalUnitSupplier> findByOrgUnitCodeAndSupplierNameOrReferenceList(String orgUnitCode,
String supplierName, String supplierReference,
boolean includeInactive) {
DetachedCriteria criteriaOrgUnitSupplier = DetachedCriteria.forClass(OrganisationalUnitSupplier.class);
DetachedCriteria criteriaOrgUnit = criteriaOrgUnitSupplier.createCriteria("organisationalUnit");
DetachedCriteria criteriaSupplier = criteriaOrgUnitSupplier.createCriteria("supplier");
if (MultiTenantUtil.getActiveUser().getIntegratedSystem() != null) {
DetachedCriteria eventCrit = criteriaOrgUnit.createCriteria("externalReferences")
.add(Restrictions.eq("integratedSystem", MultiTenantUtil.getActiveUser().getIntegratedSystem()))
.add(Restrictions.eq("referenceValue", orgUnitCode));
} else {
CriteriaBuilder.addEqRestriction(criteriaOrgUnit, "code", orgUnitCode);
CriteriaBuilder.addDisjunction(criteriaOrgUnit, "code", orgUnitCode);
}
if (supplierName != null) {
CriteriaBuilder.addEqRestriction(criteriaSupplier, "name", supplierName);
}
if (supplierReference != null) {
CriteriaBuilder.addEqRestriction(criteriaSupplier, "externalReference", supplierReference);
}
if (!includeInactive) {
CriteriaBuilder.addEqRestriction(criteriaSupplier, "state", SupplierState.ACTIVE);
CriteriaBuilder.addEqRestriction(criteriaSupplier, "complete", true);
}
List<OrganisationalUnitSupplier> results = criteriaOrgUnitSupplier.getExecutableCriteria(getSession()).list();
return results;
}
// This should be the same as findBySupplier(,,), but returns just the names. Used on the UI and report
@Override
public List<String> findOrgUnitNamesBySupplier(Supplier supplier, boolean includeInactive, boolean includeSuspended) {
DetachedCriteria criteriaOrgUnitSupplier = DetachedCriteria.forClass(OrganisationalUnitSupplier.class);
//DetachedCriteria criteriaOrgUnit = criteriaOrgUnitSupplier.createCriteria("organisationalUnit");
DetachedCriteria criteriaSupplier = criteriaOrgUnitSupplier.createCriteria("supplier");
CriteriaBuilder.addEqRestriction(criteriaOrgUnitSupplier, "supplier", supplier);
addSupplierStateRestriction(criteriaSupplier, includeInactive, includeSuspended);
criteriaOrgUnitSupplier.createAlias("organisationalUnit", "ou", CriteriaSpecification.LEFT_JOIN);
// criteriaOrgUnitSupplier.add(Restrictions.sqlRestriction("ou"));
Projection projection = Projections.projectionList().
add(Projections.property("ou.name"), "1");
criteriaOrgUnitSupplier.setProjection(projection);
criteriaOrgUnitSupplier.setResultTransformer(new BasicTransformerAdapter() {
@Override
public Object transformTuple(Object[] tuple, String[] aliases) {
return (String) tuple[0];
}
});
List<String> results = criteriaOrgUnitSupplier.getExecutableCriteria(getSession()).list();
return results;
}
@Override
protected OrganisationalUnitSupplier filterResult(ExternalReference externalReference, List<OrganisationalUnitSupplier> results) {
if (results.size() > 1) {
Set<OrganisationalUnitSupplier> suppliers = results.stream().filter(ous -> ous.getActive() == Boolean.TRUE).collect(Collectors.toSet());
if (suppliers.size() > 1) {
return failDueToDuplicateResults(externalReference, results);
} else {
return suppliers.iterator().next();
}
} else if (results.size() == 1) {
return results.iterator().next();
} else {
return null;
}
}
}