LetterOfCreditGeneralRepositoryImpl.java
package com.tradecloud.repository.impl;
import com.tradecloud.authentication.MultiTenantUtil;
import com.tradecloud.domain.base.utils.DateRange;
import com.tradecloud.domain.base.utils.DateUtils;
import com.tradecloud.domain.infrastructure.persistence.CriteriaBuilder;
import com.tradecloud.domain.letterofcredit.LetterOfCredit;
import com.tradecloud.domain.letterofcredit.LetterOfCreditState;
import com.tradecloud.domain.letterofcredit.LetterOfCreditTemplate;
import com.tradecloud.domain.model.ordermanagement.PurchaseOrder;
import com.tradecloud.domain.model.organisationalunit.OrganisationalUnit;
import com.tradecloud.domain.supplier.OrganisationalUnitSupplier;
import com.tradecloud.dto.letterofcredit.LetterOfCreditSearch;
import com.tradecloud.dto.letterofcredit.LetterOfCreditTemplateSearch;
import com.tradecloud.repository.LetterOfCreditGeneralRepository;
import com.tradecloud.repository.SearchMetaParams;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.*;
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.*;
/**
* @author jon
*/
@Repository(value = "letterOfCreditGeneralRepository")
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public class LetterOfCreditGeneralRepositoryImpl extends GeneralRepositoryImpl implements LetterOfCreditGeneralRepository {
private final static String NUMBER = "number";
private final static String BANK_REFERENCE = "bankReference";
private final static String APPLICATION_REFERENCE = "applicationReference";
private final static String STATE = "state";
private final static String KEY = "key";
private final static String NAME = "name";
private final static String DESCRIPTION = "description";
private final static String ISSUING_BANK = "issuingBank";
private final static String BANK = "owningEntity";
private final static String SUPPLIER = "beneficiary";
private final static String OUT_OF_SYNC_STATE = "outOfSyncState";
private final static String CREATED_DATE = "createdDate";
private final static String LATEST_SHIPMENT_DATE = "shippingInfo.latestShipmentDate";
private final static String SHIPMENT_DATE = "s.latestShipmentDate";
private final static String ORG_UNIT = "applicant";
private final static String ORGANISATIONAL_UNIT_UNIT = "po.organisationalUnit";
private final static String ORGANISATIONAL_UNIT_PARENT = "po.organisationalUnit.parent";
private final static String SUPPLIER_ORG_ORG = "po.supplier";
//private final static String ORGANISATIONAL_UNIT = "po.organisationalUnit";
//private final static String SUPPLIER_ORG = "po.supplier";
//private final static String ORGANISATIONAL_UNIT = "beneficiary";
private final static String SUPPLIER_ORG = "beneficiary.organisationalUnit";
private void addSearchRestrictions(DetachedCriteria criteria, LetterOfCreditSearch search) {
// TODO. Add others.
criteria.createAlias("shippingInfo", "s");
criteria.createAlias("purchaseOrders", "po");
criteria.createAlias("po.organisationalUnit", "ou");
CriteriaBuilder.addiLikeAnyRestriction(criteria, NUMBER, search.getNumber());
CriteriaBuilder.addiLikeAnyRestriction(criteria, BANK_REFERENCE, search.getBankReference());
CriteriaBuilder.addiLikeAnyRestriction(criteria, APPLICATION_REFERENCE, search.getApplicationReference());
CriteriaBuilder.addEqRestriction(criteria, ISSUING_BANK, search.getBank());
CriteriaBuilder.addEqRestriction(criteria, OUT_OF_SYNC_STATE, search.getOutOfSyncState());
CriteriaBuilder.addEqActiveStateRestriction(criteria, STATE, search.getState(), LetterOfCreditState.DELETED);
CriteriaBuilder.addDateRangeCriteria(criteria, CREATED_DATE, search.getCreatedDate());
//CriteriaBuilder.addEqRestriction(criteria, SUPPLIER_ORG, search.getSupplier());
CriteriaBuilder.addEqRestriction(criteria, SUPPLIER, search.getSupplier());
//if (search.getOrganisationalUnit() != null && search.getOrganisationalUnit().getTier().getName() != null) {
if (search.getOrganisationalUnit() != null) {
//Ignore org unit specified if the org unit is the holding company.
//In which case one would search under all org units.
if (!search.getOrganisationalUnit().getTier().getName().equals("HoldingCompany")) {
if (search.getOrganisationalUnit().getTier().getName().equals("BUSINESS_UNIT")) {
CriteriaBuilder.addEqRestriction(criteria, "ou.parent", search.getOrganisationalUnit());
} else {
CriteriaBuilder.addEqRestriction(criteria, ORGANISATIONAL_UNIT_UNIT, search.getOrganisationalUnit());
}
}
}
CriteriaBuilder.addDateRangeCriteria(criteria, SHIPMENT_DATE, search.getLatestShipmentDate());
}
/*@Override
public List<LetterOfCredit> search(LetterOfCreditSearch search) {
DetachedCriteria criteria = DetachedCriteria.forClass(LetterOfCredit.class);
criteria.addOrder(Order.desc("created"));
addSearchRestrictions(criteria, search);
return getExecutableCriteriaList(criteria, LetterOfCredit.class, search.getSearchMetaParams());
}*/
private Criteria createLetterOfCreditCriteria(LetterOfCreditSearch search) {
DetachedCriteria criteria = DetachedCriteria.forClass(LetterOfCredit.class);
criteria.createAlias("shippingInfo", "s");
criteria.createAlias("purchaseOrders", "po");
criteria.createAlias("po.organisationalUnit", "ou");
Set<OrganisationalUnit> organisationalUnits = Collections.EMPTY_SET;
if (search.isFilteredByUserOrg()) {
organisationalUnits = getUserOrganisationalUnits();
criteria.add(Restrictions.in("po.organisationalUnit", organisationalUnits));
} else if (search.getOrganisationalUnit() != null) {
//Ignore org unit specified if the org unit is the holding company.
//In which case one would search under all org units.
if (!search.getOrganisationalUnit().getTier().getName().equals("HoldingCompany")) {
if (search.getOrganisationalUnit().getTier().getName().equals("BUSINESS_UNIT")) {
criteria.add(Restrictions.eq("ou.parent", search.getOrganisationalUnit()));
} else {
criteria.add(Restrictions.eq(ORGANISATIONAL_UNIT_UNIT, search.getOrganisationalUnit()));
}
}
}
if (search.getNumber() != null) {
criteria.add(Restrictions.ilike(NUMBER, search.getNumber(), MatchMode.ANYWHERE));
}
if (search.getBankReference() != null) {
criteria.add(Restrictions.ilike(BANK_REFERENCE, search.getBankReference(), MatchMode.ANYWHERE));
}
if (search.getApplicationReference() != null) {
criteria.add(Restrictions.ilike(APPLICATION_REFERENCE, search.getApplicationReference(), MatchMode.ANYWHERE));
}
if (search.getBank() != null) {
criteria.add(Restrictions.eq(ISSUING_BANK, search.getBank()));
}
if (search.getOutOfSyncState() != null) {
criteria.add(Restrictions.eq(OUT_OF_SYNC_STATE, search.getOutOfSyncState()));
}
if (search.getState() != null) {
criteria.add(Restrictions.eq(STATE, search.getState()));
} else {
criteria.add(Restrictions.not(Restrictions.eq(STATE, LetterOfCreditState.DELETED)));
}
if (search.getSupplier() != null) {
criteria.add(Restrictions.eq(SUPPLIER, search.getSupplier()));
}
DateRange createdDateRange = search.getCreatedDate();
if (createdDateRange != null) {
if (createdDateRange.getFrom() != null) {
criteria.add(Restrictions.ge(CREATED_DATE, DateUtils.getStartOfDay(createdDateRange.getFrom())));
}
if (createdDateRange.getTo() != null) {
criteria.add(Restrictions.le(CREATED_DATE, DateUtils.getEndOfDay(createdDateRange.getTo())));
}
}
DateRange lsdDateRange = search.getLatestShipmentDate();
if (lsdDateRange != null) {
if (lsdDateRange.getFrom() != null) {
criteria.add(Restrictions.ge(SHIPMENT_DATE, DateUtils.getStartOfDay(lsdDateRange.getFrom())));
}
if (lsdDateRange.getTo() != null) {
criteria.add(Restrictions.le(SHIPMENT_DATE, DateUtils.getEndOfDay(lsdDateRange.getTo())));
}
}
//search returns multiple results of the same entities due to the purchase order table alias which cannot be removed.
criteria.setProjection(Projections.distinct(Projections.property("id")));
Criteria c = getSessionCustom().createCriteria(LetterOfCredit.class);
c.add(Subqueries.propertyIn("id", criteria));
return c;
}
protected Set<OrganisationalUnit> getUserOrganisationalUnits() {
return Optional.ofNullable(MultiTenantUtil.getActiveUser().getOrganisationalUnits()).orElseThrow(() ->
new IllegalStateException("filter by org is true, but organisational unit is not set"));
}
@Override
public List<LetterOfCredit> search(LetterOfCreditSearch search) {
Criteria criteria = createLetterOfCreditCriteria(search);
SearchMetaParams searchMetaParams = search.getSearchMetaParams();
if (searchMetaParams != null) {
criteria.setMaxResults(searchMetaParams.getRowCount());
criteria.setFirstResult(searchMetaParams.getRowIndex());
criteria.addOrder(Order.desc(CREATED_DATE));
} else {
criteria.addOrder(Order.desc(CREATED_DATE));
}
return criteria.list();
}
@Override
public List<LetterOfCredit> searchByNumber(String lcNumber) {
DetachedCriteria criteria = DetachedCriteria.forClass(LetterOfCredit.class);
getSessionCustom().createCriteria(LetterOfCredit.class).list();
criteria.addOrder(Order.desc("created"));
CriteriaBuilder.addEqRestriction(criteria, NUMBER, lcNumber);
return getExecutableCriteriaList(criteria, LetterOfCredit.class);
}
/*@Override
public long count(LetterOfCreditSearch search) {
DetachedCriteria criteria = DetachedCriteria.forClass(LetterOfCredit.class);
addSearchRestrictions(criteria, search);
return getExecutableCriteriaCount(criteria);
}*/
@Override
public long count(LetterOfCreditSearch search) {
Criteria criteria = createLetterOfCreditCriteria(search);
criteria.setProjection(Projections.rowCount());
long count = ((Long) criteria.uniqueResult()).longValue();
return count;
}
@Override
public List<LetterOfCreditTemplate> searchTemplates(LetterOfCreditTemplateSearch search) {
DetachedCriteria criteria = DetachedCriteria.forClass(LetterOfCreditTemplate.class);
criteria.addOrder(Order.desc("created"));
if (search.getSupplier() != null) {
criteria.createAlias("selectedSuppliers", "supplier");
}
// TODO. Add others.
CriteriaBuilder.addiLikeAnyRestriction(criteria, KEY, search.getKey());
CriteriaBuilder.addiLikeAnyRestriction(criteria, NAME, search.getName());
CriteriaBuilder.addiLikeAnyRestriction(criteria, DESCRIPTION, search.getDescription());
CriteriaBuilder.addEqRestriction(criteria, STATE, search.getState());
CriteriaBuilder.addEqRestriction(criteria, BANK, search.getOwningEntity());
if (search.getSupplier() != null) {
CriteriaBuilder.addEqRestriction(criteria, "supplier.id", search.getSupplier().getId());
}
return getExecutableCriteriaList(criteria, LetterOfCreditTemplate.class);
}
@Override
public List<LetterOfCreditTemplate> searchTemplatesExact(LetterOfCreditTemplateSearch search) {
DetachedCriteria criteria = DetachedCriteria.forClass(LetterOfCreditTemplate.class);
criteria.addOrder(Order.desc("created"));
if (search.getSupplier() != null) {
criteria.createAlias("selectedSuppliers", "supplier");
}
// TODO. Add others.
CriteriaBuilder.addEqRestriction(criteria, KEY, search.getKey());
CriteriaBuilder.addEqRestriction(criteria, NAME, search.getName());
CriteriaBuilder.addEqRestriction(criteria, DESCRIPTION, search.getDescription());
CriteriaBuilder.addEqRestriction(criteria, STATE, search.getState());
CriteriaBuilder.addEqRestriction(criteria, BANK, search.getOwningEntity());
if (search.getSupplier() != null) {
CriteriaBuilder.addEqRestriction(criteria, "supplier.id", search.getSupplier().getId());
}
return getExecutableCriteriaList(criteria, LetterOfCreditTemplate.class);
}
@Override
public List<OrganisationalUnitSupplier> findLCreditTemplateOrganisationalUnitSuppliers(long lcTemplateId) {
String queryString =
"select * from OrganisationalUnitSupplier org join lctemplate_orgsupplier lc on "
+ "org.id = lc.orgsupplier_id where lc.lctemplate_id = :lcTemplateId";
return (List<OrganisationalUnitSupplier>) getCurrentSession().createSQLQuery(queryString).addEntity(OrganisationalUnitSupplier.class)
.setParameter("lcTemplateId", lcTemplateId).list();
}
@Override
public List<String> getItemDescriptions(Collection<PurchaseOrder> purchaseOrders) {
String queryString = "SELECT description FROM LineItem li WHERE li.order IN (:orders) ORDER BY addedToOrderDate ASC";
Query query = getSessionCustom().createQuery(queryString);
query.setMaxResults(5);
query.setParameterList("orders", purchaseOrders);
return query.list();
}
@Override
public LetterOfCredit findLetterOfCreditByOrder(Long orderId) {
Criteria criteria = getSessionCustom().createCriteria(LetterOfCredit.class);
criteria.createAlias("purchaseOrders", "po");
criteria.add(Restrictions.eq("po.id", orderId));
return (LetterOfCredit) criteria.uniqueResult();
}
@Override
public boolean isIntegrated(PurchaseOrder purchaseOrder) {
String queryString = "SELECT lc.letterOfCreditTemplate.integrated FROM LetterOfCredit lc JOIN lc.purchaseOrders po WHERE po = :purchaseOrder";
Query query = getSessionCustom().createQuery(queryString);
query.setParameter("purchaseOrder", purchaseOrder);
Object result = query.uniqueResult();
return result != null ? (Boolean)result : false;
}
}