KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * $Id: ProductServices.java 6249 2005-12-06 00:28:19Z jaz $
3  *
4  * Copyright (c) 2002-2004 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.*;
27
28 import org.apache.commons.collections.map.LinkedMap;
29 import org.apache.commons.collections.set.ListOrderedSet;
30
31 import org.ofbiz.base.util.Debug;
32 import org.ofbiz.base.util.UtilDateTime;
33 import org.ofbiz.base.util.UtilMisc;
34 import org.ofbiz.base.util.UtilProperties;
35 import org.ofbiz.base.util.UtilValidate;
36 import org.ofbiz.entity.GenericDelegator;
37 import org.ofbiz.entity.GenericEntityException;
38 import org.ofbiz.entity.GenericValue;
39 import org.ofbiz.entity.util.EntityUtil;
40 import org.ofbiz.product.catalog.CatalogWorker;
41 import org.ofbiz.product.category.CategoryWorker;
42 import org.ofbiz.service.DispatchContext;
43 import org.ofbiz.service.GenericServiceException;
44 import org.ofbiz.service.LocalDispatcher;
45 import org.ofbiz.service.ModelService;
46 import org.ofbiz.service.ServiceUtil;
47
48 /**
49  * Product Services
50  *
51  * @author <a HREF="mailto:jaz@ofbiz.org">Andy Zeneski</a>
52  * @author <a HREF="mailto:jonesde@ofbiz.org">David E. Jones</a>
53  * @version $Rev: 6249 $
54  * @since 2.0
55  */

