protected boolean compareAndAdjustFulfillmentGroupOffers(
      PromotableOrder order, boolean fgOfferApplied) {
    Money regularOrderDiscountShippingTotal =
        BroadleafCurrencyUtils.getMoney(BigDecimal.ZERO, order.getOrderCurrency());
    regularOrderDiscountShippingTotal =
        regularOrderDiscountShippingTotal.add(order.calculateSubtotalWithoutAdjustments());
    for (PromotableFulfillmentGroup fg : order.getFulfillmentGroups()) {
      regularOrderDiscountShippingTotal =
          regularOrderDiscountShippingTotal.add(fg.getFinalizedPriceWithAdjustments());
    }

    Money discountOrderRegularShippingTotal =
        BroadleafCurrencyUtils.getMoney(BigDecimal.ZERO, order.getOrderCurrency());
    discountOrderRegularShippingTotal =
        discountOrderRegularShippingTotal.add(order.calculateSubtotalWithAdjustments());
    for (PromotableFulfillmentGroup fg : order.getFulfillmentGroups()) {
      discountOrderRegularShippingTotal =
          discountOrderRegularShippingTotal.add(fg.calculatePriceWithoutAdjustments());
    }

    if (discountOrderRegularShippingTotal.lessThan(regularOrderDiscountShippingTotal)) {
      // order/item offer is better; remove totalitarian fulfillment group offer and process other
      // fg offers
      order.removeAllCandidateFulfillmentOfferAdjustments();
      fgOfferApplied = false;
    } else {
      // totalitarian fg offer is better; remove all order/item offers
      order.removeAllCandidateOrderOfferAdjustments();
      order.removeAllCandidateItemOfferAdjustments();
      order.getOrder().setSubTotal(order.calculateSubtotalWithAdjustments());
    }
    return fgOfferApplied;
  }
 @Override
 public Money getTaxablePrice() {
   Money taxablePrice = BroadleafCurrencyUtils.getMoney(BigDecimal.ZERO, getOrder().getCurrency());
   if (sku.isTaxable() == null || sku.isTaxable()) {
     taxablePrice = getPrice();
   }
   return taxablePrice;
 }
 @Override
 public void calculateFulfillmentGroupTotal(PromotableOrder order) {
   Money totalFulfillmentCharges =
       BroadleafCurrencyUtils.getMoney(BigDecimal.ZERO, order.getOrderCurrency());
   for (PromotableFulfillmentGroup fulfillmentGroupMember : order.getFulfillmentGroups()) {
     PromotableFulfillmentGroup fulfillmentGroup = fulfillmentGroupMember;
     Money fulfillmentCharges = fulfillmentGroup.getFinalizedPriceWithAdjustments();
     fulfillmentGroup.getFulfillmentGroup().setFulfillmentPrice(fulfillmentCharges);
     totalFulfillmentCharges = totalFulfillmentCharges.add(fulfillmentCharges);
   }
   order.setTotalFufillmentCharges(totalFulfillmentCharges);
 }
  private void calculateShipping(FulfillmentGroup fulfillmentGroup) {
    if (!isValidModuleForService(fulfillmentGroup.getService()) && !isDefaultModule()) {
      LOG.info(
          "fulfillment group ("
              + fulfillmentGroup.getId()
              + ") with a service type of ("
              + fulfillmentGroup.getService()
              + ") is not valid for this module service type ("
              + getServiceName()
              + ")");
      return;
    }
    if (fulfillmentGroup.getFulfillmentGroupItems().size() == 0) {
      LOG.warn(
          "fulfillment group ("
              + fulfillmentGroup.getId()
              + ") does not contain any fulfillment group items. Unable to price banded shipping");
      fulfillmentGroup.setShippingPrice(
          BroadleafCurrencyUtils.getMoney(
              BigDecimal.ZERO, fulfillmentGroup.getOrder().getCurrency()));
      fulfillmentGroup.setSaleShippingPrice(
          BroadleafCurrencyUtils.getMoney(
              BigDecimal.ZERO, fulfillmentGroup.getOrder().getCurrency()));
      fulfillmentGroup.setRetailShippingPrice(
          BroadleafCurrencyUtils.getMoney(
              BigDecimal.ZERO, fulfillmentGroup.getOrder().getCurrency()));
      return;
    }
    Address address = fulfillmentGroup.getAddress();
    String state =
        (address != null && address.getState() != null)
            ? address.getState().getAbbreviation()
            : null;
    BigDecimal retailTotal = new BigDecimal(0);
    String feeType = feeTypeMapping.get(fulfillmentGroup.getMethod());
    String feeSubType =
        ((feeSubTypeMapping.get(state) == null)
            ? feeSubTypeMapping.get("ALL")
            : feeSubTypeMapping.get(state));

    for (FulfillmentGroupItem fulfillmentGroupItem : fulfillmentGroup.getFulfillmentGroupItems()) {
      BigDecimal price =
          (fulfillmentGroupItem.getRetailPrice() != null)
              ? fulfillmentGroupItem
                  .getRetailPrice()
                  .getAmount()
                  .multiply(BigDecimal.valueOf(fulfillmentGroupItem.getQuantity()))
              : null;
      if (price == null) {
        price =
            fulfillmentGroupItem
                .getOrderItem()
                .getRetailPrice()
                .getAmount()
                .multiply(BigDecimal.valueOf(fulfillmentGroupItem.getQuantity()));
      }
      retailTotal = retailTotal.add(price);
    }

    ShippingRate sr =
        shippingRateService.readShippingRateByFeeTypesUnityQty(feeType, feeSubType, retailTotal);
    if (sr == null) {
      throw new NotImplementedException(
          "Shipping rate " + fulfillmentGroup.getMethod() + " not supported");
    }
    BigDecimal shippingPrice = new BigDecimal(0);
    if (sr.getBandResultPercent().compareTo(0) > 0) {
      BigDecimal percent = new BigDecimal(sr.getBandResultPercent() / 100);
      shippingPrice = retailTotal.multiply(percent);
    } else {
      shippingPrice = sr.getBandResultQuantity();
    }
    fulfillmentGroup.setShippingPrice(
        BroadleafCurrencyUtils.getMoney(shippingPrice, fulfillmentGroup.getOrder().getCurrency()));
    fulfillmentGroup.setSaleShippingPrice(fulfillmentGroup.getShippingPrice());
    fulfillmentGroup.setRetailShippingPrice(fulfillmentGroup.getSaleShippingPrice());
  }
 protected Money convertToMoney(BigDecimal amount) {
   return amount == null
       ? null
       : BroadleafCurrencyUtils.getMoney(amount, getOrder().getCurrency());
 }
 @Override
 public Money getAmount() {
   return BroadleafCurrencyUtils.getMoney(amount, currency);
 }