ClientConfigRepositoryImpl.java

package com.tradecloud.repository.configuration.impl;

import com.tradecloud.domain.autoemail.Report;
import com.tradecloud.domain.base.utils.ObjectUtil;
import com.tradecloud.domain.configuration.*;
import com.tradecloud.domain.configuration.clearing.za.ClearingInstructionConfig;
import com.tradecloud.domain.configuration.clearing.za.SARSImportConfig;
import com.tradecloud.domain.configuration.product.ProductClientConfig;
import com.tradecloud.domain.configuration.supplier.SupplierClientConfig;
import com.tradecloud.domain.container.ContainerState;
import com.tradecloud.domain.costing.CostGroup;
import com.tradecloud.domain.costing.CostingType;
import com.tradecloud.domain.document.DocumentState;
import com.tradecloud.domain.document.DocumentType;
import com.tradecloud.domain.export.ExportConfig;
import com.tradecloud.domain.item.LineItem;
import com.tradecloud.domain.item.LineItemState;
import com.tradecloud.domain.item.Product;
import com.tradecloud.domain.model.elcordermanagement.ElcConfig;
import com.tradecloud.domain.model.ordermanagement.ConsignmentState;
import com.tradecloud.domain.model.ordermanagement.Order;
import com.tradecloud.domain.model.ordermanagement.OrderState;
import com.tradecloud.domain.model.ordermanagement.ProductState;
import com.tradecloud.domain.model.organisationalunit.OrganisationalUnitTier;
import com.tradecloud.domain.model.shipment.ShipmentState;
import com.tradecloud.domain.sars.Status;
import com.tradecloud.domain.settlement.SettlementDateCalculation;
import com.tradecloud.repository.base.impl.RepositoryBaseImpl;
import com.tradecloud.repository.configuration.ClientConfigRepository;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.Projections;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.io.Serializable;
import java.util.List;

