All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.broadleafcommerce.core.offer.service.discount.domain.PromotableFulfillmentGroupImpl Maven / Gradle / Ivy

There is a newer version: 3.1.15-GA
Show newest version
/*
 * Copyright 2008-2013 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.broadleafcommerce.core.offer.service.discount.domain;

import org.broadleafcommerce.common.money.Money;
import org.broadleafcommerce.core.order.domain.FulfillmentGroup;
import org.broadleafcommerce.core.order.domain.FulfillmentGroupItem;
import org.broadleafcommerce.core.order.domain.OrderItem;
import org.broadleafcommerce.core.order.domain.OrderItemContainer;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class PromotableFulfillmentGroupImpl implements PromotableFulfillmentGroup {

    private static final long serialVersionUID = 1L;
    protected FulfillmentGroup fulfillmentGroup;
    protected PromotableOrder promotableOrder;
    protected PromotableItemFactory itemFactory;
    protected List discountableOrderItems;
    protected boolean useSaleAdjustments = false;
    protected Money adjustedPrice;
    
    public List candidateFulfillmentGroupAdjustments = new ArrayList();
    
    public PromotableFulfillmentGroupImpl(FulfillmentGroup fulfillmentGroup,
            PromotableOrder promotableOrder,
            PromotableItemFactory itemFactory) {
        this.fulfillmentGroup = fulfillmentGroup;
        this.promotableOrder = promotableOrder;
        this.itemFactory = itemFactory;
    }

    @Override
    public FulfillmentGroup getFulfillmentGroup() {
        return fulfillmentGroup;
    }

    @Override
    public void updateRuleVariables(Map ruleVars) {
        ruleVars.put("fulfillmentGroup", fulfillmentGroup);
    }

    @Override
    public List getDiscountableOrderItems() {
        if (discountableOrderItems != null) {
            return discountableOrderItems;
        }
    
        discountableOrderItems = new ArrayList();
        List discountableOrderItemIds = new ArrayList();
        for (FulfillmentGroupItem fgItem : fulfillmentGroup.getFulfillmentGroupItems()) {
            OrderItem orderItem = fgItem.getOrderItem();
            if (orderItem.isDiscountingAllowed()) {
                discountableOrderItemIds.add(fgItem.getOrderItem().getId());
            } else {
                if (orderItem instanceof OrderItemContainer) {
                    OrderItemContainer orderItemContainer = (OrderItemContainer) orderItem;
                    if (orderItemContainer.getAllowDiscountsOnChildItems()) {
                        for (OrderItem containedOrderItem : orderItemContainer.getOrderItems()) {
                            if (!containedOrderItem.isDiscountingAllowed()) {
                                discountableOrderItemIds.add(containedOrderItem.getId());
                            }
                        }
                    }
                }
            }
        }
            
        for (PromotableOrderItem item : promotableOrder.getDiscountableOrderItems()) {
            if (discountableOrderItemIds.contains(item.getOrderItemId())) {
                discountableOrderItems.add(item);
            }
        }
        return discountableOrderItems;
    }

    protected Money getSalePriceBeforeAdjustments() {
        Money salePrice = fulfillmentGroup.getSaleFulfillmentPrice();
        if (salePrice == null) {
            return fulfillmentGroup.getRetailFulfillmentPrice();
        } else {
            return salePrice;
        }
    }

    protected Money calculateSaleAdjustmentPrice() {
        Money returnPrice = getSalePriceBeforeAdjustments();
        for (PromotableFulfillmentGroupAdjustment adjustment : candidateFulfillmentGroupAdjustments) {
            returnPrice = returnPrice.subtract(adjustment.getSaleAdjustmentValue());
        }
        return returnPrice;
    }

    protected Money calculateRetailAdjustmentPrice() {
        Money returnPrice = fulfillmentGroup.getRetailFulfillmentPrice();
        for (PromotableFulfillmentGroupAdjustment adjustment : candidateFulfillmentGroupAdjustments) {
            returnPrice = returnPrice.subtract(adjustment.getRetailAdjustmentValue());
        }
        return returnPrice;
    }

    /**
     * This method will check to see if the salePriceAdjustments or retailPriceAdjustments are better
     * and remove those that should not apply.
     * @return 
     */
    public void chooseSaleOrRetailAdjustments() {
        this.useSaleAdjustments = Boolean.FALSE;
        Money saleAdjustmentPrice = calculateSaleAdjustmentPrice();
        Money retailAdjustmentPrice = calculateRetailAdjustmentPrice();

        if (saleAdjustmentPrice.lessThan(retailAdjustmentPrice)) {
            this.useSaleAdjustments = Boolean.TRUE;
            adjustedPrice = saleAdjustmentPrice;
        } else {
            adjustedPrice = retailAdjustmentPrice;
        }

        if (useSaleAdjustments) {
            removeRetailOnlyAdjustments();
        }

        removeZeroDollarAdjustments(useSaleAdjustments);

        finalizeAdjustments(useSaleAdjustments);

    }

    protected void finalizeAdjustments(boolean useSaleAdjustments) {
        for (PromotableFulfillmentGroupAdjustment adjustment : candidateFulfillmentGroupAdjustments) {
            adjustment.finalizeAdjustment(useSaleAdjustments);
        }
    }

    /**
     * Removes retail only adjustments.
     */
    protected void removeRetailOnlyAdjustments() {
        Iterator adjustments = candidateFulfillmentGroupAdjustments.iterator();
        while (adjustments.hasNext()) {
            PromotableFulfillmentGroupAdjustment adjustment = adjustments.next();
            if (adjustment.getPromotableCandidateFulfillmentGroupOffer().getOffer().getApplyDiscountToSalePrice() == false) {
                adjustments.remove();
            }
        }
    }

    /**
     * If removeUnusedAdjustments is s 
     * @param useSaleAdjustments
     */
    protected void removeZeroDollarAdjustments(boolean useSalePrice) {
        Iterator adjustments = candidateFulfillmentGroupAdjustments.iterator();
        while (adjustments.hasNext()) {
            PromotableFulfillmentGroupAdjustment adjustment = adjustments.next();
            if (useSalePrice) {
                if (adjustment.getSaleAdjustmentValue().isZero()) {
                    adjustments.remove();
                }
            } else {
                if (adjustment.getRetailAdjustmentValue().isZero()) {
                    adjustments.remove();
                }
            }
        }
    }

    @Override
    public Money getFinalizedPriceWithAdjustments() {
        chooseSaleOrRetailAdjustments();
        return adjustedPrice;
    }

    @Override
    public Money calculatePriceWithoutAdjustments() {
        if (fulfillmentGroup.getSaleFulfillmentPrice() != null) {
            return fulfillmentGroup.getSaleFulfillmentPrice();
        } else {
            return fulfillmentGroup.getRetailFulfillmentPrice();
        }
    }

    @Override
    public void addCandidateFulfillmentGroupAdjustment(PromotableFulfillmentGroupAdjustment adjustment) {
        candidateFulfillmentGroupAdjustments.add(adjustment);
    }

    @Override
    public List getCandidateFulfillmentGroupAdjustments() {
        return Collections.unmodifiableList(candidateFulfillmentGroupAdjustments);
    }

    @Override
    public boolean canApplyOffer(PromotableCandidateFulfillmentGroupOffer fulfillmentGroupOffer) {
        if (candidateFulfillmentGroupAdjustments.size() > 0) {
            if (!fulfillmentGroupOffer.getOffer().isCombinableWithOtherOffers()) {
                return false;
            }

            for (PromotableFulfillmentGroupAdjustment adjustment : candidateFulfillmentGroupAdjustments) {
                if (!adjustment.isCombinable()) {
                    return false;
                }
            }
        }
        return true;
    }

    @Override
    public Money calculatePriceWithAdjustments(boolean useSalePrice) {
        if (useSalePrice) {
            return calculateSaleAdjustmentPrice();
        } else {
            return calculateRetailAdjustmentPrice();
        }
    }

    @Override
    public boolean isTotalitarianOfferApplied() {
        for (PromotableFulfillmentGroupAdjustment adjustment : candidateFulfillmentGroupAdjustments) {
            if (adjustment.getPromotableCandidateFulfillmentGroupOffer().getOffer().isTotalitarianOffer()) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void removeAllCandidateAdjustments() {
        candidateFulfillmentGroupAdjustments.clear();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy