AcceptedInvalidDocumentRepositoryImpl.java

package com.tradecloud.repository.impl;

import com.tradecloud.domain.document.CommercialCreditNote;
import com.tradecloud.domain.document.ServiceProviderCreditNote;
import com.tradecloud.domain.document.invoice.AcceptedInvalidDocument;
import com.tradecloud.domain.document.invoice.CommercialInvoice;
import com.tradecloud.domain.document.invoice.ServiceProviderInvoice;
import com.tradecloud.domain.dto.base.SearchBase;
import com.tradecloud.domain.model.organisationalunit.OrganisationalUnit;
import com.tradecloud.dto.invoice.AcceptedInvalidDocumentSearch;
import com.tradecloud.repository.AcceptedInvalidDocumentRepository;
import com.tradecloud.repository.base.impl.CriteriaValue;
import com.tradecloud.repository.base.impl.RepositoryBaseImpl;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.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.util.*;
import java.util.stream.Collectors;

@Repository(value = "acceptedInvalidDocumentRepository")
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public class AcceptedInvalidDocumentRepositoryImpl extends RepositoryBaseImpl<AcceptedInvalidDocument, AcceptedInvalidDocumentSearch>
        implements AcceptedInvalidDocumentRepository {

    @Override
    public List<AcceptedInvalidDocument> search(AcceptedInvalidDocumentSearch search) {

        String tableName = search.getTableName().toLowerCase();
        String[] orderBy = new String[]{tableName + ".created ASC"};
        Query query =
                getQuery(search, false, "", acceptedInvalidDocumentValues(search),
                        createJoinStringForAcceptedInvalidDocument(search), orderBy, "select distinct " + tableName + " ");
        return getQueryList(query, search.getSearchMetaParams());

    }

    private String createJoinStringForAcceptedInvalidDocument(AcceptedInvalidDocumentSearch search) {
        String tableName = ((SearchBase) search).getTableName().toLowerCase();

        StringBuilder sb = new StringBuilder(" join  " + tableName + ".costsInvoice as inv ");
        sb.append(" join  " + tableName + ".costsInvoice.shipment as ship ");
        if(search.isFilteredByUserOrg()){
            sb.append(" join  ship.consignments as con ");
            sb.append(" join  con.orders as porder ");
        }

        sb.append(" where " + tableName + " is not null ");
        if (search.getDocumentType() != null) {
            String invoice = getInvoiceTypeName(search);
            sb.append(" and type(inv)="+invoice);
        }else if(search.getOrganisationalUnit() != null||search.getSupplier()!=null){
            sb.append(" and type(inv)=CommercialInvoice");
        }
        Set<OrganisationalUnit> organisationalUnits= Collections.EMPTY_SET;
        if(search.isFilteredByUserOrg()){
            organisationalUnits = getUserOrganisationalUnits();
            List<Long> collect = organisationalUnits.stream().map(organisationalUnit -> organisationalUnit.getId()).collect(Collectors.toList());
            sb.append( String.format(" and porder.organisationalUnit.id in (%s) ",StringUtils.join(collect,",")));
        }else

        if (search.getOrganisationalUnit() != null) {
            sb.append(" and (select count(*) from  CommercialInvoice c where c.id=inv.id and " +
                    "c.organisationalUnit.id='" + search.getOrganisationalUnit().getId() + "'" + ") >0 ");
        }



        if(search.getSupplier()!=null){
            sb.append(" and (select count(*) from  CommercialInvoice c where c.id=inv.id and " +
                    "c.supplier.id='" + search.getSupplier().getId() + "'" + ") >0 ");
        }

        return sb.toString();
    }

    private String getInvoiceTypeName(AcceptedInvalidDocumentSearch search) {
        String invoice = "CommercialInvoice";
        switch (search.getDocumentType()) {
            case COMMERCIAL_INVOICE:
                invoice = CommercialInvoice.class.getName();
                break;
            case SERVICE_PROVIDER_INVOICE:
                invoice = ServiceProviderInvoice.class.getName();
                break;
            case SERVICE_PROVIDER_CREDIT_NOTE:
                invoice = ServiceProviderCreditNote.class.getName();
                break;
            case COMMERCIAL_CREDIT_NOTE:
                invoice = CommercialCreditNote.class.getName();
                break;
        }
        return invoice;
    }

    private Collection<CriteriaValue> acceptedInvalidDocumentValues(AcceptedInvalidDocumentSearch search) {
        Collection<CriteriaValue> fields = new LinkedHashSet<>();
        String tableName = ((SearchBase) search).getTableName().toLowerCase();

        if (StringUtils.isNotEmpty(search.getDocumentReference())) {
            fields.add(CriteriaValue.like("inv.reference", "%" + search.getDocumentReference() + "%"));
        }

        if (StringUtils.isNotEmpty(search.getShipmentReference())) {
            fields.add(CriteriaValue.like("ship.reference", "%" + search.getShipmentReference() + "%"));
        }

        if (StringUtils.isNotEmpty(search.getShipmentNumber())) {
            fields.add(CriteriaValue.like("ship.number", "%" + search.getShipmentNumber() + "%"));
        }

        if (search.getDocumentState() != null) {
            fields.add(CriteriaValue.eq("inv.state", search.getDocumentState()));
        }

        if (search.getAccepted().getFrom() != null) {
            fields.add(CriteriaValue.gt(tableName + ".created", search.getAccepted().getFrom()));
        }
        if (search.getAccepted().getTo() != null) {
            fields.add(CriteriaValue.lt(tableName + ".created", search.getAccepted().getTo()));
        }

        if (search.getUser() != null) {
            fields.add(CriteriaValue.eq(tableName + ".user", search.getUser()));
        }

//        if(search.getSupplier()!=null){
//            fields.add(CriteriaValue.eq("inv.supplier", search.getSupplier()));
//        }

        return fields;
    }

    @Override
    public long count(AcceptedInvalidDocumentSearch search) {
        String tableName = search.getTableName().toLowerCase();
        Query query =
                getQuery(search, true, "", acceptedInvalidDocumentValues(search),
                        createJoinStringForAcceptedInvalidDocument(search), null, "select count (distinct " + tableName + ") ");
        return getQueryCount(query);
    }
}