de.hybris.platform.b2bacceleratorfacades.order.converters.populator.GroupOrderEntryPopulator.java Source code

Java tutorial

Introduction

Here is the source code for de.hybris.platform.b2bacceleratorfacades.order.converters.populator.GroupOrderEntryPopulator.java

Source

/*
 * [y] hybris Platform
 *
 * Copyright (c) 2000-2014 hybris AG
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of hybris
 * ("Confidential Information"). You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the
 * license agreement you entered into with hybris.
 *
 *  
 */
package de.hybris.platform.b2bacceleratorfacades.order.converters.populator;

import java.math.BigDecimal;
import java.util.*;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Required;

import de.hybris.platform.acceleratorfacades.order.data.PriceRangeData;
import de.hybris.platform.commercefacades.order.data.AbstractOrderData;
import de.hybris.platform.commercefacades.order.data.OrderEntryData;
import de.hybris.platform.commercefacades.product.PriceDataFactory;
import de.hybris.platform.commercefacades.product.data.PriceData;
import de.hybris.platform.commercefacades.product.data.ProductData;
import de.hybris.platform.converters.Populator;
import de.hybris.platform.core.model.order.AbstractOrderModel;
import de.hybris.platform.core.model.product.ProductModel;
import de.hybris.platform.product.ProductService;
import de.hybris.platform.servicelayer.dto.converter.ConversionException;

/**
 * Groups multiple {@link OrderEntryData} as one entry in a {@link AbstractOrderData) based on the multidimensional
 * variants that share the same base product. All non multidimensional product entries will be leaved unmodified as a
 * single entry.
 */
public class GroupOrderEntryPopulator implements Populator<AbstractOrderModel, AbstractOrderData> {

    public static final String VARIANT_TYPE = "GenericVariantProduct";
    public static final int INVALID_ENTRY_NUMBER = -1;
    public static final long ZERO_QUANTITY = 0L;

    private ProductService productService;
    private PriceDataFactory priceDataFactory;

    @Override
    public void populate(AbstractOrderModel source, AbstractOrderData target) throws ConversionException {

        target.setEntries(groupEntries(target.getEntries()));

    }

    protected ArrayList groupEntries(final List<OrderEntryData> entries) {
        Map<String, OrderEntryData> group = new HashMap<>();
        boolean anyGroup = false;

        for (final OrderEntryData entry : entries) {
            final ProductData product = entry.getProduct();

            if (isGroupable(product)) {
                anyGroup = true;
                if (!group.containsKey(product.getBaseProduct())) {
                    group.put(product.getBaseProduct(), createGroupedOrderEntry(entry));
                }

                group.get(product.getBaseProduct()).getEntries().add(entry);

            } else {
                group.put(product.getCode(), entry);
            }

        }

        if (anyGroup) {
            consolidateGroupedOrderEntry(group);
        }

        return new ArrayList(group.values());
    }

    // This should be replaced by product.mutidimentional but at this stage is not yet populated
    // Only works for multidimentional products
    protected boolean isGroupable(final ProductData product) {
        return product.getBaseProduct() != null && CollectionUtils.isNotEmpty(product.getBaseOptions())
                && VARIANT_TYPE.equalsIgnoreCase(product.getBaseOptions().get(0).getVariantType());
    }

    protected void consolidateGroupedOrderEntry(final Map<String, OrderEntryData> group) {

        for (String productCode : group.keySet()) {
            final OrderEntryData parentEntry = group.get(productCode);
            if (parentEntry.getEntries() != null) {
                PriceData firstEntryTotalPrice = parentEntry.getEntries().get(0).getTotalPrice();
                PriceRangeData priceRange = parentEntry.getProduct().getPriceRange();

                if (firstEntryTotalPrice != null) {
                    priceRange.setMaxPrice(getMaxPrice(parentEntry, firstEntryTotalPrice));
                    priceRange.setMinPrice(getMinPrice(parentEntry, firstEntryTotalPrice));
                    parentEntry.setTotalPrice(getTotalPrice(parentEntry, firstEntryTotalPrice));
                }

                parentEntry.setQuantity(getTotalQuantity(parentEntry));
            }

        }
    }

