1 16 17 18 41 package com.opensourcestrategies.crmsfa.forecasts; 42 43 import java.util.Map ; 44 import java.util.List ; 45 import java.util.ArrayList ; 46 import java.util.Iterator ; 47 import java.sql.Timestamp ; 48 import java.math.BigDecimal ; 49 50 import org.ofbiz.base.util.Debug; 51 import org.ofbiz.base.util.UtilMisc; 52 import org.ofbiz.base.util.UtilDateTime; 53 import org.ofbiz.base.util.UtilProperties; 54 import org.ofbiz.entity.GenericDelegator; 55 import org.ofbiz.entity.GenericValue; 56 import org.ofbiz.entity.GenericEntityException; 57 import org.ofbiz.entity.condition.EntityConditionList; 58 import org.ofbiz.entity.condition.EntityExpr; 59 import org.ofbiz.entity.condition.EntityOperator; 60 import org.ofbiz.entity.util.EntityFindOptions; 61 import org.ofbiz.entity.util.EntityUtil; 62 import org.ofbiz.entity.util.EntityListIterator; 63 import org.ofbiz.base.util.UtilNumber; 64 65 import com.opensourcestrategies.crmsfa.opportunities.UtilOpportunity; 66 67 73 public class UtilForecast { 74 75 public static final String module = UtilForecast.class.getName(); 76 77 public static int BD_FORECAST_DECIMALS = UtilNumber.getBigDecimalScale("crmsfa.properties", "crmsfa.forecast.decimals"); 79 public static int BD_FORECAST_PERCENT_ROUNDING = UtilNumber.getBigDecimalRoundingMode("crmsfa.properties", "crmsfa.forecast.rounding"); 80 public static int BD_FORECAST_PERCENT_DECIMALS = UtilNumber.getBigDecimalScale("crmsfa.properties", "crmsfa.forecast.percent.decimals"); 81 public static int BD_FORECAST_ROUNDING = UtilNumber.getBigDecimalRoundingMode("crmsfa.properties", "crmsfa.forecast.percent.rounding"); 82 public static BigDecimal ZERO = new BigDecimal ("0"); 83 84 88 public static Map computeForecastByOpportunities(Double quotaAmount, String organizationPartyId, String internalPartyId, 89 String currencyUomId, String customTimePeriodId, GenericDelegator delegator) 90 throws GenericEntityException { 91 92 BigDecimal closedAmount = ZERO; 94 BigDecimal bestCaseAmount = ZERO; 95 BigDecimal forecastAmount = ZERO; 96 BigDecimal percentOfQuotaForecast = ZERO; 97 BigDecimal percentOfQuotaClosed= ZERO; 98 99 double minimumProbability = 0.0; 101 try { 102 minimumProbability = Double.parseDouble(UtilProperties.getPropertyValue("crmsfa.properties", "crmsfa.forecast.minProbability")); 103 } catch (NumberFormatException ne) { 104 Debug.logWarning("Failed to parse property \"crmsfa.forecast.minProbability\": " + ne.getMessage() + "\nSetting minimum probability to 0.0.", module); 105 } 106 107 EntityListIterator opportunitiesELI = UtilOpportunity.getOpportunitiesForInternalParty(organizationPartyId, internalPartyId, customTimePeriodId, null, null, delegator); 109 List opportunities = opportunitiesELI.getCompleteList(); 110 111 if (opportunities.size() == 0) { 112 Debug.logWarning("no opportunities were found for the internalParty [" + internalPartyId + "] and organizationParty [" + organizationPartyId + "] over time period id [" + customTimePeriodId + "]", module); 113 } 114 115 for (Iterator iter = opportunities.iterator(); iter.hasNext(); ) { 116 GenericValue opportunity = (GenericValue) iter.next(); 117 if (Debug.verboseOn()) { 118 Debug.logVerbose("for timePeriod [" + customTimePeriodId + "] and party [" + internalPartyId + "]. Now working with opportunity: " + opportunity, module); 119 } 120 BigDecimal amount = opportunity.getBigDecimal("estimatedAmount"); 121 BigDecimal probability = opportunity.getBigDecimal("estimatedProbability"); 122 123 if (amount == null) continue; 124 125 String oppCurrencyUomId = opportunity.getString("currencyUomId"); 127 if ((oppCurrencyUomId == null) || !oppCurrencyUomId.equals(currencyUomId)) { 128 Debug.logWarning("Forecast currency unit of measure [" + currencyUomId + "] is different from opportunity ID [" + opportunity.getString("salesOpportunityId") 129 + "] currency which is [" + oppCurrencyUomId + "]. However, conversion is not currently implemented. Forecast will be incorrect.", module); 130 } 131 132 if (opportunity.getString("opportunityStageId").equals("SOSTG_CLOSED")) { 133 134 closedAmount = closedAmount.add(amount).setScale(BD_FORECAST_DECIMALS, BD_FORECAST_ROUNDING); 136 } else { 137 138 bestCaseAmount = bestCaseAmount.add(amount).setScale(BD_FORECAST_DECIMALS, BD_FORECAST_ROUNDING); 140 141 if ((probability != null) && (probability.doubleValue() >= minimumProbability)) { 143 forecastAmount = forecastAmount.add(probability.multiply(amount)).setScale(BD_FORECAST_DECIMALS, BD_FORECAST_ROUNDING); 144 } 145 } 146 if (Debug.verboseOn()) { 147 Debug.logVerbose("Now for timePeriod [" + customTimePeriodId + "] after opportunity [" + opportunity.getString("opportunityId") + "] " + 148 "closedAmouont = [" + closedAmount + "] bestCaseAmount = [" + bestCaseAmount + "] forecastAmount = [" + forecastAmount + "]" , module); 149 } 150 } 151 152 bestCaseAmount = bestCaseAmount.add(closedAmount).setScale(BD_FORECAST_DECIMALS, BD_FORECAST_ROUNDING); 153 forecastAmount = forecastAmount.add(closedAmount).setScale(BD_FORECAST_DECIMALS, BD_FORECAST_ROUNDING); 154 155 if (quotaAmount != null && quotaAmount.doubleValue() > 0.0) { 157 BigDecimal quota = new BigDecimal (quotaAmount.doubleValue()); 158 percentOfQuotaForecast = forecastAmount.divide(quota, BD_FORECAST_PERCENT_DECIMALS, BD_FORECAST_PERCENT_ROUNDING); 159 percentOfQuotaClosed = closedAmount.divide(quota, BD_FORECAST_PERCENT_DECIMALS, BD_FORECAST_PERCENT_ROUNDING); 160 } 161 162 return UtilMisc.toMap("closedAmount", new Double (closedAmount.doubleValue()), "bestCaseAmount", new Double (bestCaseAmount.doubleValue()), 164 "forecastAmount", new Double (forecastAmount.doubleValue()), "percentOfQuotaForecast", new Double (percentOfQuotaForecast.doubleValue()), 165 "percentOfQuotaClosed", new Double (percentOfQuotaClosed.doubleValue())); 166 } 167 168 public static Map computeForecastByChildren(String parentPeriodId, String organizationPartyId, String internalPartyId, 169 String currencyUomId, GenericDelegator delegator) 170 throws GenericEntityException { 171 172 BigDecimal quotaAmount = ZERO; 174 BigDecimal closedAmount = ZERO; 175 BigDecimal bestCaseAmount = ZERO; 176 BigDecimal forecastAmount = ZERO; 177 BigDecimal percentOfQuotaForecast = ZERO; 178 BigDecimal percentOfQuotaClosed= ZERO; 179 180 List forecasts = delegator.findByAnd("SalesForecastAndCustomTimePeriod", UtilMisc.toMap("parentPeriodId", parentPeriodId, 182 "organizationPartyId", organizationPartyId, "internalPartyId", internalPartyId)); 183 for (Iterator iter = forecasts.iterator(); iter.hasNext(); ) { 184 GenericValue forecast = (GenericValue) iter.next(); 185 186 BigDecimal childQuotaAmount = forecast.getBigDecimal("quotaAmount"); 187 if (childQuotaAmount != null) { 188 quotaAmount = quotaAmount.add(childQuotaAmount).setScale(BD_FORECAST_DECIMALS, BD_FORECAST_ROUNDING); 189 } 190 191 BigDecimal childClosedAmount = forecast.getBigDecimal("closedAmount"); 192 if (childClosedAmount != null) { 193 closedAmount = closedAmount.add(childClosedAmount).setScale(BD_FORECAST_DECIMALS, BD_FORECAST_ROUNDING); 194 } 195 196 BigDecimal childForecastAmount = forecast.getBigDecimal("forecastAmount"); 197 if (childForecastAmount != null) { 198 forecastAmount = forecastAmount.add(childForecastAmount).setScale(BD_FORECAST_DECIMALS, BD_FORECAST_ROUNDING); 199 } 200 201 BigDecimal childBestCaseAmount = forecast.getBigDecimal("bestCaseAmount"); 202 if (childBestCaseAmount != null) { 203 bestCaseAmount = bestCaseAmount.add(childBestCaseAmount).setScale(BD_FORECAST_DECIMALS, BD_FORECAST_ROUNDING); 204 } 205 } 206 207 if (quotaAmount.signum() != 0) { 209 percentOfQuotaForecast = forecastAmount.divide(quotaAmount, BD_FORECAST_PERCENT_DECIMALS, BD_FORECAST_PERCENT_ROUNDING); 210 percentOfQuotaClosed = closedAmount.divide(quotaAmount, BD_FORECAST_PERCENT_DECIMALS, BD_FORECAST_PERCENT_ROUNDING); 211 } 212 213 return UtilMisc.toMap("closedAmount", new Double (closedAmount.doubleValue()), "bestCaseAmount", new Double (bestCaseAmount.doubleValue()), 215 "forecastAmount", new Double (forecastAmount.doubleValue()), "percentOfQuotaForecast", new Double (percentOfQuotaForecast.doubleValue()), 216 "percentOfQuotaClosed", new Double (percentOfQuotaClosed.doubleValue()), "quotaAmount", new Double (quotaAmount.doubleValue())); 217 } 218 } 219 | Popular Tags |