56 public class ProductServices {
57
58     public static final String JavaDoc module = ProductServices.class.getName();
59     public static final String JavaDoc resource = "ProductUiLabels";
60
61     /**
62      * Creates a Collection of product entities which are variant products from the specified product ID.
63      */

64     public static Map prodFindAllVariants(DispatchContext dctx, Map context) {
65         // * String productId -- Parent (virtual) product ID
66
context.put("type", "PRODUCT_VARIANT");
67         return prodFindAssociatedByType(dctx, context);
68     }
69
70     /**
71      * Finds a specific product or products which contain the selected features.
72      */

73     public static Map prodFindSelectedVariant(DispatchContext dctx, Map context) {
74         // * String productId -- Parent (virtual) product ID
75
// * Map selectedFeatures -- Selected features
76
GenericDelegator delegator = dctx.getDelegator();
77         Locale locale = (Locale) context.get("locale");
78         String JavaDoc productId = (String JavaDoc) context.get("productId");
79         Map selectedFeatures = (Map) context.get("selectedFeatures");
80         ArrayList products = new ArrayList();
81         // All the variants for this products are retrieved
82
Map resVariants = prodFindAllVariants(dctx, context);
83         List variants = (List)resVariants.get("assocProducts");
84         GenericValue oneVariant = null;
85         Iterator variantsIt = variants.iterator();
86         while (variantsIt.hasNext()) {
87             // For every variant, all the standard features are retrieved
88
oneVariant = (GenericValue)variantsIt.next();
89             Map feaContext = new HashMap();
90             feaContext.put("productId", oneVariant.get("productIdTo"));
91             feaContext.put("type", "STANDARD_FEATURE");
92             Map resFeatures = prodGetFeatures(dctx, feaContext);
93             List features = (List)resFeatures.get("productFeatures");
94             Iterator featuresIt = features.iterator();
95             GenericValue oneFeature = null;
96             boolean variantFound = true;
97             // The variant is discarded if at least one of its standard features
98
// has the same type of one of the selected features but a different feature id.
99
// Example:
100
// Input: (COLOR, Black), (SIZE, Small)
101
// Variant1: (COLOR, Black), (SIZE, Large) --> nok
102
// Variant2: (COLOR, Black), (SIZE, Small) --> ok
103
// Variant3: (COLOR, Black), (SIZE, Small), (IMAGE, SkyLine) --> ok
104
// Variant4: (COLOR, Black), (IMAGE, SkyLine) --> ok
105
while (featuresIt.hasNext()) {
106                 oneFeature = (GenericValue)featuresIt.next();
107                 if (selectedFeatures.containsKey(oneFeature.getString("productFeatureTypeId"))) {
108                     if (!selectedFeatures.containsValue(oneFeature.getString("productFeatureId"))) {
109                         variantFound = false;
110                         break;
111                     }
112                 }
113             }
114             if (variantFound) {
115                 try {
116                     products.add(delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", oneVariant.getString("productIdTo"))));
117                 } catch (GenericEntityException e) {
118                     Map messageMap = UtilMisc.toMap("errProductFeatures", e.toString());
119                     String JavaDoc errMsg = UtilProperties.getMessage(resource,"productservices.problem_reading_product_features_errors", messageMap, locale);
120                     Debug.logError(e, errMsg, module);
121                     return ServiceUtil.returnError(errMsg);
122                 }
123             }
124         }
125
126         Map result = ServiceUtil.returnSuccess();
127         result.put("products", products);
128         return result;
129     }
130
131     /**
132      * Finds product variants based on a product ID and a distinct feature.
133      */

134     public static Map prodFindDistinctVariants(DispatchContext dctx, Map context) {
135         // * String productId -- Parent (virtual) product ID
136
// * String feature -- Distinct feature name
137
GenericDelegator delegator = dctx.getDelegator();
138         String JavaDoc productId = (String JavaDoc) context.get("productId");
139         String JavaDoc feature = (String JavaDoc) context.get("feature");
140
141         return ServiceUtil.returnError("This service has not yet been implemented.");
142     }
143
144     /**
145      * Finds a Set of feature types in sequence.
146      */

147     public static Map prodFindFeatureTypes(DispatchContext dctx, Map context) {
148         // * String productId -- Product ID to look up feature types
149
GenericDelegator delegator = dctx.getDelegator();
150         String JavaDoc productId = (String JavaDoc) context.get("productId");
151         Locale locale = (Locale) context.get("locale");
152         String JavaDoc errMsg=null;
153         Set featureSet = new ListOrderedSet();
154
155         try {
156             Map fields = UtilMisc.toMap("productId", productId, "productFeatureApplTypeId", "SELECTABLE_FEATURE");
157             List order = UtilMisc.toList("sequenceNum", "productFeatureTypeId");
158             List features = delegator.findByAndCache("ProductFeatureAndAppl", fields, order);
159             Iterator i = features.iterator();
160             while (i.hasNext()) {
161                 featureSet.add(((GenericValue) i.next()).getString("productFeatureTypeId"));
162             }
163             //if (Debug.infoOn()) Debug.logInfo("" + featureSet, module);
164
} catch (GenericEntityException e) {
165             Map messageMap = UtilMisc.toMap("errProductFeatures", e.toString());
166             errMsg = UtilProperties.getMessage(resource,"productservices.problem_reading_product_features_errors", messageMap, locale);
167             Debug.logError(e, errMsg, module);
168             return ServiceUtil.returnError(errMsg);
169         }
170
171         if (featureSet.size() == 0) {
172             errMsg = UtilProperties.getMessage(resource,"productservices.problem_reading_product_features", locale);
173             // ToDo DO 2004-02-23 Where should the errMsg go?
174
Debug.logWarning(errMsg + " for product " + productId, module);
175             //return ServiceUtil.returnError(errMsg);
176
}
177         Map result = ServiceUtil.returnSuccess();
178         result.put("featureSet", featureSet);
179         return result;
180     }
181
182     /**
183      * Builds a variant feature tree.
184      */

185     public static Map prodMakeFeatureTree(DispatchContext dctx, Map context) {
186         // * String productId -- Parent (virtual) product ID
187
// * List featureOrder -- Order of features
188
// * String productStoreId -- Product Store ID for Inventory
189
String JavaDoc productStoreId = (String JavaDoc) context.get("productStoreId");
190         Locale locale = (Locale) context.get("locale");
191
192         GenericDelegator delegator = dctx.getDelegator();
193         LocalDispatcher dispatcher = dctx.getDispatcher();
194         Map result = new HashMap();
195         List featureOrder = new LinkedList((Collection) context.get("featureOrder"));
196
197         if (featureOrder == null || featureOrder.size() == 0) {
198             return ServiceUtil.returnError("Empty list of features passed");
199         }
200
201         Collection variants = (Collection) prodFindAllVariants(dctx, context).get("assocProducts");
202         List virtualVariant = new ArrayList();
203
204         if (variants == null || variants.size() == 0) {
205             return ServiceUtil.returnSuccess();
206         }
207         List items = new ArrayList();
208         Iterator i = variants.iterator();
209
210         while (i.hasNext()) {
211             String JavaDoc productIdTo = (String JavaDoc) ((GenericValue) i.next()).get("productIdTo");
212
213             // first check to see if intro and discontinue dates are within range
214
GenericValue productTo = null;
215
216             try {
217                 productTo = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", productIdTo));
218             } catch (GenericEntityException e) {
219                 Debug.logError(e, module);
220                 Map messageMap = UtilMisc.toMap("productIdTo", productIdTo, "errMessage", e.toString());
221                 return ServiceUtil.returnError(UtilProperties.getMessage(resource, "productservices.error_finding_associated_variant_with_ID_error", messageMap, locale));
222             }
223             if (productTo == null) {
224                 Debug.logWarning("Could not find associated variant with ID " + productIdTo + ", not showing in list", module);
225                 continue;
226             }
227
228             java.sql.Timestamp JavaDoc nowTimestamp = UtilDateTime.nowTimestamp();
229
230             // check to see if introductionDate hasn't passed yet
231
if (productTo.get("introductionDate") != null && nowTimestamp.before(productTo.getTimestamp("introductionDate"))) {
232                 if (Debug.verboseOn()) {
233                     String JavaDoc excMsg = "Tried to view the Product " + productTo.getString("productName") +
234                         " (productId: " + productTo.getString("productId") + ") as a variant. This product has not yet been made available for sale, so not adding for view.";
235
236                     Debug.logVerbose(excMsg, module);
237                 }
238                 continue;
239             }
240
241             // check to see if salesDiscontinuationDate has passed
242
if (productTo.get("salesDiscontinuationDate") != null && nowTimestamp.after(productTo.getTimestamp("salesDiscontinuationDate"))) {
243                 if (Debug.verboseOn()) {
244                     String JavaDoc excMsg = "Tried to view the Product " + productTo.getString("productName") +
245                         " (productId: " + productTo.getString("productId") + ") as a variant. This product is no longer available for sale, so not adding for view.";
246
247                     Debug.logVerbose(excMsg, module);
248                 }
249                 continue;
250             }
251
252             // next check inventory for each item: if inventory is not required or is available
253
try {
254                 Map invReqResult = dispatcher.runSync("isStoreInventoryAvailableOrNotRequired", UtilMisc.toMap("productStoreId", productStoreId, "productId", productIdTo, "quantity", new Double JavaDoc(1.0)));
255                 if (ServiceUtil.isError(invReqResult)) {
256                     return ServiceUtil.returnError("Error calling the isStoreInventoryRequired when building the variant product tree.", null, null, invReqResult);
257                 } else if ("Y".equals((String JavaDoc) invReqResult.get("availableOrNotRequired"))) {
258                     items.add(productIdTo);
259                     if (productTo.getString("isVirtual") != null && productTo.getString("isVirtual").equals("Y")) {
260                         virtualVariant.add(productIdTo);
261                     }
262                 }
263             } catch (GenericServiceException e) {
264                 String JavaDoc errMsg = "Error calling the isStoreInventoryRequired when building the variant product tree: " + e.toString();
265                 Debug.logError(e, errMsg, module);
266                 return ServiceUtil.returnError(errMsg);
267             }
268         }
269
270         String JavaDoc productId = (String JavaDoc) context.get("productId");
271
272         // Make the selectable feature list
273
List selectableFeatures = null;
274         try {
275             Map fields = UtilMisc.toMap("productId", productId, "productFeatureApplTypeId", "SELECTABLE_FEATURE");
276             List sort = UtilMisc.toList("sequenceNum");
277
278             selectableFeatures = delegator.findByAndCache("ProductFeatureAndAppl", fields, sort);
279             selectableFeatures = EntityUtil.filterByDate(selectableFeatures, true);
280         } catch (GenericEntityException e) {
281             Debug.logError(e, module);
282             return ServiceUtil.returnError(UtilProperties.getMessage(resource,"productservices.empty_list_of_selectable_features_found", locale));
283         }
284         Map features = new HashMap();
285         Iterator sFIt = selectableFeatures.iterator();
286
287         while (sFIt.hasNext()) {
288             GenericValue v = (GenericValue) sFIt.next();
289             String JavaDoc featureType = v.getString("productFeatureTypeId");
290             String JavaDoc feature = v.getString("description");
291
292             if (!features.containsKey(featureType)) {
293                 List featureList = new LinkedList();
294                 featureList.add(feature);
295                 features.put(featureType, featureList);
296             } else {
297                 List featureList = (LinkedList) features.get(featureType);
298                 featureList.add(feature);
299                 features.put(featureType, featureList);
300             }
301         }
302
303         Map tree = null;
304         try {
305             tree = makeGroup(delegator, features, items, featureOrder, 0);
306         } catch (Exception JavaDoc e) {
307             Debug.logError(e, module);
308             return ServiceUtil.returnError(e.getMessage());
309         }
310         if (tree == null || tree.size() == 0) {
311             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
312             result.put(ModelService.ERROR_MESSAGE, UtilProperties.getMessage(resource,"productservices.feature_grouping_came_back_empty", locale));
313         } else {
314             result.put("variantTree", tree);
315             result.put("virtualVariant", virtualVariant);
316             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
317         }
318
319         Map sample = null;
320         try {
321             sample = makeVariantSample(dctx.getDelegator(), features, items, (String JavaDoc) featureOrder.get(0));
322         } catch (Exception JavaDoc e) {
323             return ServiceUtil.returnError(e.getMessage());
324         }
325         
326         if (sample == null || sample.size() == 0) {
327             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
328             result.put(ModelService.ERROR_MESSAGE, UtilProperties.getMessage(resource,"productservices.feature_sample_came_back_empty", locale));
329         } else {
330             result.put("variantSample", sample);
331             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
332         }
333
334         return result;
335     }
336
337     /**
338      * Gets the product features of a product.
339      */

340     public static Map prodGetFeatures(DispatchContext dctx, Map context) {
341         // * String productId -- Product ID to fond
342
// * String type -- Type of feature (STANDARD_FEATURE, SELECTABLE_FEATURE)
343
// * String distinct -- Distinct feature (SIZE, COLOR)
344
GenericDelegator delegator = dctx.getDelegator();
345         Map result = new HashMap();
346         String JavaDoc productId = (String JavaDoc) context.get("productId");
347         String JavaDoc distinct = (String JavaDoc) context.get("distinct");
348         String JavaDoc type = (String JavaDoc) context.get("type");
349         Locale locale = (Locale) context.get("locale");
350         String JavaDoc errMsg=null;
351         Collection features = null;
352
353         try {
354             Map fields = UtilMisc.toMap("productId", productId);
355             List order = UtilMisc.toList("sequenceNum", "productFeatureTypeId");
356
357             if (distinct != null) fields.put("productFeatureTypeId", distinct);
358             if (type != null) fields.put("productFeatureApplTypeId", type);
359             features = delegator.findByAndCache("ProductFeatureAndAppl", fields, order);
360             result.put("productFeatures", features);
361             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
362         } catch (GenericEntityException e) {
363             Map messageMap = UtilMisc.toMap("errMessage", e.toString());
364             errMsg = UtilProperties.getMessage(resource,"productservices.problem_reading_product_feature_entity", messageMap, locale);
365             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
366             result.put(ModelService.ERROR_MESSAGE, errMsg);
367         }
368         return result;
369     }
370
371     /**
372      * Finds a product by product ID.
373      */

374     public static Map prodFindProduct(DispatchContext dctx, Map context) {
375         // * String productId -- Product ID to find
376
GenericDelegator delegator = dctx.getDelegator();
377         Map result = new HashMap();
378         String JavaDoc productId = (String JavaDoc) context.get("productId");
379         Locale locale = (Locale) context.get("locale");
380         String JavaDoc errMsg = null;
381
382         if (productId == null || productId.length() == 0) {
383             errMsg = UtilProperties.getMessage(resource,"productservices.invalid_productId_passed", locale);
384             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
385             result.put(ModelService.ERROR_MESSAGE, errMsg);
386             return result;
387         }
388
389         try {
390             GenericValue product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", productId));
391             GenericValue mainProduct = product;
392
393             if (product.get("isVariant") != null && product.getString("isVariant").equalsIgnoreCase("Y")) {
394                 List c = product.getRelatedByAndCache("AssocProductAssoc",
395                         UtilMisc.toMap("productAssocTypeId", "PRODUCT_VARIANT"));
396
397                 if (c != null) {
398                     //if (Debug.infoOn()) Debug.logInfo("Found related: " + c, module);
399
c = EntityUtil.filterByDate(c, true);
400                     //if (Debug.infoOn()) Debug.logInfo("Found Filtered related: " + c, module);
401
if (c.size() > 0) {
402                         GenericValue asV = (GenericValue) c.iterator().next();
403
404                         //if (Debug.infoOn()) Debug.logInfo("ASV: " + asV, module);
405
mainProduct = asV.getRelatedOneCache("MainProduct");
406                         //if (Debug.infoOn()) Debug.logInfo("Main product = " + mainProduct, module);
407
}
408                 }
409             }
410             result.put("product", mainProduct);
411             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
412         } catch (GenericEntityException e) {
413             e.printStackTrace();
414             Map messageMap = UtilMisc.toMap("errMessage", e.getMessage());
415             errMsg = UtilProperties.getMessage(resource,"productservices.problems_reading_product_entity", messageMap, locale);
416             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
417             result.put(ModelService.ERROR_MESSAGE, errMsg);
418         }
419
420         return result;
421     }
422
423     /**
424      * Finds associated products by product ID and association ID.
425      */

426     public static Map prodFindAssociatedByType(DispatchContext dctx, Map context) {
427         // * String productId -- Current Product ID
428
// * String type -- Type of association (ie PRODUCT_UPGRADE, PRODUCT_COMPLEMENT, PRODUCT_VARIANT)
429
GenericDelegator delegator = dctx.getDelegator();
430         Map result = new HashMap();
431         String JavaDoc productId = (String JavaDoc) context.get("productId");
432         String JavaDoc productIdTo = (String JavaDoc) context.get("productIdTo");
433         String JavaDoc type = (String JavaDoc) context.get("type");
434         Locale locale = (Locale) context.get("locale");
435         String JavaDoc errMsg = null;
436
437         Boolean JavaDoc cvaBool = (Boolean JavaDoc) context.get("checkViewAllow");
438         boolean checkViewAllow = (cvaBool == null ? false : cvaBool.booleanValue());
439         String JavaDoc prodCatalogId = (String JavaDoc) context.get("prodCatalogId");
440
441         if (productId == null && productIdTo == null) {
442             errMsg = UtilProperties.getMessage(resource,"productservices.both_productId_and_productIdTo_cannot_be_null", locale);
443             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
444             result.put(ModelService.ERROR_MESSAGE, errMsg);
445             return result;
446         }
447
448         if (productId != null && productIdTo != null) {
449             errMsg = UtilProperties.getMessage(resource,"productservices.both_productId_and_productIdTo_cannot_be_defined", locale);
450             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
451             result.put(ModelService.ERROR_MESSAGE, errMsg);
452             return result;
453         }
454
455         productId = productId == null ? productIdTo : productId;
456         GenericValue product = null;
457
458         try {
459             product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", productId));
460         } catch (GenericEntityException e) {
461             Map messageMap = UtilMisc.toMap("errMessage", e.getMessage());
462             errMsg = UtilProperties.getMessage(resource,"productservices.productservices.problems_reading_product_entity", messageMap, locale);
463             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
464             result.put(ModelService.ERROR_MESSAGE, errMsg);
465             return result;
466         }
467
468         if (product == null) {
469             errMsg = UtilProperties.getMessage(resource,"productservices.problems_getting_product_entity", locale);
470             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
471             result.put(ModelService.ERROR_MESSAGE, errMsg);
472             return result;
473         }
474
475         try {
476             List productAssocs = null;
477
478             if (productIdTo == null) {
479                 productAssocs = product.getRelatedCache("MainProductAssoc", UtilMisc.toMap("productAssocTypeId", type), UtilMisc.toList("sequenceNum"));
480             } else {
481                 productAssocs = product.getRelatedCache("AssocProductAssoc", UtilMisc.toMap("productAssocTypeId", type), UtilMisc.toList("sequenceNum"));
482             }
483             // filter the list by date
484
productAssocs = EntityUtil.filterByDate(productAssocs, true);
485             // first check to see if there is a view allow category and if these producta are in it...
486
if (checkViewAllow && prodCatalogId != null && productAssocs != null && productAssocs.size() > 0) {
487                 String JavaDoc viewProductCategoryId = CatalogWorker.getCatalogViewAllowCategoryId(delegator, prodCatalogId);
488                 if (viewProductCategoryId != null) {
489                     if (productIdTo == null) {
490                         productAssocs = CategoryWorker.filterProductsInCategory(delegator, productAssocs, viewProductCategoryId, "productIdTo");
491                     } else {
492                         productAssocs = CategoryWorker.filterProductsInCategory(delegator, productAssocs, viewProductCategoryId, "productId");
493                     }
494                 }
495             }
496
497
498             result.put("assocProducts", productAssocs);
499             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS);
500         } catch (GenericEntityException e) {
501             Map messageMap = UtilMisc.toMap("errMessage", e.getMessage());
502             errMsg = UtilProperties.getMessage(resource,"productservices.problems_product_association_relation_error", messageMap, locale);
503             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
504             result.put(ModelService.ERROR_MESSAGE, errMsg);
505             return result;
506         }
507
508         return result;
509     }
510
511     // Builds a product feature tree
512
private static Map makeGroup(GenericDelegator delegator, Map featureList, List items, List order, int index)
513         throws IllegalArgumentException JavaDoc, IllegalStateException JavaDoc {
514         //List featureKey = new ArrayList();
515
Map tempGroup = new HashMap();
516         Map group = new LinkedMap();
517         String JavaDoc orderKey = (String JavaDoc) order.get(index);
518
519         if (featureList == null) {
520             throw new IllegalArgumentException JavaDoc("Cannot build feature tree: featureList is null");
521         }
522
523         if (index < 0) {
524             throw new IllegalArgumentException JavaDoc("Invalid index '" + index + "' min index '0'");
525         }
526         if (index + 1 > order.size()) {
527             throw new IllegalArgumentException JavaDoc("Invalid index '" + index + "' max index '" + (order.size() - 1) + "'");
528         }
529
530         // loop through items and make the lists
531
Iterator itemIterator = items.iterator();
532
533         while (itemIterator.hasNext()) {
534             // -------------------------------
535
// Gather the necessary data
536
// -------------------------------
537
String JavaDoc thisItem = (String JavaDoc) itemIterator.next();
538
539             if (Debug.verboseOn()) Debug.logVerbose("ThisItem: " + thisItem, module);
540             List features = null;
541
542             try {
543                 Map fields = UtilMisc.toMap("productId", thisItem, "productFeatureTypeId", orderKey,
544                         "productFeatureApplTypeId", "STANDARD_FEATURE");
545                 List sort = UtilMisc.toList("sequenceNum");
546
547                 // get the features and filter out expired dates
548
features = delegator.findByAndCache("ProductFeatureAndAppl", fields, sort);
549                 features = EntityUtil.filterByDate(features, true);
550             } catch (GenericEntityException e) {
551                 throw new IllegalStateException JavaDoc("Problem reading relation: " + e.getMessage());
552             }
553             if (Debug.verboseOn()) Debug.logVerbose("Features: " + features, module);
554
555             // -------------------------------
556
Iterator featuresIterator = features.iterator();
557
558             while (featuresIterator.hasNext()) {
559                 GenericValue item = (GenericValue) featuresIterator.next();
560                 Object JavaDoc itemKey = item.get("description");
561
562                 if (tempGroup.containsKey(itemKey)) {
563                     List itemList = (List) tempGroup.get(itemKey);
564
565                     if (!itemList.contains(thisItem))
566                         itemList.add(thisItem);
567                 } else {
568                     List itemList = UtilMisc.toList(thisItem);
569
570                     tempGroup.put(itemKey, itemList);
571                 }
572             }
573         }
574         if (Debug.verboseOn()) Debug.logVerbose("TempGroup: " + tempGroup, module);
575
576         // Loop through the feature list and order the keys in the tempGroup
577
List orderFeatureList = (List) featureList.get(orderKey);
578
579         if (orderFeatureList == null) {
580             throw new IllegalArgumentException JavaDoc("Cannot build feature tree: orderFeatureList is null for orderKey=" + orderKey);
581         }
582
583         Iterator featureListIt = orderFeatureList.iterator();
584
585         while (featureListIt.hasNext()) {
586             String JavaDoc featureStr = (String JavaDoc) featureListIt.next();
587
588             if (tempGroup.containsKey(featureStr))
589                 group.put(featureStr, tempGroup.get(featureStr));
590         }
591
592         if (Debug.verboseOn()) Debug.logVerbose("Group: " + group, module);
593
594         // no groups; no tree
595
if (group.size() == 0) {
596             return group;
597             //throw new IllegalStateException("Cannot create tree from group list; error on '" + orderKey + "'");
598
}
599
600         if (index + 1 == order.size()) {
601             return group;
602         }
603
604         // loop through the keysets and get the sub-groups
605
Iterator groupIterator = group.keySet().iterator();
606         while (groupIterator.hasNext()) {
607             Object JavaDoc key = groupIterator.next();
608             List itemList = (List) group.get(key);
609
610             if (itemList != null && itemList.size() > 0) {
611                 Map subGroup = makeGroup(delegator, featureList, itemList, order, index + 1);
612                 group.put(key, subGroup);
613             } else {
614                 // do nothing, ie put nothing in the Map
615
//throw new IllegalStateException("Cannot create tree from an empty list; error on '" + key + "'");
616
}
617         }
618         return group;
619     }
620
621     // builds a variant sample (a single sku for a featureType)
622
private static Map makeVariantSample(GenericDelegator delegator, Map featureList, List items, String JavaDoc feature) {
623         Map tempSample = new HashMap();
624         Map sample = new LinkedMap();
625         Iterator itemIt = items.iterator();
626
627         while (itemIt.hasNext()) {
628             String JavaDoc productId = (String JavaDoc) itemIt.next();
629             List features = null;
630
631             try {
632                 Map fields = UtilMisc.toMap("productId", productId, "productFeatureTypeId", feature,
633                         "productFeatureApplTypeId", "STANDARD_FEATURE");
634                 List sort = UtilMisc.toList("sequenceNum", "description");
635
636                 // get the features and filter out expired dates
637
features = delegator.findByAndCache("ProductFeatureAndAppl", fields, sort);
638                 features = EntityUtil.filterByDate(features, true);
639             } catch (GenericEntityException e) {
640                 throw new IllegalStateException JavaDoc("Problem reading relation: " + e.getMessage());
641             }
642             Iterator featureIt = features.iterator();
643
644             while (featureIt.hasNext()) {
645                 GenericValue featureAppl = (GenericValue) featureIt.next();
646
647                 try {
648                     GenericValue product = delegator.findByPrimaryKeyCache("Product",
649                             UtilMisc.toMap("productId", productId));
650
651                     tempSample.put(featureAppl.getString("description"), product);
652                 } catch (GenericEntityException e) {
653                     throw new RuntimeException JavaDoc("Cannot get product entity: " + e.getMessage());
654                 }
655             }
656         }
657
658         // Sort the sample based on the feature list.
659
List features = (LinkedList) featureList.get(feature);
660         Iterator fi = features.iterator();
661
662         while (fi.hasNext()) {
663             String JavaDoc f = (String JavaDoc) fi.next();
664
665             if (tempSample.containsKey(f))
666                 sample.put(f, tempSample.get(f));
667         }
668
669         return sample;
670     }
671
672     public static Map quickAddVariant(DispatchContext dctx, Map context) {
673         GenericDelegator delegator = dctx.getDelegator();
674         Map result = new HashMap();
675         Locale locale = (Locale) context.get("locale");
676         String JavaDoc errMsg=null;
677         String JavaDoc productId = (String JavaDoc) context.get("productId");
678         String JavaDoc variantProductId = (String JavaDoc) context.get("productVariantId");
679         String JavaDoc productFeatureIds = (String JavaDoc) context.get("productFeatureIds");
680         
681         try {
682             // read the product, duplicate it with the given id
683
GenericValue product = delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", productId));
684             if (product == null) {
685                 Map messageMap = UtilMisc.toMap("productId", productId);
686                 errMsg = UtilProperties.getMessage(resource,"productservices.product_not_found_with_ID", messageMap, locale);
687                 result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
688                 result.put(ModelService.ERROR_MESSAGE, errMsg);
689                 return result;
690             }
691             // check if product exists
692
GenericValue variantProduct = delegator.findByPrimaryKey("Product",UtilMisc.toMap("productId", variantProductId));
693             boolean variantProductExists = (variantProduct != null);
694             if (variantProduct == null) {
695                 //if product does not exist
696
variantProduct = GenericValue.create(product);
697                 variantProduct.set("productId", variantProductId);
698                 variantProduct.set("isVirtual", "N");
699                 variantProduct.set("isVariant", "Y");
700                 variantProduct.set("primaryProductCategoryId", null);
701                 //create new
702
variantProduct.create();
703             } else {
704                 //if product does exist
705
variantProduct.set("isVirtual", "N");
706                 variantProduct.set("isVariant", "Y");
707                 variantProduct.set("primaryProductCategoryId", null);
708                 //update entry
709
variantProduct.store();
710             }
711             GenericValue variantProductAssoc = null;
712             if (variantProductExists) {
713                 // Since the variant product is already a variant, first of all we remove the old features
714
// and the associations of type PRODUCT_VARIANT: a given product can be a variant of only one product.
715
delegator.removeByAnd("ProductAssoc", UtilMisc.toMap("productIdTo", variantProductId,
716                                                                      "productAssocTypeId", "PRODUCT_VARIANT"));
717                 delegator.removeByAnd("ProductFeatureAppl", UtilMisc.toMap("productId", variantProductId,
718                                                                            "productFeatureApplTypeId", "STANDARD_FEATURE"));
719             }
720             // add an association from productId to variantProductId of the PRODUCT_VARIANT
721
GenericValue productAssoc = delegator.makeValue("ProductAssoc",
722                                                             UtilMisc.toMap("productId", productId, "productIdTo", variantProductId,
723                                                                            "productAssocTypeId", "PRODUCT_VARIANT", "fromDate", UtilDateTime.nowTimestamp()));
724             productAssoc.create();
725
726             // add the selected standard features to the new product given the productFeatureIds
727
java.util.StringTokenizer JavaDoc st = new java.util.StringTokenizer JavaDoc(productFeatureIds, "|");
728             while (st.hasMoreTokens()) {
729                 String JavaDoc productFeatureId = st.nextToken();
730                
731                 GenericValue productFeature = delegator.findByPrimaryKey("ProductFeature", UtilMisc.toMap("productFeatureId", productFeatureId));
732                 
733                 GenericValue productFeatureAppl = delegator.makeValue("ProductFeatureAppl",
734                 UtilMisc.toMap("productId", variantProductId, "productFeatureId", productFeatureId,
735                 "productFeatureApplTypeId", "STANDARD_FEATURE", "fromDate", UtilDateTime.nowTimestamp()));
736                 
737                 // set the default seq num if it's there...
738
if (productFeature != null) {
739                     productFeatureAppl.set("sequenceNum", productFeature.get("defaultSequenceNum"));
740                 }
741                 
742                 productFeatureAppl.create();
743             }
744             
745         } catch (GenericEntityException e) {
746             Debug.logError(e, "Entity error creating quick add variant data", module);
747             Map messageMap = UtilMisc.toMap("errMessage", e.toString());
748             errMsg = UtilProperties.getMessage(resource,"productservices.entity_error_quick_add_variant_data", messageMap, locale);
749             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
750             result.put(ModelService.ERROR_MESSAGE, errMsg);
751             return result;
752         }
753         result.put("productVariantId", variantProductId);
754         return result;
755     }
756
757     /**
758      * This will create a virtual product and return its ID, and associate all of the variants with it.
759      * It will not put the selectable features on the virtual or standard features on the variant.
760      */

761     public static Map quickCreateVirtualWithVariants(DispatchContext dctx, Map context) {
762         GenericDelegator delegator = dctx.getDelegator();
763         Locale locale = (Locale) context.get("locale");
764         Timestamp JavaDoc nowTimestamp = UtilDateTime.nowTimestamp();
765         
766         // get the various IN attributes
767
String JavaDoc variantProductIdsBag = (String JavaDoc) context.get("variantProductIdsBag");
768         String JavaDoc productFeatureIdOne = (String JavaDoc) context.get("productFeatureIdOne");
769         String JavaDoc productFeatureIdTwo = (String JavaDoc) context.get("productFeatureIdTwo");
770         String JavaDoc productFeatureIdThree = (String JavaDoc) context.get("productFeatureIdThree");
771
772         Map successResult = ServiceUtil.returnSuccess();
773         
774         try {
775             // Generate new virtual productId, prefix with "VP", put in successResult
776
String JavaDoc productId = (String JavaDoc) context.get("productId");
777             
778             if (UtilValidate.isEmpty(productId)) {
779                 productId = "VP" + delegator.getNextSeqId("VirtualProduct");
780                 // Create new virtual product...
781
GenericValue product = delegator.makeValue("Product", null);
782                 product.set("productId", productId);
783                 // set: isVirtual=Y, isVariant=N, productTypeId=FINISHED_GOOD, introductionDate=now
784
product.set("isVirtual", "Y");
785                 product.set("isVariant", "N");
786                 product.set("productTypeId", "FINISHED_GOOD");
787                 product.set("introductionDate", nowTimestamp);
788                 // set all to Y: returnable, taxable, chargeShipping, autoCreateKeywords, includeInPromotions
789
product.set("returnable", "Y");
790                 product.set("taxable", "Y");
791                 product.set("chargeShipping", "Y");
792                 product.set("autoCreateKeywords", "Y");
793                 product.set("includeInPromotions", "Y");
794                 // in it goes!
795
product.create();
796             }
797             successResult.put("productId", productId);
798             
799             // separate variantProductIdsBag into a Set of variantProductIds
800
//note: can be comma, tab, or white-space delimited
801
Set prelimVariantProductIds = new HashSet();
802             List splitIds = Arrays.asList(variantProductIdsBag.split("[,\\p{Space}]"));
803             Debug.logInfo("Variants: bag=" + variantProductIdsBag, module);
804             Debug.logInfo("Variants: split=" + splitIds, module);
805             prelimVariantProductIds.addAll(splitIds);
806             //note: should support both direct productIds and GoodIdentification entries (what to do if more than one GoodID? Add all?
807

808             Map variantProductsById = new HashMap();
809             Iterator variantProductIdIter = prelimVariantProductIds.iterator();
810             while (variantProductIdIter.hasNext()) {
811                 String JavaDoc variantProductId = (String JavaDoc) variantProductIdIter.next();
812                 if (UtilValidate.isEmpty(variantProductId)) {
813                     // not sure why this happens, but seems to from time to time with the split method
814
continue;
815                 }
816                 // is a Product.productId?
817
GenericValue variantProduct = delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", variantProductId));
818                 if (variantProduct != null) {
819                     variantProductsById.put(variantProductId, variantProduct);
820                 } else {
821                     // is a GoodIdentification.idValue?
822
List goodIdentificationList = delegator.findByAnd("GoodIdentification", UtilMisc.toMap("idValue", variantProductId));
823                     if (goodIdentificationList == null || goodIdentificationList.size() == 0) {
824                         // whoops, nothing found... return error
825
return ServiceUtil.returnError("Error creating a virtual with variants: the ID [" + variantProductId + "] is not a valid Product.productId or a GoodIdentification.idValue");
826                     }
827                     
828                     if (goodIdentificationList.size() > 1) {
829                         // what to do here? for now just log a warning and add all of them as variants; they can always be dissociated later
830
Debug.logWarning("Warning creating a virtual with variants: the ID [" + variantProductId + "] was not a productId and resulted in [" + goodIdentificationList.size() + "] GoodIdentification records: " + goodIdentificationList, module);
831                     }
832                     
833                     Iterator goodIdentificationIter = goodIdentificationList.iterator();
834                     while (goodIdentificationIter.hasNext()) {
835                         GenericValue goodIdentification = (GenericValue) goodIdentificationIter.next();
836                         GenericValue giProduct = goodIdentification.getRelatedOne("Product");
837                         if (giProduct != null) {
838                             variantProductsById.put(giProduct.get("productId"), giProduct);
839                         }
840                     }
841                 }
842             }
843
844             // Attach productFeatureIdOne, Two, Three to the new virtual and all variant products as a standard feature
845
Set featureProductIds = new HashSet();
846             featureProductIds.add(productId);
847             featureProductIds.addAll(variantProductsById.keySet());
848             Set productFeatureIds = new HashSet();
849             productFeatureIds.add(productFeatureIdOne);
850             productFeatureIds.add(productFeatureIdTwo);
851             productFeatureIds.add(productFeatureIdThree);
852             
853             Iterator featureProductIdIter = featureProductIds.iterator();
854             while (featureProductIdIter.hasNext()) {
855                 Iterator productFeatureIdIter = productFeatureIds.iterator();
856                 String JavaDoc featureProductId = (String JavaDoc) featureProductIdIter.next();
857                 while (productFeatureIdIter.hasNext()) {
858                     String JavaDoc productFeatureId = (String JavaDoc) productFeatureIdIter.next();
859                     if (UtilValidate.isNotEmpty(productFeatureId)) {
860                         GenericValue productFeatureAppl = delegator.makeValue("ProductFeatureAppl",
861                                 UtilMisc.toMap("productId", featureProductId, "productFeatureId", productFeatureId,
862                                         "productFeatureApplTypeId", "STANDARD_FEATURE", "fromDate", nowTimestamp));
863                         productFeatureAppl.create();
864                     }
865                 }
866             }
867             
868             Iterator variantProductIter = variantProductsById.values().iterator();
869             while (variantProductIter.hasNext()) {
870                 // for each variant product set: isVirtual=N, isVariant=Y, introductionDate=now
871
GenericValue variantProduct = (GenericValue) variantProductIter.next();
872                 variantProduct.set("isVirtual", "N");
873                 variantProduct.set("isVariant", "Y");
874                 variantProduct.set("introductionDate", nowTimestamp);
875                 variantProduct.store();
876
877                 // for each variant product create associate with the new virtual as a PRODUCT_VARIANT
878
GenericValue productAssoc = delegator.makeValue("ProductAssoc",
879                         UtilMisc.toMap("productId", productId, "productIdTo", variantProduct.get("productId"),
880                                 "productAssocTypeId", "PRODUCT_VARIANT", "fromDate", nowTimestamp));
881                 productAssoc.create();
882             }
883         } catch (GenericEntityException e) {
884             String JavaDoc errMsg = "Error creating new virtual product from variant products: " + e.toString();
885             Debug.logError(e, errMsg, module);
886             return ServiceUtil.returnError(errMsg);
887         }
888         return successResult;
889     }
890
891     public static Map updateProductIfAvailableFromShipment(DispatchContext dctx, Map context) {
892         if ("Y".equals(UtilProperties.getPropertyValue("catalog.properties", "reactivate.product.from.receipt", "N"))) {
893             LocalDispatcher dispatcher = dctx.getDispatcher();
894             GenericDelegator delegator = dctx.getDelegator();
895             GenericValue userLogin = (GenericValue) context.get("userLogin");
896             String JavaDoc inventoryItemId = (String JavaDoc) context.get("inventoryItemId");
897
898             GenericValue inventoryItem = null;
899             try {
900                 inventoryItem = delegator.findByPrimaryKeyCache("InventoryItem", UtilMisc.toMap("inventoryItemId", inventoryItemId));
901             } catch (GenericEntityException e) {
902                 Debug.logError(e, module);
903                 return ServiceUtil.returnError(e.getMessage());
904             }
905
906             if (inventoryItem != null) {
907                 String JavaDoc productId = inventoryItem.getString("productId");
908                 GenericValue product = null;
909                 try {
910                     product = delegator.findByPrimaryKeyCache("Product", UtilMisc.toMap("productId", productId));
911                 } catch (GenericEntityException e) {
912                     Debug.logError(e, module);
913                     return ServiceUtil.returnError(e.getMessage());
914                 }
915
916                 if (product != null) {
917                     Timestamp JavaDoc salesDiscontinuationDate = product.getTimestamp("salesDiscontinuationDate");
918                     if (salesDiscontinuationDate != null && salesDiscontinuationDate.before(UtilDateTime.nowTimestamp())) {
919                         Map invRes = null;
920                         try {
921                             invRes = dispatcher.runSync("getProductInventoryAvailable", UtilMisc.toMap("productId", productId, "userLogin", userLogin));
922                         } catch (GenericServiceException e) {
923                             Debug.logError(e, module);
924                             return ServiceUtil.returnError(e.getMessage());
925                         }
926
927                         Double JavaDoc availableToPromiseTotal = (Double JavaDoc) invRes.get("availableToPromiseTotal");
928                         if (availableToPromiseTotal != null && availableToPromiseTotal.doubleValue() > 0) {
929                             // refresh the product so we can update it
930
GenericValue productToUpdate = null;
931                             try {
932                                 productToUpdate = delegator.findByPrimaryKey("Product", product.getPrimaryKey());
933                             } catch (GenericEntityException e) {
934                                 Debug.logError(e, module);
935                                 return ServiceUtil.returnError(e.getMessage());
936                             }
937
938                             // set and save
939
productToUpdate.set("salesDiscontinuationDate", null);
940                             try {
941                                 delegator.store(productToUpdate);
942                             } catch (GenericEntityException e) {
943                                 Debug.logError(e, module);
944                                 return ServiceUtil.returnError(e.getMessage());
945                             }
946                         }
947                     }
948                 }
949             }
950         }
951
952         return ServiceUtil.returnSuccess();
953     }
954 }
955
956
Popular Tags