ServiceProviderInvoiceRepositoryImpl.java

package com.tradecloud.repository.impl;

import com.tradecloud.domain.document.Document;
import com.tradecloud.domain.document.invoice.ActualOrder;
import com.tradecloud.domain.document.invoice.ServiceProviderInvoice;
import com.tradecloud.domain.party.ServiceProvider;
import com.tradecloud.domain.shipment.Shipment;
import com.tradecloud.dto.invoice.SupplyPaymentSearch;
import com.tradecloud.repository.ServiceProviderInvoiceRepository;
import org.hibernate.SQLQuery;
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.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * Default implementation of the {@literal ServiceProviderInvoiceRepository}
 * interface.
 */
@Repository(value = "serviceProviderInvoiceRepository")
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public class ServiceProviderInvoiceRepositoryImpl extends CostsInvoiceRepositoryImpl<ServiceProviderInvoice> implements
        ServiceProviderInvoiceRepository {

    private static final long serialVersionUID = 1L;

    @Override
    public List<ServiceProviderInvoice> findAllByReference(String reference) {
        return findAllByReference("serviceProviderInvoice.byReference", reference);
    }

    @Override
    public List<ServiceProviderInvoice> findByReferenceAndServiceProvider(String reference, ServiceProvider serviceProvider) {
        List<ServiceProviderInvoice> list =
                (List<ServiceProviderInvoice>) findByNamedQueryAndNamedParam("serviceProviderInvoice.byReferenceAndServiceProvider",
                        new String[]{"reference", "serviceProvider"}, new Object[]{reference, serviceProvider});
        return list;
    }

    @Override
    public List<ActualOrder> findActualOrdersByInvoice(ServiceProviderInvoice invoice) {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * Specifically for reporting.
     *
     * @param search
     * @return
     */
    @Override
    public long supplyPaymentReportCount(SupplyPaymentSearch search) {
        return 0;
    }

    /**
     * Specifically for reporting.
     *
     * @param search
     * @return
     */
    @Override
    public List<Document> supplyPaymentReportSearch(SupplyPaymentSearch search) {
        return null;
    }

    @Override
    public int countOnShipmentNotDeleted(long shipmentId) {
        return ((Long) getCurrentSession()
                .createQuery("select count(*) from ServiceProviderInvoice where shipment.id = :shipmentId and state != 'DELETED'")
                .setParameter("shipmentId", shipmentId).iterate().next()).intValue();
    }

    @Override
    public List numbersInUse(Long shipmentId, String type, String... numbers) {
        Function<String, String> addQuotes = s -> "'" + s + "'";
        String result = Arrays.asList(numbers).stream()
                .map(addQuotes)
                .collect(Collectors.joining(", "));

        StringBuilder sb = new StringBuilder("select " + type + ".number from " + type);
        sb.append(" left join costsinvoice on costsinvoice.id = " + type + ".id where ");
        sb.append(type + ".number in (" + result + ") ");
        sb.append(" and shipment_id <> :shipmentId ");
        sb.append(" and costsinvoice.state <> 'DELETED'");

        SQLQuery sqlQuery = (SQLQuery) getCurrentSession().createSQLQuery(sb.toString());
        sqlQuery.setParameter("shipmentId", shipmentId);

        List<String> list = sqlQuery.list();
        return list;
    }

    @Override
    public List findInvoiceRefMrnLrn(List<Long> shipmenIds) {
        StringBuilder sb = new StringBuilder("select shipment_id, string_agg(distinct(reference),',') as spiref," +
                "string_agg(distinct(l.number),',') as lrn,string_agg(distinct(m.number),',') as mrn  from costsinvoice b")
                .append(" join serviceproviderinvoice spi on (spi.id=b.id) ")
                .append(" left join lrnnumbers l on (l.id=b.id) left  join mrnnumbers m on (m.id=b.id) ")
                .append(" where b.state in ('SETTLED','SIGNED_OFF') ")
                .append(" and b.shipment_id in (:shipmenIds)")
                .append(" group by shipment_id ");
        return getSessionCustom().createNativeQuery(sb.toString()).setParameterList("shipmenIds", shipmenIds).list();
    }

    @Override
    public List<ServiceProviderInvoice> getActiveServiceProviderInvoices(Shipment shipment) {
        Query<ServiceProviderInvoice> query = getSession()
                .createQuery("from ServiceProviderInvoice where shipment = :shipment and state != 'DELETED'", ServiceProviderInvoice.class);
        query.setParameter("shipment", shipment);
        return query.list();
    }

}