KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > product > product > ProductUtilServices


1 /*
2  * $Id: ProductUtilServices.java 5462 2005-08-05 18:35:48Z jonesde $
3  *
4  * Copyright (c) 2002 The Open For Business Project (www.ofbiz.org)
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included
13  * in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
20  * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
21  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */

23 package org.ofbiz.product.product;
24
25 import java.sql.Timestamp JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.HashSet JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.List JavaDoc;
30 import java.util.Map JavaDoc;
31 import java.util.Set JavaDoc;
32 import java.util.Locale JavaDoc;
33
34 import org.ofbiz.base.util.Debug;
35 import org.ofbiz.base.util.StringUtil;
36 import org.ofbiz.base.util.UtilDateTime;
37 import org.ofbiz.base.util.UtilMisc;
38 import org.ofbiz.base.util.UtilProperties;
39 import org.ofbiz.base.util.UtilValidate;
40 import org.ofbiz.base.util.string.FlexibleStringExpander;
41 import org.ofbiz.entity.GenericDelegator;
42 import org.ofbiz.entity.GenericEntityException;
43 import org.ofbiz.entity.GenericPK;
44 import org.ofbiz.entity.GenericValue;
45 import org.ofbiz.entity.condition.EntityCondition;
46 import org.ofbiz.entity.condition.EntityConditionList;
47 import org.ofbiz.entity.condition.EntityExpr;
48 import org.ofbiz.entity.condition.EntityOperator;
49 import org.ofbiz.entity.model.DynamicViewEntity;
50 import org.ofbiz.entity.model.ModelEntity;
51 import org.ofbiz.entity.model.ModelKeyMap;
52 import org.ofbiz.entity.util.EntityListIterator;
53 import org.ofbiz.entity.util.EntityUtil;
54 import org.ofbiz.service.DispatchContext;
55 import org.ofbiz.service.GenericServiceException;
56 import org.ofbiz.service.LocalDispatcher;
57 import org.ofbiz.service.ServiceUtil;
58
59 /**
60  * Product Services
61  *
62  * @author <a HREF="mailto:jaz@ofbiz.org">Andy Zeneski</a>
63  * @author <a HREF="mailto:jonesde@ofbiz.org">David E. Jones</a>
64  * @version $Rev: 5462 $
65  * @since 2.0
66  */

