ServiceProviderPaymentReportRepositoryImpl.java

package com.tradecloud.repository.costingdocument.impl;

import com.tradecloud.domain.document.Document;
import com.tradecloud.domain.document.DocumentState;
import com.tradecloud.domain.document.PaymentState;
import com.tradecloud.domain.document.ServiceProviderCreditNote;
import com.tradecloud.domain.document.invoice.ServiceProviderInvoice;
import com.tradecloud.domain.model.organisationalunit.OrganisationalUnit;
import com.tradecloud.dto.invoice.ServiceProviderPaymentSearch;
import com.tradecloud.repository.base.impl.RepositoryBaseImpl;
import com.tradecloud.repository.costingdocument.ServiceProviderPaymentReportRepository;
import org.hibernate.Criteria;
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.Collections;
import java.util.List;
import java.util.Set;

@Repository(value = "serviceProviderPaymentReportRepository")
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public class ServiceProviderPaymentReportRepositoryImpl extends RepositoryBaseImpl<Document, ServiceProviderPaymentSearch> implements
        ServiceProviderPaymentReportRepository {

    private static final long serialVersionUID = 1L;

    @Override
    public List<Document> serviceProviderPaymentSearch(ServiceProviderPaymentSearch search) {
        DetachedCriteria detachedCriteria = createserviceProviderPaymentReportCriteria(search);
        detachedCriteria.setProjection(Projections.distinct(Projections.property("id")));
        DetachedCriteria criteria2 = DetachedCriteria.forClass(ServiceProviderInvoice.class);
        criteria2.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
        criteria2.add(Property.forName("id").in(detachedCriteria));
        return criteria2.getExecutableCriteria(getSessionCustom()).list();
    }

    @Override
    public long serviceProviderPaymentReportCount(ServiceProviderPaymentSearch search) {
        DetachedCriteria detachedCriteria = createserviceProviderPaymentReportCriteria(search);
        detachedCriteria.setProjection(Projections.distinct(Projections.property("id")));
        Criteria criteria = detachedCriteria.getExecutableCriteria(getSessionCustom());
        List results = criteria.list();
        if (!results.isEmpty()) {
            DetachedCriteria criteria2 = DetachedCriteria.forClass(ServiceProviderCreditNote.class);
            criteria2.createAlias("serviceProviderInvoice", "spi");
            criteria2.add(Restrictions.in("spi.id", results));
            criteria2.add(Restrictions.ne("state", DocumentState.DELETED));
            criteria2.setProjection(Projections.rowCount());
            long count = (Long) criteria2.getExecutableCriteria(getSessionCustom()).list().get(0);
            return results.size() + count;
        }
        return 0;
    }

    private DetachedCriteria createserviceProviderPaymentReportCriteria(ServiceProviderPaymentSearch search) {
        DetachedCriteria criteria = DetachedCriteria.forClass(ServiceProviderInvoice.class);
        criteria.createAlias("shipment", "s");
        if (null != search.getShipmentReference() && search.getShipmentReference().length() > 0) {
            criteria.add(Restrictions.ilike("s.reference", search.getShipmentReference(), MatchMode.ANYWHERE));
        }
        if (null != search.getServiceProvider()) {
            criteria.add(Restrictions.eq("serviceProvider", search.getServiceProvider()));
        } else if (search.getServiceProviders() != null && search.getServiceProviders().length > 0) {
            criteria.add(Restrictions.in("serviceProvider", search.getServiceProviders()));
        }

        if (null != search.getInvoiceReference() && search.getInvoiceReference().length() > 0) {
            criteria.add(Restrictions.ilike("reference", search.getInvoiceReference(), MatchMode.ANYWHERE));
        }
        if (null != search.getInvoiceCurrency()) {
            criteria.add(Restrictions.eq("currency", search.getInvoiceCurrency()));
        }
        if (null != search.getPaymentCurrency()) {
            criteria.createAlias("plannedSettlements", "ps");
            criteria.add(Restrictions.eq("ps.currency", search.getPaymentCurrency()));
        }
        if (search.getPaymentState() != null) {
            if (PaymentState.SETTLED.name().equals(search.getPaymentState())) {
                criteria.add(Restrictions.isNotNull("actualSettlementDate"));
            } else if (PaymentState.UNSETTLED.name().equals(search.getPaymentState())) {
                criteria.add(Restrictions.isNull("actualSettlementDate"));
            }
        }
        if (search.getSettlementDateFrom() != null && search.getSettlementDateTo() != null) {
            criteria.add(Restrictions.between("estimatedSettlementDate", search.getSettlementDateFrom(), search.getSettlementDateTo()));
        } else if (search.getSettlementDateFrom() != null && search.getSettlementDateTo() == null) {
            criteria.add(Restrictions.gt("estimatedSettlementDate", search.getSettlementDateFrom()));
        } else if (search.getSettlementDateFrom() == null && search.getSettlementDateTo() != null) {
            criteria.add(Restrictions.lt("estimatedSettlementDate", search.getSettlementDateTo()));
        }
        if (search.getDocumentDateFrom() != null && search.getDocumentDateTo() != null) {
            criteria.add(Restrictions.between("dateCreated", search.getDocumentDateFrom(), search.getDocumentDateTo()));
        } else if (search.getDocumentDateFrom() != null && search.getDocumentDateTo() == null) {
            criteria.add(Restrictions.gt("dateCreated", search.getDocumentDateFrom()));
        } else if (search.getDocumentDateFrom() == null && search.getDocumentDateTo() != null) {
            criteria.add(Restrictions.lt("dateCreated", search.getDocumentDateTo()));
        }

        Set<OrganisationalUnit> organisationalUnits = Collections.EMPTY_SET;
        if (search.getOrganisationalUnit() != null) {
            organisationalUnits = Collections.singleton(search.getOrganisationalUnit());
        } else if (search.isFilteredByUserOrg()) {
            organisationalUnits = getUserOrganisationalUnits();
        }

        if (!organisationalUnits.isEmpty()) {
            criteria.createAlias("s.consignments", "con");
            criteria.createAlias("con.orders", "porder");
            criteria.add(Restrictions.in("porder.organisationalUnit", organisationalUnits));
        }

        criteria.add(Restrictions.ne("state", DocumentState.DELETED));
        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
        return criteria;
    }

}