/*
 * JBILLING CONFIDENTIAL
 * _____________________
 *
 * [2003] - [2012] Enterprise jBilling Software Ltd.
 * All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Enterprise jBilling Software.
 * The intellectual and technical concepts contained
 * herein are proprietary to Enterprise jBilling Software
 * and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden.
 */

package com.sapienter.jbilling.server.pricing.strategy;

import com.sapienter.jbilling.server.item.PricingField;
import com.sapienter.jbilling.server.item.tasks.PricingResult;
import com.sapienter.jbilling.server.order.Usage;
import com.sapienter.jbilling.server.order.UsageBL;
import com.sapienter.jbilling.server.order.db.OrderDTO;
import com.sapienter.jbilling.server.pricing.db.AttributeDefinition;
import com.sapienter.jbilling.server.pricing.db.ChainPosition;
import com.sapienter.jbilling.server.pricing.db.PriceModelDTO;
import com.sapienter.jbilling.server.pricing.util.AttributeUtils;
import org.apache.log4j.Logger;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.SortedMap;

import static com.sapienter.jbilling.server.pricing.db.AttributeDefinition.Type.*;

/**
 * ItemSelectorPercentageStrategy
 *
 * @author Brian Cowdery
 * @since 13/07/11
 */
public class ItemPercentageSelectorStrategy extends ItemSelectorStrategy {

    private static final Logger LOG = Logger.getLogger(ItemPercentageSelectorStrategy.class);

    private static final BigDecimal ONE_HUNDRED = new BigDecimal("100.00");

    public ItemPercentageSelectorStrategy() {
        setAttributeDefinitions(
                new AttributeDefinition("typeId", INTEGER, true),
                new AttributeDefinition("percentOfTypeId", INTEGER, true),
                new AttributeDefinition("100", INTEGER, false)
        );

        setChainPositions(
                ChainPosition.START
        );

        setRequiresUsage(true);
    }

    public void applyTo(OrderDTO pricingOrder, PricingResult result, List<PricingField> fields,
                        PriceModelDTO planPrice, BigDecimal quantity, Usage usage, boolean singlePurchase) {

        // price of selector trigger item will be the set $/unit rate
        result.setPrice(planPrice.getRate());

        if (pricingOrder != null) {
            // parse item selection tiers
            SortedMap<Integer, Integer> tiers = getTiers(planPrice.getAttributes());
            LOG.debug("Item selector percentage tiers: " + tiers);

            BigDecimal percentage = getPercentageUsed(usage.getQuantity());
            LOG.debug("( " + usage.getQuantity() + " ) * 100 = " + percentage);
            LOG.debug("Selecting tier for usage percentage " + percentage);

            // find matching tier
            Integer selectedItemId = tiers.get(0);
            for (Integer tier : tiers.keySet()) {
                if (percentage.compareTo(new BigDecimal(tier)) >= 0) {
                    selectedItemId = tiers.get(tier);
                }
            }

            // add item
            if (selectedItemId != null) {
                addIfNotExists(pricingOrder, tiers, selectedItemId);
            } else {
                LOG.debug("No tier for usage percentage " + percentage);
            }

        } else {
            LOG.debug("No pricing order given (simple price fetch), skipping tiered item selection.");
        }
    }

    /**
     * Calculate the percentage
     * @param typeUsage
     * @return
     */
    public BigDecimal getPercentageUsed(BigDecimal typeUsage) {
        if (typeUsage.compareTo(BigDecimal.ZERO) == 0) return BigDecimal.ZERO;

        typeUsage = typeUsage.setScale(2);

        return typeUsage.multiply(ONE_HUNDRED);
    }
}

@@ -1928,18 +1928,16 @@
 nition(%22
-10
 0%22, INTE
@@ -2060,19 +2060,20 @@
 esUsage(
-tru
+fals
 e);%0A    
@@ -2625,24 +2625,493 @@
  + tiers);%0A%0A
+            // items used for selection%0A            Integer typeId = AttributeUtils.getInteger(planPrice.getAttributes(), %22typeId%22);%0A            Integer percentOfTypeId = AttributeUtils.getInteger(planPrice.getAttributes(), %22percentOfTypeId%22);%0A%0A            Usage typeUsage = new UsageBL(result.getUserId(), pricingOrder).getItemTypeUsage(typeId);%0A            Usage percentageTypeUsage = new UsageBL(result.getUserId(), pricingOrder).getItemTypeUsage(percentOfTypeId);%0A%0A
             
@@ -3152,17 +3152,56 @@
 ageUsed(
-u
+typeUsage.getQuantity(), percentageTypeU
 sage.get
@@ -3242,17 +3242,65 @@
 (%22( %22 + 
-u
+typeUsage.getQuantity() + %22 / %22 + percentageTypeU
 sage.get
@@ -4152,24 +4152,56 @@
 m typeUsage%0A
+     * @param percentageOfUsage%0A
      * @retu
@@ -4271,16 +4271,46 @@
 ypeUsage
+, BigDecimal percentageOfUsage
 ) %7B%0A    
@@ -4388,77 +4388,267 @@
 RO;%0A
-%0A        typeUsage = typeUsage.setScale(2);%0A%0A        return typeUsage
+        if (percentageOfUsage.compareTo(BigDecimal.ZERO) == 0) return ONE_HUNDRED;%0A%0A        typeUsage = typeUsage.setScale(2);%0A        percentageOfUsage = percentageOfUsage.setScale(2);%0A%0A        return typeUsage.divide(percentageOfUsage, RoundingMode.HALF_UP)
 .mul

Revert "Bugs #2955 Attribute of 'Item percentage Selector' pricing is not update at order screen page."