67 public class ProductUtilServices {
68
69     public static final String JavaDoc module = ProductUtilServices.class.getName();
70     public static final String JavaDoc resource = "ProductUiLabels";
71
72     /** First expirt all ProductAssocs for all disc variants, then disc all virtuals that have all expired variant ProductAssocs */
73     public static Map JavaDoc discVirtualsWithDiscVariants(DispatchContext dctx, Map JavaDoc context) {
74         GenericDelegator delegator = dctx.getDelegator();
75         Timestamp JavaDoc nowTimestamp = UtilDateTime.nowTimestamp();
76         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
77         String JavaDoc errMsg = null;
78
79         try {
80             EntityCondition conditionOne = new EntityConditionList(UtilMisc.toList(
81                     new EntityExpr("isVariant", EntityOperator.EQUALS, "Y"),
82                     new EntityExpr("salesDiscontinuationDate", EntityOperator.NOT_EQUAL, null),
83                     new EntityExpr("salesDiscontinuationDate", EntityOperator.LESS_THAN_EQUAL_TO, nowTimestamp)
84                     ), EntityOperator.AND);
85             EntityListIterator eliOne = delegator.findListIteratorByCondition("Product", conditionOne, null, null);
86             GenericValue productOne = null;
87             int numSoFarOne = 0;
88             while ((productOne = (GenericValue) eliOne.next()) != null) {
89                 String JavaDoc virtualProductId = ProductWorker.getVariantVirtualId(productOne);
90                 GenericValue virtualProduct = delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", virtualProductId));
91                 if (virtualProduct == null) {
92                     continue;
93                 }
94                 List JavaDoc passocList = delegator.findByAnd("ProductAssoc", UtilMisc.toMap("productId", virtualProductId, "productIdTo", productOne.get("productId"), "productAssocTypeId", "PRODUCT_VARIANT"));
95                 passocList = EntityUtil.filterByDate(passocList, nowTimestamp);
96                 if (passocList.size() > 0) {
97                     Iterator JavaDoc passocIter = passocList.iterator();
98                     while (passocIter.hasNext()) {
99                         GenericValue passoc = (GenericValue) passocIter.next();
100                         passoc.set("thruDate", nowTimestamp);
101                         passoc.store();
102                     }
103
104                     numSoFarOne++;
105                     if (numSoFarOne % 500 == 0) {
106                         Debug.logInfo("Expired variant ProductAssocs for " + numSoFarOne + " sales discontinued variant products.", module);
107                     }
108                 }
109             }
110             eliOne.close();
111
112             // get all non-discontinued virtuals, see if all variant ProductAssocs are expired, if discontinue
113
EntityCondition condition = new EntityConditionList(UtilMisc.toList(
114                     new EntityExpr("isVirtual", EntityOperator.EQUALS, "Y"),
115                     new EntityExpr(new EntityExpr("salesDiscontinuationDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr("salesDiscontinuationDate", EntityOperator.GREATER_THAN_EQUAL_TO, nowTimestamp))
116                     ), EntityOperator.AND);
117             EntityListIterator eli = delegator.findListIteratorByCondition("Product", condition, null, null);
118             GenericValue product = null;
119             int numSoFar = 0;
120             while ((product = (GenericValue) eli.next()) != null) {
121                 List JavaDoc passocList = delegator.findByAnd("ProductAssoc", UtilMisc.toMap("productId", product.get("productId"), "productAssocTypeId", "PRODUCT_VARIANT"));
122                 passocList = EntityUtil.filterByDate(passocList, nowTimestamp);
123                 if (passocList.size() == 0) {
124                     product.set("salesDiscontinuationDate", nowTimestamp);
125
126                     numSoFar++;
127                     if (numSoFar % 500 == 0) {
128                         Debug.logInfo("Sales discontinued " + numSoFar + " virtual products that have no valid variants.", module);
129                     }
130                 }
131             }
132             eli.close();
133         } catch (GenericEntityException e) {
134             Map JavaDoc messageMap = UtilMisc.toMap("errMessage", e.toString());
135             errMsg = UtilProperties.getMessage(resource,"productutilservices.entity_error_running_discVirtualsWithDiscVariants", messageMap, locale);
136             Debug.logError(e, errMsg, module);
137             return ServiceUtil.returnError(errMsg);
138         }
139
140         return ServiceUtil.returnSuccess();
141     }
142
143     /** for all disc products, remove from category memberships */
144     public static Map JavaDoc removeCategoryMembersOfDiscProducts(DispatchContext dctx, Map JavaDoc context) {
145         GenericDelegator delegator = dctx.getDelegator();
146         Timestamp JavaDoc nowTimestamp = UtilDateTime.nowTimestamp();
147         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
148         String JavaDoc errMsg = null;
149
150         try {
151             EntityCondition condition = new EntityConditionList(UtilMisc.toList(
152                     new EntityExpr("salesDiscontinuationDate", EntityOperator.NOT_EQUAL, null),
153                     new EntityExpr("salesDiscontinuationDate", EntityOperator.LESS_THAN_EQUAL_TO, nowTimestamp)
154                     ), EntityOperator.AND);
155             EntityListIterator eli = delegator.findListIteratorByCondition("Product", condition, null, null);
156             GenericValue product = null;
157             int numSoFar = 0;
158             while ((product = (GenericValue) eli.next()) != null) {
159                 String JavaDoc productId = product.getString("productId");
160                 List JavaDoc productCategoryMemberList = delegator.findByAnd("ProductCategoryMember", UtilMisc.toMap("productId", productId));
161                 if (productCategoryMemberList.size() > 0) {
162                     Iterator JavaDoc productCategoryMemberIter = productCategoryMemberList.iterator();
163                     while (productCategoryMemberIter.hasNext()) {
164                         GenericValue productCategoryMember = (GenericValue) productCategoryMemberIter.next();
165                         // coded this way rather than a removeByAnd so it can be easily changed...
166
productCategoryMember.remove();
167                     }
168                     numSoFar++;
169                     if (numSoFar % 500 == 0) {
170                         Debug.logInfo("Removed category members for " + numSoFar + " sales discontinued products.", module);
171                     }
172                 }
173             }
174             eli.close();
175             Debug.logInfo("Completed - Removed category members for " + numSoFar + " sales discontinued products.", module);
176         } catch (GenericEntityException e) {
177             Map JavaDoc messageMap = UtilMisc.toMap("errMessage", e.toString());
178             errMsg = UtilProperties.getMessage(resource,"productutilservices.entity_error_running_removeCategoryMembersOfDiscProducts", messageMap, locale);
179             Debug.logError(e, errMsg, module);
180             return ServiceUtil.returnError(errMsg);
181         }
182
183         return ServiceUtil.returnSuccess();
184     }
185
186     public static Map JavaDoc removeDuplicateOpenEndedCategoryMembers(DispatchContext dctx, Map JavaDoc context) {
187         GenericDelegator delegator = dctx.getDelegator();
188         Timestamp JavaDoc nowTimestamp = UtilDateTime.nowTimestamp();
189         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
190         String JavaDoc errMsg = null;
191
192         try {
193             DynamicViewEntity dve = new DynamicViewEntity();
194             dve.addMemberEntity("PCM", "ProductCategoryMember");
195             dve.addAlias("PCM", "productId", null, null, null, Boolean.TRUE, null);
196             dve.addAlias("PCM", "productCategoryId", null, null, null, Boolean.TRUE, null);
197             dve.addAlias("PCM", "fromDate", null, null, null, null, null);
198             dve.addAlias("PCM", "thruDate", null, null, null, null, null);
199             dve.addAlias("PCM", "productIdCount", "productId", null, null, null, "count");
200
201             EntityCondition condition = new EntityConditionList(UtilMisc.toList(
202                     new EntityExpr("fromDate", EntityOperator.LESS_THAN, nowTimestamp),
203                     new EntityExpr("thruDate", EntityOperator.EQUALS, null)
204                     ), EntityOperator.AND);
205             EntityCondition havingCond = new EntityExpr("productIdCount", EntityOperator.GREATER_THAN, new Long JavaDoc(1));
206             EntityListIterator eli = delegator.findListIteratorByCondition(dve, condition, havingCond, UtilMisc.toList("productId", "productCategoryId", "productIdCount"), null, null);
207             GenericValue pcm = null;
208             int numSoFar = 0;
209             while ((pcm = (GenericValue) eli.next()) != null) {
210                 List JavaDoc productCategoryMemberList = delegator.findByAnd("ProductCategoryMember", UtilMisc.toMap("productId", pcm.get("productId"), "productCategoryId", pcm.get("productCategoryId")));
211                 if (productCategoryMemberList.size() > 1) {
212                     // remove all except the first...
213
productCategoryMemberList.remove(0);
214                     Iterator JavaDoc productCategoryMemberIter = productCategoryMemberList.iterator();
215                     while (productCategoryMemberIter.hasNext()) {
216                         GenericValue productCategoryMember = (GenericValue) productCategoryMemberIter.next();
217                         productCategoryMember.remove();
218                     }
219                     numSoFar++;
220                     if (numSoFar % 500 == 0) {
221                         Debug.logInfo("Removed category members for " + numSoFar + " products with duplicate category members.", module);
222                     }
223                 }
224             }
225             eli.close();
226             Debug.logInfo("Completed - Removed category members for " + numSoFar + " products with duplicate category members.", module);
227         } catch (GenericEntityException e) {
228             Map JavaDoc messageMap = UtilMisc.toMap("errMessage", e.toString());
229             errMsg = UtilProperties.getMessage(resource,"productutilservices.entity_error_running_removeDuplicateOpenEndedCategoryMembers", messageMap, locale);
230             Debug.logError(e, errMsg, module);
231             return ServiceUtil.returnError(errMsg);
232         }
233
234         return ServiceUtil.returnSuccess();
235     }
236
237     public static Map JavaDoc makeStandAloneFromSingleVariantVirtuals(DispatchContext dctx, Map JavaDoc context) {
238         GenericDelegator delegator = dctx.getDelegator();
239         LocalDispatcher dispatcher = dctx.getDispatcher();
240         GenericValue userLogin = (GenericValue) context.get("userLogin");
241         Timestamp JavaDoc nowTimestamp = UtilDateTime.nowTimestamp();
242         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
243         String JavaDoc errMsg = null;
244
245         Debug.logInfo("Starting makeStandAloneFromSingleVariantVirtuals", module);
246
247         DynamicViewEntity dve = new DynamicViewEntity();
248         dve.addMemberEntity("PVIRT", "Product");
249         dve.addMemberEntity("PVA", "ProductAssoc");
250         //dve.addMemberEntity("PVAR", "Product");
251
dve.addViewLink("PVIRT", "PVA", Boolean.FALSE, UtilMisc.toList(new ModelKeyMap("productId", "productId")));
252         //dve.addViewLink("PVA", "PVAR", Boolean.FALSE, UtilMisc.toList(new ModelKeyMap("productIdTo", "productId")));
253
dve.addAlias("PVIRT", "productId", null, null, null, Boolean.TRUE, null);
254         dve.addAlias("PVIRT", "salesDiscontinuationDate", null, null, null, null, null);
255         dve.addAlias("PVA", "productAssocTypeId", null, null, null, null, null);
256         dve.addAlias("PVA", "fromDate", null, null, null, null, null);
257         dve.addAlias("PVA", "thruDate", null, null, null, null, null);
258         dve.addAlias("PVA", "productIdToCount", "productIdTo", null, null, null, "count-distinct");
259         //dve.addAlias("PVAR", "variantProductId", "productId", null, null, null, null);
260

261         try {
262             EntityCondition condition = new EntityConditionList(UtilMisc.toList(
263                     new EntityExpr("productAssocTypeId", EntityOperator.EQUALS, "PRODUCT_VARIANT"),
264                     new EntityExpr(new EntityExpr("salesDiscontinuationDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr("salesDiscontinuationDate", EntityOperator.GREATER_THAN, nowTimestamp))
265                     ), EntityOperator.AND);
266             EntityCondition havingCond = new EntityExpr("productIdToCount", EntityOperator.EQUALS, new Long JavaDoc(1));
267             EntityListIterator eliOne = delegator.findListIteratorByCondition(dve, condition, havingCond, UtilMisc.toList("productId", "productIdToCount"), null, null);
268             List JavaDoc valueList = eliOne.getCompleteList();
269             eliOne.close();
270
271             Debug.logInfo("Found " + valueList.size() + " virtual products with one variant to turn into a stand alone product.", module);
272
273             int numWithOneOnly = 0;
274             Iterator JavaDoc valueIter = valueList.iterator();
275             while (valueIter.hasNext()) {
276                 // has only one variant period, is it valid? should already be discontinued if not
277
GenericValue value = (GenericValue) valueIter.next();
278
279                 String JavaDoc productId = value.getString("productId");
280                 List JavaDoc paList = delegator.findByAnd("ProductAssoc", UtilMisc.toMap("productId", productId, "productAssocTypeId", "PRODUCT_VARIANT"));
281                 // verify the query; tested on a bunch, looks good
282
if (paList.size() != 1) {
283                     Debug.logInfo("Virtual product with ID " + productId + " should have 1 assoc, has " + paList.size(), module);
284                 } else {
285                     //if (numWithOneOnly < 100) {
286
// Debug.logInfo("Virtual product ID to make stand-alone: " + productId, module);
287
//}
288
// for all virtuals with one variant move all info from virtual to variant and remove virtual, make variant as not a variant
289
dispatcher.runSync("mergeVirtualWithSingleVariant", UtilMisc.toMap("productId", productId, "removeOld", Boolean.TRUE, "userLogin", userLogin));
290
291                     numWithOneOnly++;
292                     if (numWithOneOnly % 100 == 0) {
293                         Debug.logInfo("Made " + numWithOneOnly + " virtual products with only one valid variant stand-alone products.", module);
294                     }
295                 }
296             }
297
298             EntityCondition conditionWithDates = new EntityConditionList(UtilMisc.toList(
299                     new EntityExpr("productAssocTypeId", EntityOperator.EQUALS, "PRODUCT_VARIANT"),
300                     new EntityExpr(new EntityExpr("salesDiscontinuationDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr("salesDiscontinuationDate", EntityOperator.GREATER_THAN, nowTimestamp)),
301                     new EntityExpr("fromDate", EntityOperator.LESS_THAN_EQUAL_TO, nowTimestamp),
302                     new EntityExpr(new EntityExpr("thruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr("thruDate", EntityOperator.GREATER_THAN_EQUAL_TO, nowTimestamp))
303                     ), EntityOperator.AND);
304             EntityListIterator eliMulti = delegator.findListIteratorByCondition(dve, conditionWithDates, havingCond, UtilMisc.toList("productId", "productIdToCount"), null, null);
305             List JavaDoc valueMultiList = eliMulti.getCompleteList();
306             eliMulti.close();
307
308             Debug.logInfo("Found " + valueMultiList.size() + " virtual products with one VALID variant to pull the variant from to make a stand alone product.", module);
309
310             int numWithOneValid = 0;
311             Iterator JavaDoc valueMultiIter = valueMultiList.iterator();
312             while (valueMultiIter.hasNext()) {
313                 GenericValue value = (GenericValue) valueMultiIter.next();
314                 // has only one valid variant
315
String JavaDoc productId = value.getString("productId");
316
317                 List JavaDoc paList = EntityUtil.filterByDate(delegator.findByAnd("ProductAssoc", UtilMisc.toMap("productId", productId, "productAssocTypeId", "PRODUCT_VARIANT")), nowTimestamp);
318
319                 // verify the query; tested on a bunch, looks good
320
if (paList.size() != 1) {
321                     Debug.logInfo("Virtual product with ID " + productId + " should have 1 assoc, has " + paList.size(), module);
322                 } else {
323                     // for all virtuals with one valid variant move info from virtual to variant, put variant in categories from virtual, remove virtual from all categories but leave "family" otherwise intact, mark variant as not a variant
324
dispatcher.runSync("mergeVirtualWithSingleVariant", UtilMisc.toMap("productId", productId, "removeOld", Boolean.FALSE, "userLogin", userLogin));
325
326                     numWithOneValid++;
327                     if (numWithOneValid % 100 == 0) {
328                         Debug.logInfo("Made " + numWithOneValid + " virtual products with one valid variant stand-alone products.", module);
329                     }
330                 }
331             }
332
333             Debug.logInfo("Found virtual products with one valid variant: " + numWithOneValid + ", with one variant only: " + numWithOneOnly, module);
334         } catch (GenericEntityException e) {
335             Map JavaDoc messageMap = UtilMisc.toMap("errMessage", e.toString());
336             errMsg = UtilProperties.getMessage(resource,"productutilservices.entity_error_running_makeStandAloneFromSingleVariantVirtuals", messageMap, locale);
337             Debug.logError(e, errMsg, module);
338             return ServiceUtil.returnError(errMsg);
339         } catch (GenericServiceException e) {
340             Map JavaDoc messageMap = UtilMisc.toMap("errMessage", e.toString());
341             errMsg = UtilProperties.getMessage(resource,"productutilservices.entity_error_running_makeStandAloneFromSingleVariantVirtuals", messageMap, locale);
342             Debug.logError(e, errMsg, module);
343             return ServiceUtil.returnError(errMsg);
344         }
345
346         return ServiceUtil.returnSuccess();
347     }
348
349     public static Map JavaDoc mergeVirtualWithSingleVariant(DispatchContext dctx, Map JavaDoc context) {
350         GenericDelegator delegator = dctx.getDelegator();
351         Timestamp JavaDoc nowTimestamp = UtilDateTime.nowTimestamp();
352
353         String JavaDoc productId = (String JavaDoc) context.get("productId");
354         Boolean JavaDoc removeOldBool = (Boolean JavaDoc) context.get("removeOld");
355         boolean removeOld = removeOldBool.booleanValue();
356         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
357         String JavaDoc errMsg = null;
358
359         Boolean JavaDoc testBool = (Boolean JavaDoc) context.get("test");
360         boolean test = false;
361         if (testBool != null) {
362             test = testBool.booleanValue();
363         }
364
365         try {
366             GenericValue product = delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", productId));
367             Debug.logInfo("Processing virtual product with one variant with ID: " + productId + " and name: " + product.getString("internalName"), module);
368
369             List JavaDoc paList = EntityUtil.filterByDate(delegator.findByAnd("ProductAssoc", UtilMisc.toMap("productId", productId, "productAssocTypeId", "PRODUCT_VARIANT")), nowTimestamp);
370             if (paList.size() > 1) {
371                 Map JavaDoc messageMap = UtilMisc.toMap("productId", productId);
372                 errMsg = UtilProperties.getMessage(resource,"productutilservices.found_more_than_one_valid_variant_for_virtual_ID", messageMap, locale);
373                 Debug.logInfo(errMsg, module);
374                 return ServiceUtil.returnError(errMsg);
375             }
376
377             if (paList.size() == 0) {
378                 Map JavaDoc messageMap = UtilMisc.toMap("productId", productId);
379                 errMsg = UtilProperties.getMessage(resource,"productutilservices.did_not_find_any_valid_variants_for_virtual_ID", messageMap, locale);
380                 Debug.logInfo(errMsg, module);
381                 return ServiceUtil.returnError(errMsg);
382             }
383
384             GenericValue productAssoc = EntityUtil.getFirst(paList);
385             if (removeOld) {
386                 // remove the productAssoc before getting down so it isn't copied over...
387
if (test) {
388                     Debug.logInfo("Test mode, would remove: " + productAssoc, module);
389                 } else {
390                     productAssoc.remove();
391                 }
392             } else {
393                 // don't remove, just expire to avoid running again in the future
394
productAssoc.set("thruDate", nowTimestamp);
395                 if (test) {
396                     Debug.logInfo("Test mode, would store: " + productAssoc, module);
397                 } else {
398                     productAssoc.store();
399                 }
400             }
401             String JavaDoc variantProductId = productAssoc.getString("productIdTo");
402
403             // Product
404
GenericValue variantProduct = delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", variantProductId));
405
406             Debug.logInfo("--variant has ID: " + variantProductId + " and name: " + variantProduct.getString("internalName"), module);
407
408             // start with the values from the virtual product, override from the variant...
409
GenericValue newVariantProduct = delegator.makeValue("Product", product);
410             newVariantProduct.setAllFields(variantProduct, false, "", null);
411             newVariantProduct.set("isVariant", "N");
412             if (test) {
413                 Debug.logInfo("Test mode, would store: " + newVariantProduct, module);
414             } else {
415                 newVariantProduct.store();
416             }
417
418             // ProductCategoryMember - always remove these to pull the virtual from any categories it might have been in
419
duplicateRelated(product, "", "ProductCategoryMember", "productId", variantProductId, nowTimestamp, true, delegator, test);
420
421             // ProductFeatureAppl
422
duplicateRelated(product, "", "ProductFeatureAppl", "productId", variantProductId, nowTimestamp, removeOld, delegator, test);
423
424             // ProductContent
425
duplicateRelated(product, "", "ProductContent", "productId", variantProductId, nowTimestamp, removeOld, delegator, test);
426
427             // ProductPrice
428
duplicateRelated(product, "", "ProductPrice", "productId", variantProductId, nowTimestamp, removeOld, delegator, test);
429
430             // GoodIdentification
431
duplicateRelated(product, "", "GoodIdentification", "productId", variantProductId, nowTimestamp, removeOld, delegator, test);
432
433             // ProductAttribute
434
duplicateRelated(product, "", "ProductAttribute", "productId", variantProductId, nowTimestamp, removeOld, delegator, test);
435
436             // ProductAssoc
437
duplicateRelated(product, "Main", "ProductAssoc", "productId", variantProductId, nowTimestamp, removeOld, delegator, test);
438             duplicateRelated(product, "Assoc", "ProductAssoc", "productIdTo", variantProductId, nowTimestamp, removeOld, delegator, test);
439
440             if (removeOld) {
441                 if (test) {
442                     Debug.logInfo("Test mode, would remove related ProductKeyword with dummy key: " + product.getRelatedDummyPK("ProductKeyword"), module);
443                     Debug.logInfo("Test mode, would remove: " + product, module);
444                 } else {
445                     product.removeRelated("ProductKeyword");
446                     product.remove();
447                 }
448             }
449
450             if (test) {
451                 return ServiceUtil.returnError("Test mode - returning error to get a rollback");
452             }
453         } catch (GenericEntityException e) {
454             Map JavaDoc messageMap = UtilMisc.toMap("errMessage", e.toString());
455             errMsg = UtilProperties.getMessage(resource,"productutilservices.entity_error_running_makeStandAloneFromSingleVariantVirtuals", messageMap, locale);
456             Debug.logError(e, errMsg, module);
457             return ServiceUtil.returnError(errMsg);
458         }
459
460         return ServiceUtil.returnSuccess();
461     }
462
463     protected static void duplicateRelated(GenericValue product, String JavaDoc title, String JavaDoc relatedEntityName, String JavaDoc productIdField, String JavaDoc variantProductId, Timestamp JavaDoc nowTimestamp, boolean removeOld, GenericDelegator delegator, boolean test) throws GenericEntityException {
464         List JavaDoc relatedList = EntityUtil.filterByDate(product.getRelated(title + relatedEntityName), nowTimestamp);
465         Iterator JavaDoc relatedIter = relatedList.iterator();
466         while (relatedIter.hasNext()) {
467             GenericValue relatedValue = (GenericValue) relatedIter.next();
468             GenericValue newRelatedValue = (GenericValue) relatedValue.clone();
469             newRelatedValue.set(productIdField, variantProductId);
470
471             // create a new one? see if one already exists with different from/thru dates
472
ModelEntity modelEntity = relatedValue.getModelEntity();
473             if (modelEntity.isField("fromDate")) {
474                 GenericPK findValue = newRelatedValue.getPrimaryKey();
475                 // can't just set to null, need to remove the value so it isn't a constraint in the query
476
//findValue.set("fromDate", null);
477
findValue.remove("fromDate");
478                 List JavaDoc existingValueList = EntityUtil.filterByDate(delegator.findByAnd(relatedEntityName, findValue), nowTimestamp);
479                 if (existingValueList.size() > 0) {
480                     if (test) {
481                         Debug.logInfo("Found " + existingValueList.size() + " existing values for related entity name: " + relatedEntityName + ", not copying, findValue is: " + findValue, module);
482                     }
483                     continue;
484                 }
485                 newRelatedValue.set("fromDate", nowTimestamp);
486             }
487
488             if (delegator.findCountByAnd(relatedEntityName, newRelatedValue.getPrimaryKey()) == 0) {
489                 if (test) {
490                     Debug.logInfo("Test mode, would create: " + newRelatedValue, module);
491                 } else {
492                     newRelatedValue.create();
493                 }
494             }
495         }
496         if (removeOld) {
497             if (test) {
498                 Debug.logInfo("Test mode, would remove related " + title + relatedEntityName + " with dummy key: " + product.getRelatedDummyPK(title + relatedEntityName), module);
499             } else {
500                 product.removeRelated(title + relatedEntityName);
501             }
502         }
503     }
504
505
506     /** reset all product image names with a certain pattern, ex: /images/products/${size}/${productId}.jpg
507      * NOTE: only works on fields of Product right now
508      */

509     public static Map JavaDoc setAllProductImageNames(DispatchContext dctx, Map JavaDoc context) {
510         GenericDelegator delegator = dctx.getDelegator();
511         Timestamp JavaDoc nowTimestamp = UtilDateTime.nowTimestamp();
512         String JavaDoc pattern = (String JavaDoc) context.get("pattern");
513         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
514         String JavaDoc errMsg = null;
515
516         if (UtilValidate.isEmpty(pattern)) {
517             String JavaDoc imageFilenameFormat = UtilProperties.getPropertyValue("catalog", "image.filename.format");
518             String JavaDoc imageUrlPrefix = UtilProperties.getPropertyValue("catalog", "image.url.prefix");
519             pattern = imageUrlPrefix + "/" + imageFilenameFormat;
520         }
521
522         try {
523             EntityListIterator eli = delegator.findListIteratorByCondition("Product", null, null, null);
524             GenericValue product = null;
525             int numSoFar = 0;
526             while ((product = (GenericValue) eli.next()) != null) {
527                 String JavaDoc productId = (String JavaDoc) product.get("productId");
528                 Map JavaDoc smallMap = UtilMisc.toMap("size", "small", "productId", productId);
529                 Map JavaDoc mediumMap = UtilMisc.toMap("size", "medium", "productId", productId);
530                 Map JavaDoc largeMap = UtilMisc.toMap("size", "large", "productId", productId);
531                 Map JavaDoc detailMap = UtilMisc.toMap("size", "detail", "productId", productId);
532
533                 if ("Y".equals(product.getString("isVirtual"))) {
534                     // find the first variant, use it's ID for the names...
535
List JavaDoc productAssocList = EntityUtil.filterByDate(delegator.findByAnd("ProductAssoc", UtilMisc.toMap("productId", productId, "productAssocTypeId", "PRODUCT_VARIANT")), nowTimestamp);
536                     if (productAssocList.size() > 0) {
537                         GenericValue productAssoc = EntityUtil.getFirst(productAssocList);
538                         smallMap.put("productId", productAssoc.get("productIdTo"));
539                         mediumMap.put("productId", productAssoc.get("productIdTo"));
540                         product.set("smallImageUrl", FlexibleStringExpander.expandString(pattern, smallMap));
541                         product.set("mediumImageUrl", FlexibleStringExpander.expandString(pattern, mediumMap));
542                     } else {
543                         product.set("smallImageUrl", null);
544                         product.set("mediumImageUrl", null);
545                     }
546                     product.set("largeImageUrl", null);
547                     product.set("detailImageUrl", null);
548                 } else {
549                     product.set("smallImageUrl", FlexibleStringExpander.expandString(pattern, smallMap));
550                     product.set("mediumImageUrl", FlexibleStringExpander.expandString(pattern, mediumMap));
551                     product.set("largeImageUrl", FlexibleStringExpander.expandString(pattern, largeMap));
552                     product.set("detailImageUrl", FlexibleStringExpander.expandString(pattern, detailMap));
553                 }
554
555                 product.store();
556                 numSoFar++;
557                 if (numSoFar % 500 == 0) {
558                     Debug.logInfo("Image URLs set for " + numSoFar + " products.", module);
559                 }
560             }
561             eli.close();
562             Debug.logInfo("Completed - Image URLs set for " + numSoFar + " products.", module);
563         } catch (GenericEntityException e) {
564             Map JavaDoc messageMap = UtilMisc.toMap("errMessage", e.toString());
565             errMsg = UtilProperties.getMessage(resource,"productutilservices.entity_error_running_setAllProductImageNames", messageMap, locale);
566             Debug.logError(e, errMsg, module);
567             return ServiceUtil.returnError(errMsg);
568         }
569
570         return ServiceUtil.returnSuccess();
571     }
572
573     public static Map JavaDoc clearAllVirtualProductImageNames(DispatchContext dctx, Map JavaDoc context) {
574         GenericDelegator delegator = dctx.getDelegator();
575         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
576         String JavaDoc errMsg = null;
577
578         try {
579             EntityListIterator eli = delegator.findListIteratorByCondition("Product", new EntityExpr("isVirtual", EntityOperator.EQUALS, "Y"), null, null);
580             GenericValue product = null;
581             int numSoFar = 0;
582             while ((product = (GenericValue) eli.next()) != null) {
583                 product.set("smallImageUrl", null);
584                 product.set("mediumImageUrl", null);
585                 product.set("largeImageUrl", null);
586                 product.set("detailImageUrl", null);
587                 product.store();
588                 numSoFar++;
589                 if (numSoFar % 500 == 0) {
590                     Debug.logInfo("Image URLs cleared for " + numSoFar + " products.", module);
591                 }
592             }
593             eli.close();
594             Debug.logInfo("Completed - Image URLs set for " + numSoFar + " products.", module);
595         } catch (GenericEntityException e) {
596             Map JavaDoc messageMap = UtilMisc.toMap("errMessage", e.toString());
597             errMsg = UtilProperties.getMessage(resource,"productutilservices.entity_error_running_clearAllVirtualProductImageNames", messageMap, locale);
598             Debug.logError(e, errMsg, module);
599             return ServiceUtil.returnError(errMsg);
600         }
601
602         return ServiceUtil.returnSuccess();
603     }
604
605     // set category descriptions from longDescriptions
606
/*
607 allCategories = delegator.findAll("ProductCategory");
608 allCatIter = allCategories.iterator();
609 while (allCatIter.hasNext()) {
610    cat = allCatIter.next();
611    if (UtilValidate.isEmpty(cat.getString("description"))) {
612        StringBuffer description = new StringBuffer(cat.getString("longDescription").toLowerCase());
613        description.setCharAt(0, Character.toUpperCase(description.charAt(0)));
614        for (int i=0; i<description.length() - 1; i++) {
615            if (description.charAt(i) == ' ') {
616                description.setCharAt(i+1, Character.toUpperCase(description.charAt(i+1)));
617            }
618        }
619        Debug.logInfo("new description: " + description, "ctc.bsh");
620               cat.put("description", description.toString());
621        cat.store();
622    }
623 }
624      */

625
626
627
628     public static Map JavaDoc attachProductFeaturesToCategory(DispatchContext dctx, Map JavaDoc context) {
629         GenericDelegator delegator = dctx.getDelegator();
630         String JavaDoc productCategoryId = (String JavaDoc) context.get("productCategoryId");
631         String JavaDoc doSubCategoriesStr = (String JavaDoc) context.get("doSubCategories");
632         Locale JavaDoc locale = (Locale JavaDoc) context.get("locale");
633         String JavaDoc errMsg = null;
634
635         // default to true
636
boolean doSubCategories = !"N".equals(doSubCategoriesStr);
637         Timestamp JavaDoc nowTimestamp = UtilDateTime.nowTimestamp();
638
639         Set JavaDoc productFeatureTypeIdsToExclude = new HashSet JavaDoc();
640         String JavaDoc excludeProp = UtilProperties.getPropertyValue("prodsearch", "attach.feature.type.exclude");
641         if (UtilValidate.isNotEmpty(excludeProp)) {
642             List JavaDoc typeList = StringUtil.split(excludeProp, ",");
643             productFeatureTypeIdsToExclude.addAll(typeList);
644         }
645
646         Set JavaDoc productFeatureTypeIdsToInclude = null;
647         String JavaDoc includeProp = UtilProperties.getPropertyValue("prodsearch", "attach.feature.type.include");
648         if (UtilValidate.isNotEmpty(includeProp)) {
649             List JavaDoc typeList = StringUtil.split(includeProp, ",");
650             if (typeList.size() > 0) {
651                 productFeatureTypeIdsToInclude = new HashSet JavaDoc(typeList);
652             }
653         }
654
655         try {
656             attachProductFeaturesToCategory(productCategoryId, productFeatureTypeIdsToInclude, productFeatureTypeIdsToExclude, delegator, doSubCategories, nowTimestamp);
657         } catch (GenericEntityException e) {
658             Map JavaDoc messageMap = UtilMisc.toMap("errMessage", e.toString());
659             errMsg = UtilProperties.getMessage(resource,"productutilservices.error_in_attachProductFeaturesToCategory", messageMap, locale);
660             Debug.logError(e, errMsg, module);
661             return ServiceUtil.returnError(errMsg);
662         }
663
664         return ServiceUtil.returnSuccess();
665     }
666
667     /** Get all features associated with products and associate them with a feature group attached to the category for each feature type;
668      * includes products associated with this category only, but will also associate all feature groups of sub-categories with this category, optionally calls this method for all sub-categories too
669      */

670     public static void attachProductFeaturesToCategory(String JavaDoc productCategoryId, Set JavaDoc productFeatureTypeIdsToInclude, Set JavaDoc productFeatureTypeIdsToExclude, GenericDelegator delegator, boolean doSubCategories, Timestamp JavaDoc nowTimestamp) throws GenericEntityException {
671         if (nowTimestamp == null) {
672             nowTimestamp = UtilDateTime.nowTimestamp();
673         }
674
675         // do sub-categories first so all feature groups will be in place
676
List JavaDoc subCategoryList = delegator.findByAnd("ProductCategoryRollup", UtilMisc.toMap("parentProductCategoryId", productCategoryId));
677         if (doSubCategories) {
678             Iterator JavaDoc subCategoryIter = subCategoryList.iterator();
679             while (subCategoryIter.hasNext()) {
680                 GenericValue productCategoryRollup = (GenericValue) subCategoryIter.next();
681                 attachProductFeaturesToCategory(productCategoryRollup.getString("productCategoryId"), productFeatureTypeIdsToInclude, productFeatureTypeIdsToExclude, delegator, true, nowTimestamp);
682             }
683         }
684
685         // now get all features for this category and make associated feature groups
686
Map JavaDoc productFeatureIdByTypeIdSetMap = new HashMap JavaDoc();
687         List JavaDoc productCategoryMemberList = delegator.findByAnd("ProductCategoryMember", UtilMisc.toMap("productCategoryId", productCategoryId));
688         Iterator JavaDoc productCategoryMemberIter = productCategoryMemberList.iterator();
689         while (productCategoryMemberIter.hasNext()) {
690             GenericValue productCategoryMember = (GenericValue) productCategoryMemberIter.next();
691             String JavaDoc productId = productCategoryMember.getString("productId");
692             EntityCondition condition = new EntityConditionList(UtilMisc.toList(
693                     new EntityExpr("productId", EntityOperator.EQUALS, productId),
694                     new EntityExpr("fromDate", EntityOperator.LESS_THAN_EQUAL_TO, nowTimestamp),
695                     new EntityExpr(new EntityExpr("thruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr("thruDate", EntityOperator.GREATER_THAN_EQUAL_TO, nowTimestamp))
696             ), EntityOperator.AND);
697             EntityListIterator productFeatureAndApplEli = delegator.findListIteratorByCondition("ProductFeatureAndAppl", condition, null, null);
698             GenericValue productFeatureAndAppl = null;
699             while ((productFeatureAndAppl = (GenericValue) productFeatureAndApplEli.next()) != null) {
700                 String JavaDoc productFeatureId = productFeatureAndAppl.getString("productFeatureId");
701                 String JavaDoc productFeatureTypeId = productFeatureAndAppl.getString("productFeatureTypeId");
702                 if (productFeatureTypeIdsToInclude != null && productFeatureTypeIdsToInclude.size() > 0 && !productFeatureTypeIdsToInclude.contains(productFeatureTypeId)) {
703                     continue;
704                 }
705                 if (productFeatureTypeIdsToExclude != null && productFeatureTypeIdsToExclude.contains(productFeatureTypeId)) {
706                     continue;
707                 }
708                 Set JavaDoc productFeatureIdSet = (Set JavaDoc) productFeatureIdByTypeIdSetMap.get(productFeatureTypeId);
709                 if (productFeatureIdSet == null) {
710                     productFeatureIdSet = new HashSet JavaDoc();
711                     productFeatureIdByTypeIdSetMap.put(productFeatureTypeId, productFeatureIdSet);
712                 }
713                 productFeatureIdSet.add(productFeatureId);
714             }
715             productFeatureAndApplEli.close();
716         }
717
718         Iterator JavaDoc productFeatureIdByTypeIdSetIter = productFeatureIdByTypeIdSetMap.entrySet().iterator();
719         while (productFeatureIdByTypeIdSetIter.hasNext()) {
720             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) productFeatureIdByTypeIdSetIter.next();
721             String JavaDoc productFeatureTypeId = (String JavaDoc) entry.getKey();
722             Set JavaDoc productFeatureIdSet = (Set JavaDoc) entry.getValue();
723
724             String JavaDoc productFeatureGroupId = productCategoryId + "_" + productFeatureTypeId;
725             if (productFeatureGroupId.length() > 20) {
726                 Debug.logWarning("Manufactured productFeatureGroupId was greater than 20 characters, means that we had some long productCategoryId and/or productFeatureTypeId values, at the category part should be unique since it is first, so if the feature type isn't unique it just means more than one type of feature will go into the category...", module);
727                 productFeatureGroupId = productFeatureGroupId.substring(0, 20);
728             }
729
730             GenericValue productFeatureGroup = delegator.findByPrimaryKey("ProductFeatureGroup", UtilMisc.toMap("productFeatureGroupId", productFeatureGroupId));
731             if (productFeatureGroup == null) {
732                 // auto-create the group
733
String JavaDoc description = "Feature Group for type [" + productFeatureTypeId + "] features in category [" + productCategoryId + "]";
734                 productFeatureGroup = delegator.makeValue("ProductFeatureGroup", UtilMisc.toMap("productFeatureGroupId", productFeatureGroupId, "description", description));
735                 productFeatureGroup.create();
736
737                 GenericValue productFeatureCatGrpAppl = delegator.makeValue("ProductFeatureCatGrpAppl", UtilMisc.toMap("productFeatureGroupId", productFeatureGroupId, "productCategoryId", productCategoryId, "fromDate", nowTimestamp));
738                 productFeatureCatGrpAppl.create();
739             }
740
741             // now put all of the features in the group, if there is not already a valid feature placement there...
742
Iterator JavaDoc productFeatureIdIter = productFeatureIdSet.iterator();
743             while (productFeatureIdIter.hasNext()) {
744                 String JavaDoc productFeatureId = (String JavaDoc) productFeatureIdIter.next();
745                 EntityCondition condition = new EntityConditionList(UtilMisc.toList(
746                         new EntityExpr("productFeatureId", EntityOperator.EQUALS, productFeatureId),
747                         new EntityExpr("productFeatureGroupId", EntityOperator.EQUALS, productFeatureGroupId),
748                         new EntityExpr("fromDate", EntityOperator.LESS_THAN_EQUAL_TO, nowTimestamp),
749                         new EntityExpr(new EntityExpr("thruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr("thruDate", EntityOperator.GREATER_THAN_EQUAL_TO, nowTimestamp))
750                 ), EntityOperator.AND);
751                 if (delegator.findCountByCondition("ProductFeatureGroupAppl", condition, null) == 0) {
752                     // if no valid ones, create one
753
GenericValue productFeatureGroupAppl = delegator.makeValue("ProductFeatureGroupAppl", UtilMisc.toMap("productFeatureGroupId", productFeatureGroupId, "productFeatureId", productFeatureId, "fromDate", nowTimestamp));
754                     productFeatureGroupAppl.create();
755                 }
756             }
757         }
758
759         // now get all feature groups associated with sub-categories and associate them with this category
760
Iterator JavaDoc subCategoryIter = subCategoryList.iterator();
761         while (subCategoryIter.hasNext()) {
762             GenericValue productCategoryRollup = (GenericValue) subCategoryIter.next();
763             String JavaDoc subProductCategoryId = productCategoryRollup.getString("productCategoryId");
764             EntityCondition condition = new EntityConditionList(UtilMisc.toList(
765                     new EntityExpr("productCategoryId", EntityOperator.EQUALS, subProductCategoryId),
766                     new EntityExpr("fromDate", EntityOperator.LESS_THAN_EQUAL_TO, nowTimestamp),
767                     new EntityExpr(new EntityExpr("thruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr("thruDate", EntityOperator.GREATER_THAN_EQUAL_TO, nowTimestamp))
768             ), EntityOperator.AND);
769             EntityListIterator productFeatureCatGrpApplEli = delegator.findListIteratorByCondition("ProductFeatureCatGrpAppl", condition, null, null);
770             GenericValue productFeatureCatGrpAppl = null;
771             while ((productFeatureCatGrpAppl = (GenericValue) productFeatureCatGrpApplEli.next()) != null) {
772                 String JavaDoc productFeatureGroupId = productFeatureCatGrpAppl.getString("productFeatureGroupId");
773                 EntityCondition checkCondition = new EntityConditionList(UtilMisc.toList(
774                         new EntityExpr("productCategoryId", EntityOperator.EQUALS, productCategoryId),
775                         new EntityExpr("productFeatureGroupId", EntityOperator.EQUALS, productFeatureGroupId),
776                         new EntityExpr("fromDate", EntityOperator.LESS_THAN_EQUAL_TO, nowTimestamp),
777                         new EntityExpr(new EntityExpr("thruDate", EntityOperator.EQUALS, null), EntityOperator.OR, new EntityExpr("thruDate", EntityOperator.GREATER_THAN_EQUAL_TO, nowTimestamp))
778                 ), EntityOperator.AND);
779                 if (delegator.findCountByCondition("ProductFeatureCatGrpAppl", checkCondition, null) == 0) {
780                     // if no valid ones, create one
781
GenericValue productFeatureGroupAppl = delegator.makeValue("ProductFeatureCatGrpAppl", UtilMisc.toMap("productFeatureGroupId", productFeatureGroupId, "productCategoryId", productCategoryId, "fromDate", nowTimestamp));
782                     productFeatureGroupAppl.create();
783                 }
784             }
785             productFeatureCatGrpApplEli.close();
786         }
787     }
788
789     public static Map JavaDoc removeAllFeatureGroupsForCategory(DispatchContext dctx, Map JavaDoc context) {
790         return ServiceUtil.returnSuccess();
791     }
792
793     public static void getFeatureGroupsForCategory(String JavaDoc productCategoryId, Set JavaDoc productFeatureGroupIdsToRemove, GenericDelegator delegator, boolean doSubCategories, Timestamp JavaDoc nowTimestamp) throws GenericEntityException {
794
795     }
796 }
797
798
Popular Tags