    protected PriceData getMaxPrice(OrderEntryData parentEntry, PriceData samplePrice) {
        long newMaxPrice = 0;

        for (OrderEntryData childEntry : parentEntry.getEntries()) {
            if (isNotEmptyPrice(childEntry.getBasePrice())) {
                final long basePriceValue = childEntry.getBasePrice().getValue().longValue();
                if (basePriceValue > newMaxPrice) {
                    newMaxPrice = basePriceValue;
                }
            }
        }

        return buildPrice(samplePrice, newMaxPrice);
    }

    protected PriceData getMinPrice(OrderEntryData parentEntry, PriceData samplePrice) {
        long newMinPrice = Long.MAX_VALUE;

        for (OrderEntryData childEntry : parentEntry.getEntries()) {
            if (isNotEmptyPrice(childEntry.getBasePrice())) {
                final long basePriceValue = childEntry.getBasePrice().getValue().longValue();
                if (basePriceValue < newMinPrice) {
                    newMinPrice = basePriceValue;
                }
            }
        }

        return buildPrice(samplePrice, newMinPrice);
    }

    private boolean isNotEmptyPrice(PriceData price) {
        return price != null && price.getValue() != null;
    }

    protected PriceData getTotalPrice(OrderEntryData parentEntry, PriceData samplePrice) {
        long newTotalPrice = 0;

        for (OrderEntryData childEntry : parentEntry.getEntries()) {
            if (isNotEmptyPrice(childEntry.getBasePrice())) {
                newTotalPrice += childEntry.getTotalPrice().getValue().longValue();
            }
        }

        return buildPrice(samplePrice, newTotalPrice);
    }

    protected long getTotalQuantity(OrderEntryData parentEntry) {

        long totalQuantity = 0;
        for (OrderEntryData childEntry : parentEntry.getEntries()) {
            totalQuantity += (childEntry.getQuantity() != null ? childEntry.getQuantity() : 0);
        }

        return totalQuantity;
    }

    protected OrderEntryData createGroupedOrderEntry(final OrderEntryData firstEntry) {

        final OrderEntryData groupedEntry = new OrderEntryData();
        groupedEntry.setEntries(new ArrayList<OrderEntryData>());
        groupedEntry.setEntryNumber(INVALID_ENTRY_NUMBER);

        groupedEntry.setQuantity(ZERO_QUANTITY);

        final ProductData baseProduct = createBaseProduct(firstEntry.getProduct());
        groupedEntry.setProduct(baseProduct);

        groupedEntry.setUpdateable(firstEntry.isUpdateable());
        groupedEntry.setBasePrice(firstEntry.getBasePrice());

        return groupedEntry;
    }

    protected ProductData createBaseProduct(final ProductData variant) {

        final ProductData productData = new ProductData();

        productData.setUrl(variant.getUrl());
        productData.setPurchasable(variant.getPurchasable());
        productData.setMultidimensional(true);
        productData.setImages(variant.getImages());

        final ProductModel productModel = productService.getProductForCode(variant.getBaseProduct());
        productData.setCode(productModel.getCode());
        productData.setName(productModel.getName());
        productData.setDescription(productModel.getDescription());

        productData.setPriceRange(new PriceRangeData());

        return productData;

    }

    protected PriceData buildPrice(final PriceData base, final long amount) {
        return getPriceDataFactory().create(base.getPriceType(), BigDecimal.valueOf(amount), base.getCurrencyIso());
    }

    protected ProductService getProductService() {
        return productService;
    }

    @Required
    public void setProductService(final ProductService productService) {
        this.productService = productService;
    }

    protected PriceDataFactory getPriceDataFactory() {
        return priceDataFactory;
    }

    @Required
    public void setPriceDataFactory(PriceDataFactory priceDataFactory) {
        this.priceDataFactory = priceDataFactory;
    }
}