Author: jonesde
Date: Mon May 19 22:48:51 2008 New Revision: 658108 URL: http://svn.apache.org/viewvc?rev=658108&view=rev Log: Applied patch from Bilgin Ibryam in Jira #OFBIZ-1756 to extend the support for by hours and by days in recurrence info and use them as part of conditions for promotions Modified: ofbiz/trunk/applications/ecommerce/data/DemoProduct.xml ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java ofbiz/trunk/applications/product/data/ProductTypeData.xml ofbiz/trunk/framework/service/src/org/ofbiz/service/calendar/RecurrenceInfo.java ofbiz/trunk/framework/service/src/org/ofbiz/service/calendar/RecurrenceRule.java Modified: ofbiz/trunk/applications/ecommerce/data/DemoProduct.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/ecommerce/data/DemoProduct.xml?rev=658108&r1=658107&r2=658108&view=diff ============================================================================== --- ofbiz/trunk/applications/ecommerce/data/DemoProduct.xml (original) +++ ofbiz/trunk/applications/ecommerce/data/DemoProduct.xml Mon May 19 22:48:51 2008 @@ -565,6 +565,7 @@ <ProductPromo productPromoId="9019" promoName="Test Percent off when Customer Orders over $1000 in 12 months" userEntered="Y" useLimitPerOrder="1" createdDate="2001-05-13 12:00:00.0"> <promoText><![CDATA[Spend more than $1000 in any 12 months on our fabulous Widgets and Gizmos and get a 5% discount.]]></promoText> </ProductPromo> + <ProductPromo productPromoId="9020" promoName="Test Promotion Recurrence - Happy hour" promoText="Get 1 Free [WG-1111], between 15:00 - 18:00 at weekdays" userEntered="Y" showToCustomer="Y" requireCode="N" useLimitPerOrder="1" createdDate="2008-01-01 12:00:00.0" createdByUserLogin="admin" lastModifiedDate="2008-01-01 12:00:00.0" lastModifiedByUserLogin="admin"/> <ProductPromoRule productPromoId="9000" productPromoRuleId="01" ruleName="Rule 1: Free Widget"/> <ProductPromoRule productPromoId="9010" productPromoRuleId="01" ruleName="Test Percent off rule"/> <ProductPromoRule productPromoId="9011" productPromoRuleId="01" ruleName="Test percent off order"/> @@ -576,6 +577,7 @@ <ProductPromoRule productPromoId="9017" productPromoRuleId="01" ruleName="GWP for Gizmos Only"/> <ProductPromoRule productPromoId="9018" productPromoRuleId="01" ruleName="GWP for Gizmos Only Not Counted"/> <ProductPromoRule productPromoId="9019" productPromoRuleId="01" ruleName="Percent off for Ordered Sub-Total History"/> + <ProductPromoRule productPromoId="9020" productPromoRuleId="01" ruleName="Test Promotion Recurrence"/> <ProductPromoAction productPromoId="9000" productPromoRuleId="01" productPromoActionSeqId="01" productPromoActionEnumId="PROMO_GWP" orderAdjustmentTypeId="PROMOTION_ADJUSTMENT" quantity="1.0" productId="WG-1111"/> <ProductPromoAction productPromoId="9010" productPromoRuleId="01" productPromoActionSeqId="01" productPromoActionEnumId="PROMO_PROD_DISC" orderAdjustmentTypeId="PROMOTION_ADJUSTMENT" quantity="1.0" amount="20.0"/> <ProductPromoAction productPromoId="9011" productPromoRuleId="01" productPromoActionSeqId="01" productPromoActionEnumId="PROMO_ORDER_PERCENT" orderAdjustmentTypeId="PROMOTION_ADJUSTMENT" amount="10.0"/> @@ -587,6 +589,7 @@ <ProductPromoAction productPromoId="9017" productPromoRuleId="01" productPromoActionSeqId="01" productPromoActionEnumId="PROMO_GWP" orderAdjustmentTypeId="PROMOTION_ADJUSTMENT" quantity="1.0" productId="GZ-1006"/> <ProductPromoAction productPromoId="9018" productPromoRuleId="01" productPromoActionSeqId="01" productPromoActionEnumId="PROMO_GWP" orderAdjustmentTypeId="PROMOTION_ADJUSTMENT" quantity="1.0" productId="GZ-1006"/> <ProductPromoAction productPromoId="9019" productPromoRuleId="01" productPromoActionSeqId="01" productPromoActionEnumId="PROMO_ORDER_PERCENT" orderAdjustmentTypeId="PROMOTION_ADJUSTMENT" amount="5.0"/> + <ProductPromoAction productPromoId="9020" productPromoRuleId="01" productPromoActionSeqId="01" productPromoActionEnumId="PROMO_GWP" orderAdjustmentTypeId="PROMOTION_ADJUSTMENT" quantity="1.0" productId="WG-1111"/> <ProductPromoCond productPromoId="9000" productPromoRuleId="01" productPromoCondSeqId="01" inputParamEnumId="PPIP_ORDER_TOTAL" operatorEnumId="PPC_GT" condValue="100"/> <ProductPromoCond productPromoId="9012" productPromoRuleId="01" productPromoCondSeqId="01" inputParamEnumId="PPIP_ORDER_TOTAL" operatorEnumId="PPC_GTE" condValue="50"/> <ProductPromoCond productPromoId="9013" productPromoRuleId="01" productPromoCondSeqId="01" inputParamEnumId="PPIP_PRODUCT_QUANT" operatorEnumId="PPC_EQ" condValue="3"/> @@ -594,6 +597,7 @@ <ProductPromoCond productPromoId="9017" productPromoRuleId="01" productPromoCondSeqId="01" inputParamEnumId="PPIP_PRODUCT_AMOUNT" operatorEnumId="PPC_EQ" condValue="50"/> <ProductPromoCond productPromoId="9018" productPromoRuleId="01" productPromoCondSeqId="01" inputParamEnumId="PPIP_PRODUCT_TOTAL" operatorEnumId="PPC_GTE" condValue="150"/> <ProductPromoCond productPromoId="9019" productPromoRuleId="01" productPromoCondSeqId="01" inputParamEnumId="PPIP_ORST_HIST" operatorEnumId="PPC_GTE" condValue="1000" otherValue="12"/> + <ProductPromoCond productPromoId="9020" productPromoRuleId="01" productPromoCondSeqId="01" inputParamEnumId="PPIP_RECURRENCE" operatorEnumId="PPC_EQ" condValue="205"/> <ProductPromoCategory productPromoId="9013" productPromoRuleId="_NA_" productPromoActionSeqId="_NA_" productPromoCondSeqId="_NA_" productCategoryId="200" andGroupId="_NA_" productPromoApplEnumId="PPPA_INCLUDE" includeSubCategories="Y"/> <ProductPromoCategory productPromoId="9013" productPromoRuleId="_NA_" productPromoActionSeqId="_NA_" productPromoCondSeqId="_NA_" productCategoryId="201" andGroupId="_NA_" productPromoApplEnumId="PPPA_EXCLUDE" includeSubCategories="Y"/> <ProductPromoCategory productPromoId="9013" productPromoRuleId="_NA_" productPromoActionSeqId="_NA_" productPromoCondSeqId="_NA_" productCategoryId="20111" andGroupId="_NA_" productPromoApplEnumId="PPPA_ALWAYS" includeSubCategories="N"/> @@ -622,6 +626,7 @@ <ProductStorePromoAppl productStoreId="9000" productPromoId="9017" fromDate="2001-05-13 12:00:00.0" sequenceNum="1"/> <ProductStorePromoAppl productStoreId="9000" productPromoId="9018" fromDate="2001-05-13 12:00:00.0" sequenceNum="1"/> <ProductStorePromoAppl productStoreId="9000" productPromoId="9019" fromDate="2001-05-13 12:00:00.0" sequenceNum="1"/> + <ProductStorePromoAppl productStoreId="9000" productPromoId="9020" fromDate="2001-05-13 12:00:00.0" sequenceNum="1"/> <ProductPromo productPromoId="9021" promoName="Test Products for Special Promo Price" promoText="With special code [9021] get products in the Featured Products category for their special promotion price." userEntered="Y" showToCustomer="Y" requireCode="Y" createdDate="2001-05-13 12:00:00.0" createdByUserLogin="admin" lastModifiedDate="2001-05-13 12:00:00.0" lastModifiedByUserLogin="admin"/> <ProductPromoCode productPromoCodeId="9021" productPromoId="9021" userEntered="Y" requireEmailOrParty="N" createdDate="2001-05-13 12:00:00.0" createdByUserLogin="admin" lastModifiedDate="2001-05-13 12:00:00.0" lastModifiedByUserLogin="admin"/> @@ -629,6 +634,10 @@ <ProductPromoAction productPromoId="9021" productPromoRuleId="01" productPromoActionSeqId="01" productPromoActionEnumId="PROMO_PROD_SPPRC" orderAdjustmentTypeId="PROMOTION_ADJUSTMENT"/> <ProductPromoCategory productPromoId="9021" productPromoRuleId="01" productPromoActionSeqId="01" productPromoCondSeqId="_NA_" productCategoryId="PROMOTIONS" andGroupId="_NA_" productPromoApplEnumId="PPPA_INCLUDE" includeSubCategories="N"/> <ProductStorePromoAppl productStoreId="9000" productPromoId="9021" fromDate="2001-05-13 12:00:00.0" sequenceNum="1"/> + + <!-- a promotion recurrence example for happy hour--> + <RecurrenceRule recurrenceRuleId="205" frequency="DAILY" intervalNumber="1" countNumber="-1" byHourList="15,16,17" byDayList="MO,TU,WE,TH,FR"/> + <RecurrenceInfo recurrenceInfoId="205" startDateTime="2008-01-01 00:00:00.000" recurrenceRuleId="205" recurrenceCount="0"/> <!-- a default pricing rule to play with; take 20% off all products in the PROMOTIONS category --> <ProductPriceRule productPriceRuleId="9000" ruleName="Test Rule 1" isSale="Y"/> Modified: ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java?rev=658108&r1=658107&r2=658108&view=diff ============================================================================== --- ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java (original) +++ ofbiz/trunk/applications/order/src/org/ofbiz/order/shoppingcart/product/ProductPromoWorker.java Mon May 19 22:48:51 2008 @@ -59,6 +59,8 @@ import org.ofbiz.service.LocalDispatcher; import org.ofbiz.service.ModelService; import org.ofbiz.service.ServiceUtil; +import org.ofbiz.service.calendar.RecurrenceInfo; +import org.ofbiz.service.calendar.RecurrenceInfoException; /** * ProductPromoWorker - Worker class for catalog/product promotion related functionality @@ -1035,6 +1037,24 @@ } else { return false; } + } else if ("PPIP_RECURRENCE".equals(inputParamEnumId)) { + compareBase = new Integer(1); + GenericValue recurrenceInfo = delegator.findByPrimaryKeyCache("RecurrenceInfo", UtilMisc.toMap("recurrenceInfoId", condValue)); + if (recurrenceInfo != null) { + RecurrenceInfo recurrence = null; + try { + recurrence = new RecurrenceInfo(recurrenceInfo); + } catch (RecurrenceInfoException e) { + Debug.logError(e, module); + } + + // check the current recurrence + if (recurrence != null) { + if (recurrence.isValidCurrent()) { + compareBase = new Integer(0); + } + } + } } else { Debug.logWarning(UtilProperties.getMessage(resource_error,"OrderAnUnSupportedProductPromoCondInputParameterLhs", UtilMisc.toMap("inputParamEnumId",productPromoCond.getString("inputParamEnumId")), cart.getLocale()), module); return false; Modified: ofbiz/trunk/applications/product/data/ProductTypeData.xml URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/data/ProductTypeData.xml?rev=658108&r1=658107&r2=658108&view=diff ============================================================================== --- ofbiz/trunk/applications/product/data/ProductTypeData.xml (original) +++ ofbiz/trunk/applications/product/data/ProductTypeData.xml Mon May 19 22:48:51 2008 @@ -348,6 +348,7 @@ <Enumeration description="Party Classification" enumCode="PARTY_CLASS" enumId="PPIP_PARTY_CLASS" sequenceId="08" enumTypeId="PROD_PROMO_IN_PARAM"/> <Enumeration description="Role Type" enumCode="ROLE_TYPE" enumId="PPIP_ROLE_TYPE" sequenceId="09" enumTypeId="PROD_PROMO_IN_PARAM"/> <Enumeration description="Order sub-total X in last Y Months" enumCode="ORST_HIST" enumId="PPIP_ORST_HIST" sequenceId="10" enumTypeId="PROD_PROMO_IN_PARAM"/> + <Enumeration description="Promotion Recurrence" enumCode="PROMO_RECURRENCE" enumId="PPIP_RECURRENCE" sequenceId="11" enumTypeId="PROD_PROMO_IN_PARAM"/> <EnumerationType description="Product Promotion Condition" enumTypeId="PROD_PROMO_COND" hasTable="N" parentTypeId="PROD_PROMO"/> <!-- old style very technical ... Modified: ofbiz/trunk/framework/service/src/org/ofbiz/service/calendar/RecurrenceInfo.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/calendar/RecurrenceInfo.java?rev=658108&r1=658107&r2=658108&view=diff ============================================================================== --- ofbiz/trunk/framework/service/src/org/ofbiz/service/calendar/RecurrenceInfo.java (original) +++ ofbiz/trunk/framework/service/src/org/ofbiz/service/calendar/RecurrenceInfo.java Mon May 19 22:48:51 2008 @@ -19,7 +19,6 @@ package org.ofbiz.service.calendar; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Iterator; @@ -27,7 +26,6 @@ import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.StringUtil; -import org.ofbiz.base.util.UtilMisc; import org.ofbiz.entity.GenericDelegator; import org.ofbiz.entity.GenericEntityException; import org.ofbiz.entity.GenericValue; @@ -44,7 +42,7 @@ protected List<RecurrenceRule> rRulesList; protected List<RecurrenceRule> eRulesList; protected List<Date> rDateList; - protected List<Date> eDateList;; + protected List<Date> eDateList; /** Creates new RecurrenceInfo */ public RecurrenceInfo(GenericValue info) throws RecurrenceInfoException { @@ -231,6 +229,33 @@ } return nextRuleTime; } + + /** Checks the current recurrence validity at the moment. */ + public boolean isValidCurrent() { + return isValidCurrent(RecurrenceUtil.now()); + } + + /** Checks the current recurrence validity for checkTime. */ + public boolean isValidCurrent(long checkTime) { + if (checkTime == 0 || (rDateList == null && rRulesList == null)) { + return false; + } + + boolean found = false; + Iterator<RecurrenceRule> rulesIterator = getRecurrenceRuleIterator(); + while (rulesIterator.hasNext()) { + RecurrenceRule rule = rulesIterator.next(); + long currentTime = rule.validCurrent(getStartTime(), checkTime, getCurrentCount()); + currentTime = checkDateList(rDateList, currentTime, checkTime); + if ((currentTime > 0) && isValid(checkTime)) { + found = true; + } else { + return false; + } + } + + return found; + } private long getNextTime(RecurrenceRule rule, long fromTime) { long nextTime = rule.next(getStartTime(), fromTime, getCurrentCount()); Modified: ofbiz/trunk/framework/service/src/org/ofbiz/service/calendar/RecurrenceRule.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/calendar/RecurrenceRule.java?rev=658108&r1=658107&r2=658108&view=diff ============================================================================== --- ofbiz/trunk/framework/service/src/org/ofbiz/service/calendar/RecurrenceRule.java (original) +++ ofbiz/trunk/framework/service/src/org/ofbiz/service/calendar/RecurrenceRule.java Mon May 19 22:48:51 2008 @@ -26,7 +26,6 @@ import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.StringUtil; -import org.ofbiz.base.util.UtilMisc; import org.ofbiz.entity.GenericDelegator; import org.ofbiz.entity.GenericEntityException; import org.ofbiz.entity.GenericValue; @@ -285,6 +284,116 @@ } /** + * Gets the current recurrence (current for the checkTime) of this rule and returns it if it is valid. + * If the current recurrence is not valid, doesn't try to find a valid one, instead returns 0. + *@param startTime The time this recurrence first began. + *@param checkTime The time to base the current recurrence on. + *@param currentCount The total number of times the recurrence has run. + *@return long The current recurrence as long if valid. If next recurrence is not valid, returns 0. + */ + public long validCurrent(long startTime, long checkTime, long currentCount) { + if (startTime == 0) { + startTime = RecurrenceUtil.now(); + } + if (checkTime == 0) { + checkTime = startTime; + } + + // Test the end time of the recurrence. + if (getEndTime() != 0 && getEndTime() <= RecurrenceUtil.now()) { + return 0; + } + + // Test the recurrence limit. + if (getCount() != -1 && currentCount >= getCount()) { + return 0; + } + + // Get the next frequency from checkTime + Date nextRun = getNextFreq(startTime, checkTime); + Calendar cal = Calendar.getInstance(); + Calendar checkTimeCal = Calendar.getInstance(); + cal.setTime(nextRun); + checkTimeCal.setTime(new Date(checkTime)); + + // Get previous frequency and update its values from checkTime + switch (getFrequency()) { + case YEARLY: + cal.add(Calendar.YEAR, -getIntervalInt()); + if (cal.get(Calendar.YEAR) != checkTimeCal.get(Calendar.YEAR)) { + return 0; + } + + case MONTHLY: + if (MONTHLY == getFrequency()) { + cal.add(Calendar.MONTH, -getIntervalInt()); + if (cal.get(Calendar.MONTH) != checkTimeCal.get(Calendar.MONTH)) { + return 0; + } + } else { + cal.set(Calendar.MONTH, checkTimeCal.get(Calendar.MONTH)); + } + + case WEEKLY: + if (WEEKLY == getFrequency()) { + cal.add(Calendar.WEEK_OF_YEAR, -getIntervalInt()); + if (cal.get(Calendar.WEEK_OF_YEAR) != checkTimeCal.get(Calendar.WEEK_OF_YEAR)) { + return 0; + } + } else { + cal.set(Calendar.WEEK_OF_YEAR, checkTimeCal.get(Calendar.WEEK_OF_YEAR)); + } + + case DAILY: + if (DAILY == getFrequency()) { + cal.add(Calendar.DAY_OF_MONTH, -getIntervalInt()); + if (cal.get(Calendar.DAY_OF_MONTH) != checkTimeCal.get(Calendar.DAY_OF_MONTH)) { + return 0; + } + } else { + cal.set(Calendar.DAY_OF_MONTH, checkTimeCal.get(Calendar.DAY_OF_MONTH)); + } + + case HOURLY: + if (HOURLY == getFrequency()) { + cal.add(Calendar.HOUR_OF_DAY, -getIntervalInt()); + if (cal.get(Calendar.HOUR_OF_DAY) != checkTimeCal.get(Calendar.HOUR_OF_DAY)) { + return 0; + } + } else { + cal.set(Calendar.HOUR_OF_DAY, checkTimeCal.get(Calendar.HOUR_OF_DAY)); + } + + case MINUTELY: + if (MINUTELY == getFrequency()) { + cal.add(Calendar.MINUTE, -getIntervalInt()); + if (cal.get(Calendar.MINUTE) != checkTimeCal.get(Calendar.MINUTE)) { + return 0; + } + } else { + cal.set(Calendar.MINUTE, checkTimeCal.get(Calendar.MINUTE)); + } + + case SECONDLY: + if (SECONDLY == getFrequency()) { + cal.add(Calendar.SECOND, -getIntervalInt()); + if (cal.get(Calendar.SECOND) != checkTimeCal.get(Calendar.SECOND)) { + return 0; + } + } else { + cal.set(Calendar.SECOND, checkTimeCal.get(Calendar.SECOND)); + } + } + + // Check for validity of the current frequency. + if (validByRule(cal.getTime())) { + return cal.getTime().getTime(); + } + + return 0; + } + + /** * Tests the date to see if it falls within the rules *@param startDate date object to test *@return True if the date is within the rules @@ -344,7 +453,7 @@ break; case HOURLY: - cal.add(Calendar.HOUR, getIntervalInt()); + cal.add(Calendar.HOUR_OF_DAY, getIntervalInt()); break; case DAILY: @@ -380,15 +489,15 @@ // Test each byXXX rule. if (bySecondList != null && bySecondList.size() > 0) { - if (!bySecondList.contains(cal.get(Calendar.SECOND))) + if (!bySecondList.contains(String.valueOf(cal.get(Calendar.SECOND)))) return false; } if (byMinuteList != null && byMinuteList.size() > 0) { - if (!byMinuteList.contains(cal.get(Calendar.MINUTE))) + if (!byMinuteList.contains(String.valueOf(cal.get(Calendar.MINUTE)))) return false; } if (byHourList != null && byHourList.size() > 0) { - if (!byHourList.contains(cal.get(Calendar.HOUR))) + if (!byHourList.contains(String.valueOf(cal.get(Calendar.HOUR_OF_DAY)))) return false; } if (byDayList != null && byDayList.size() > 0) { @@ -399,7 +508,7 @@ String dayRule = (String) iter.next(); String dayString = getDailyString(dayRule); - if (Calendar.DAY_OF_WEEK == getCalendarDay(dayString)) { + if (cal.get(Calendar.DAY_OF_WEEK) == getCalendarDay(dayString)) { if ((hasNumber(dayRule)) && (getFrequency() == MONTHLY || getFrequency() == YEARLY)) { int modifier = getDailyNumber(dayRule); @@ -563,7 +672,7 @@ private boolean hasNumber(String str) { String list[] = {"+", "-", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"}; List numberList = Arrays.asList(list); - String firstChar = str.substring(0, 0); + String firstChar = str.substring(0, 1); if (numberList.contains(firstChar)) return true; @@ -599,7 +708,7 @@ StringBuilder sBuf = new StringBuilder(); for (int i = 0; i < str.length(); i++) { - String thisChar = str.substring(i, i); + String thisChar = str.substring(i, i+1); if (!hasNumber(thisChar)) { sBuf.append(thisChar); @@ -610,6 +719,7 @@ // Returns the Calendar day of the rule day string private int getCalendarDay(String day) { + if (day != null) day = day.trim(); if (day.equalsIgnoreCase("MO")) return Calendar.MONDAY; if (day.equalsIgnoreCase("TU")) |
Free forum by Nabble | Edit this page |