@Repository(value = "clientConfigRepository")
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public class ClientConfigRepositoryImpl extends RepositoryBaseImpl<ClientConfig, Object> implements ClientConfigRepository {

    private static final long serialVersionUID = 1L;

    private <T> T findFirstByNamedQuery(String namedQuery) {
        List<T> list = findGenericByNamedQuery(namedQuery);
        return list.isEmpty() ? null : list.get(0);
    }

    private <T> List<T> findGenericByNamedQuery(String namedQuery) {
        @SuppressWarnings("unchecked")
        List<T> list = (List<T>) getNamedQuery(namedQuery);
        return list;
    }

    @Override
    public List<SettlementDateCalculation> findAllSettlementDateCalculations() {
        @SuppressWarnings("unchecked")
        List<SettlementDateCalculation> sdcList = (List<SettlementDateCalculation>)
                findByNamedQuery("findAllOrderByTypeDescAndCostGroupAsc");
        return sdcList;
    }

    @Override
    public List<PublicHolidayRule> findAllPublicHolidayRules() {
        @SuppressWarnings("unchecked")
        List<PublicHolidayRule> list = (List<PublicHolidayRule>) getNamedQuery("publicholidayrule.findAll");
        return list;
    }

    @Override
    public AgentClientConfig findAgentClientConfig() {
        @SuppressWarnings("unchecked")
        List<AgentClientConfig> list = (List<AgentClientConfig>) getNamedQuery("clientConfig.findAgentClientConfig");
        return list.isEmpty() ? null : list.get(0);
    }

    @Override
    public StateClientConfig findStateClientConfig() {
        @SuppressWarnings("unchecked")
        List<StateClientConfig> list = (List<StateClientConfig>) getNamedQuery("clientConfig.findStateClientConfig");
        return list.isEmpty() ? null : list.get(0);
    }

    @Override
    public ContainerClientConfig findContainerClientConfig() {
        @SuppressWarnings("unchecked")
        List<ContainerClientConfig> list = (List<ContainerClientConfig>) getNamedQuery("clientConfig.findContainerClientConfig");
        return list.isEmpty() ? null : list.get(0);
    }

    @Override
    public GlobalClientConfig findGlobalClientConfig() {
        @SuppressWarnings("unchecked")
        List<GlobalClientConfig> list = (List<GlobalClientConfig>) getNamedQuery("clientConfig.findGlobalClientConfig");
        return list.isEmpty() ? null : list.get(0);
    }

    @Override
    public ShipmentClientConfig findShipmentClientConfig() {
        @SuppressWarnings("unchecked")
        List<ShipmentClientConfig> list = (List<ShipmentClientConfig>) getNamedQuery("clientConfig.findShipmentClientConfig");
        return list.isEmpty() ? null : list.get(0);
    }

    @Override
    public CostingClientConfig findCostingClientConfig() {
        @SuppressWarnings("unchecked")
        List<CostingClientConfig> list = (List<CostingClientConfig>) getNamedQuery("clientConfig.findCostingClientConfig");
        return list.isEmpty() ? null : list.get(0);
    }

    @Override
    public DocumentClientConfig findDocumentClientConfig() {
        @SuppressWarnings("unchecked")
        List<DocumentClientConfig> list = (List<DocumentClientConfig>) getNamedQuery("clientConfig.findDocumentClientConfig");
        return list.isEmpty() ? null : list.get(0);
    }

    @Override
    public ConsignmentClientConfig findConsignmentClientConfig() {
        @SuppressWarnings("unchecked")
        List<ConsignmentClientConfig> list = (List<ConsignmentClientConfig>)
                findByNamedQuery("clientConfig.findConsignmentClientConfig");
        return list.isEmpty() ? null : list.get(0);
    }

    @Override
    public ExchangeRateClientConfig findExchangeRateClientConfig() {
        @SuppressWarnings("unchecked")
        List<ExchangeRateClientConfig> list = (List<ExchangeRateClientConfig>) findByNamedQuery("clientConfig.findExchangeRateClientConfig");
        return list.isEmpty() ? null : list.get(0);
    }

    @Override
    public SABSSlidingScaleClientConfig findSABSSlidingScaleClientConfig() {
        @SuppressWarnings("unchecked")
        List<SABSSlidingScaleClientConfig> list = (List<SABSSlidingScaleClientConfig>)
                findByNamedQuery("clientConfig.findSABSSlidingScaleClientConfig");
        return list.isEmpty() ? null : list.get(0);
    }

    @Override
    public SABSTariffClientConfig findSABSTariffClientConfig() {
        @SuppressWarnings("unchecked")
        List<SABSTariffClientConfig> list = (List<SABSTariffClientConfig>) findByNamedQuery("clientConfig.findSABSTariffClientConfig");
        return list.isEmpty() ? null : list.get(0);
    }

    @Override
    public SupplierClientConfig findSupplierClientConfig() {
        @SuppressWarnings("unchecked")
        List<SupplierClientConfig> list = (List<SupplierClientConfig>) getNamedQuery("clientConfig.findSupplierClientConfig");
        return list.isEmpty() ? null : list.get(0);
    }

    @Override
    public ProductClientConfig findProductClientConfig() {
        List<ProductClientConfig> list = (List<ProductClientConfig>) getNamedQuery("clientConfig.findProductClientConfig");
        return list.isEmpty() ? null : list.get(0);
    }

    @Override
    public ItemsAndOrdersClientConfig findItemsAndOrdersClientConfig() {
        @SuppressWarnings("unchecked")
        List<ItemsAndOrdersClientConfig> list = (List<ItemsAndOrdersClientConfig>) getNamedQuery("clientConfig.findItemsAndOrdersClientConfig");
        return list.isEmpty() ? null : list.get(0);
    }

    @Override
    public TariffingClientConfig findTariffingClientConfig() {
        return findFirstByNamedQuery("clientConfig.findTariffingClientConfig");
    }

    @Override
    public boolean itemStateInUse(LineItemState itemState, LineItem.Type type) {
        return stateInUseWithType("itemStateMetaData.inUse", itemState, type);
    }

    @Override
    public boolean orderStateInUse(OrderState orderState, Order.Type type) {
        return stateInUseWithType("orderStateMetaData.inUse", orderState, type);
    }

    @Override
    public boolean consignmentStateInUse(ConsignmentState consignmentState) {
        return stateInUse("consignmentStateMetaData.inUse", consignmentState);
    }

    @Override
    public boolean documentStateInUse(DocumentState documentState, DocumentType documentType) {
        switch (documentType) {
            case COMMERCIAL_INVOICE:
                return stateInUse("commercialInvoiceStateMetaData.inUse", documentState);
            case SERVICE_PROVIDER_INVOICE:
                return stateInUse("serviceProviderInvoiceStateMetaData.inUse", documentState);
            case COMMERCIAL_CREDIT_NOTE:
                return stateInUse("commercialCreditNoteStateMetaData.inUse", documentState);
            case SERVICE_PROVIDER_CREDIT_NOTE:
                return stateInUse("serviceProviderCreditNoteStateMetaData.inUse", documentState);
            case CARTON:
                return stateInUse("cartonStateMetaData.inUse", documentState);
            default:
                return false;
        }
    }

    @Override
    public boolean shipmentStateInUse(ShipmentState shipmentState) {
        return stateInUse("shipmentStateMetaData.inUse", shipmentState);
    }

    @Override
    public boolean exportShipmentStateInUse(Status shipmentState) {
        return stateInUse("exportShipmentStateMetaData.inUse", shipmentState);
    }

    @Override
    public boolean containerStateInUse(ContainerState containerState) {
        return stateInUse("containerStateMetaData.inUse", containerState);
    }

    @Override
    public boolean productStateInUse(ProductState productState, Product.Type type) {
        return stateInUseWithType("productStateMetaData.inUse", productState, type);
    }

    private boolean stateInUse(String namedQuery, Enum<?> state) {
        @SuppressWarnings({"unchecked", "rawtypes"})
        List<StateMetaData> orderMetaData = (List<StateMetaData>) getNamedQueryAndNamedParam(namedQuery, "state", state);
        return orderMetaData.isEmpty() ? false : ObjectUtil.first(orderMetaData).isInUse();
    }

    private boolean stateInUseWithType(String namedQuery, Enum<?> state, Enum<?> type) {
        @SuppressWarnings({"unchecked", "rawtypes"})
        String[] paramName = {"state", "type"};
        Object[] paramValue = {state, type};

        List<StateMetaData> orderMetaData = (List<StateMetaData>) getNamedQueryAndNamedParam(namedQuery, paramName, paramValue);
        return orderMetaData.isEmpty() ? false : ObjectUtil.first(orderMetaData).isInUse();
    }

    @Override
    public LetterOfCreditClientConfig findLetterOfCreditClientConfig() {
        return findFirstByNamedQuery("clientConfig.findLetterOfCreditClientConfig");
    }

    @Override
    public ExportConfig findExportConfig() {
        List<ExportConfig> list = (List<ExportConfig>) getNamedQuery("clientConfig.findExportConfig");
        return list.isEmpty() ? null : list.get(0);
    }

    @Override
    public ReportMainConfig findReportMainConfig() {
        List<ReportMainConfig> list = (List<ReportMainConfig>) getNamedQuery("clientConfig.findReportMainConfig");
        return list.isEmpty() ? null : list.get(0);
    }

    @Override
    public boolean isIncotermEditableInIntegratedOrderItemsAndOrdersClientConfig() {
        Criteria criteria = getSessionCustom().createCriteria(ItemsAndOrdersClientConfig.class);
        criteria.createAlias("orderIntegrationConfig", "oic");
        criteria.createAlias("oic.purchaseOrderIntegrationProperties", "poip");
        criteria.setProjection(Projections.projectionList().
                add(Projections.property("poip.incoterm"), "0"));

        return (Boolean) criteria.uniqueResult();
    }

    @Override
    public SettlementDateCalculation findSettlementDateCalculation(CostGroup costGroup, CostingType costingType) {
        String queryString = "from SettlementDateCalculation where costGroup = :costGroup and costingType=:costingType";
        Query query = getCurrentSession().createQuery(queryString);
        query.setParameter("costGroup", costGroup);
        query.setParameter("costingType", costingType);
        List list = query.list();
        return list.isEmpty() ? null : (SettlementDateCalculation) list.get(0);
    }

    @Override
    public ElcConfig findElcClientConfig() {
        @SuppressWarnings("unchecked")
        List<ElcConfig> list = (List<ElcConfig>) getNamedQuery("clientConfig.findElcClientConfig");
        return ObjectUtil.first(list);
    }

    @Override
    public AutoEmailReportConfig findAutoEmailReportConfigForReport(Report report) {
        if (report != null) {
            String reportName = report.toString().substring(7, report.toString().length());
            List<AutoEmailReportConfig> list = (List<AutoEmailReportConfig>)
                    findByNamedQueryAndNamedParam("clientConfig.findAutoEmailConfigForReport",
                            new String[]{"reportType"}, new Object[]{reportName});

            return ObjectUtil.first(list);
        }
        return null;
    }

    @Override
    public List<AutoEmailReportConfig> findAllAutoEmailReportConfig() {
        List<AutoEmailReportConfig> autoEmailReportConfigs = (List<AutoEmailReportConfig>) getNamedQuery(
                "clientConfig.findAllAutoEmailConfigForReport");
        return autoEmailReportConfigs;
    }

    @Override
    public List<SpecialRequirementConfig> findAllSpecialRequirements() {
        List<SpecialRequirementConfig> specialRequirements = (List<SpecialRequirementConfig>) getNamedQuery("findAllSpecialRequirements");
        return specialRequirements;
    }

    @Override
    public OrganisationalUnitTier findExchangeRateConfigTier() {
        List<OrganisationalUnitTier> list = (List<OrganisationalUnitTier>) findByNamedQuery("clientConfig.findExchangeRateOrganisationalUnitTier");
        return list.isEmpty() ? null : list.get(0);
    }

    @Override
    public ClearingInstructionConfig getClearingInstructionConfig(boolean imports) {
        CriteriaBuilder criteriaBuilder = getSession().getCriteriaBuilder();
        CriteriaQuery<ClearingInstructionConfig> criteriaQuery = criteriaBuilder.createQuery(ClearingInstructionConfig.class);
        Root<ClearingInstructionConfig> c = criteriaQuery.from(ClearingInstructionConfig.class);
        criteriaQuery = criteriaQuery.select(c).where(criteriaBuilder.equal(c.get("imports"), imports));
        org.hibernate.query.Query<ClearingInstructionConfig> q = getSession().createQuery(criteriaQuery);
        q.setMaxResults(1);
        return q.uniqueResult();
    }

    @Override
    public ClearingInstructionConfig updateClearingInstructionConfig(ClearingInstructionConfig config) {
        if (config.getId() == null) {
            Serializable id = getSession().save(config);
            return getSession().get(ClearingInstructionConfig.class, id);
        } else {
            getSession().update(config);
            return getSession().get(ClearingInstructionConfig.class, config.getId());
        }
    }

    @Override
    public List<SARSImportConfig> getAllSarsImportConfig(boolean active) {
        String queryString = "from SARSImportConfig where active = :active";
        Query query = getCurrentSession().createQuery(queryString);
        query.setParameter("active", active);
        return query.getResultList();
    }

    @Override
    public ItacConfig updateItacConfig(ItacConfig itacConfig) {
        Object merged = getCurrentSession().merge(itacConfig);
        return (ItacConfig) merged;
    }

    @Override
    public ItacConfig getItacConfig() {
        return getCurrentSession().createQuery(" from ItacConfig", ItacConfig.class).getSingleResult();
    }
}