1   /**
2    * Copyright (c) 2000-2007 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.shopping.util;
24  
25  import com.liferay.portal.PortalException;
26  import com.liferay.portal.SystemException;
27  import com.liferay.portal.kernel.language.LanguageUtil;
28  import com.liferay.portal.kernel.portlet.LiferayWindowState;
29  import com.liferay.portal.kernel.util.Constants;
30  import com.liferay.portal.kernel.util.GetterUtil;
31  import com.liferay.portal.kernel.util.OrderByComparator;
32  import com.liferay.portal.kernel.util.StringMaker;
33  import com.liferay.portal.kernel.util.StringPool;
34  import com.liferay.portal.kernel.util.StringUtil;
35  import com.liferay.portal.theme.ThemeDisplay;
36  import com.liferay.portal.util.WebKeys;
37  import com.liferay.portlet.shopping.NoSuchCartException;
38  import com.liferay.portlet.shopping.model.ShoppingCart;
39  import com.liferay.portlet.shopping.model.ShoppingCartItem;
40  import com.liferay.portlet.shopping.model.ShoppingCategory;
41  import com.liferay.portlet.shopping.model.ShoppingCoupon;
42  import com.liferay.portlet.shopping.model.ShoppingItem;
43  import com.liferay.portlet.shopping.model.ShoppingItemField;
44  import com.liferay.portlet.shopping.model.ShoppingItemPrice;
45  import com.liferay.portlet.shopping.model.ShoppingOrder;
46  import com.liferay.portlet.shopping.model.ShoppingOrderItem;
47  import com.liferay.portlet.shopping.model.impl.ShoppingCartImpl;
48  import com.liferay.portlet.shopping.model.impl.ShoppingCouponImpl;
49  import com.liferay.portlet.shopping.model.impl.ShoppingItemPriceImpl;
50  import com.liferay.portlet.shopping.model.impl.ShoppingOrderImpl;
51  import com.liferay.portlet.shopping.service.ShoppingCartLocalServiceUtil;
52  import com.liferay.portlet.shopping.service.ShoppingCategoryLocalServiceUtil;
53  import com.liferay.portlet.shopping.service.ShoppingOrderItemLocalServiceUtil;
54  import com.liferay.portlet.shopping.service.persistence.ShoppingItemPriceUtil;
55  import com.liferay.portlet.shopping.util.comparator.ItemMinQuantityComparator;
56  import com.liferay.portlet.shopping.util.comparator.ItemNameComparator;
57  import com.liferay.portlet.shopping.util.comparator.ItemPriceComparator;
58  import com.liferay.portlet.shopping.util.comparator.ItemSKUComparator;
59  import com.liferay.portlet.shopping.util.comparator.OrderDateComparator;
60  import com.liferay.util.HttpUtil;
61  import com.liferay.util.MathUtil;
62  
63  import java.text.NumberFormat;
64  
65  import java.util.ArrayList;
66  import java.util.HashMap;
67  import java.util.HashSet;
68  import java.util.Iterator;
69  import java.util.List;
70  import java.util.Map;
71  import java.util.Set;
72  
73  import javax.portlet.PortletRequest;
74  import javax.portlet.PortletSession;
75  import javax.portlet.PortletURL;
76  import javax.portlet.RenderRequest;
77  import javax.portlet.RenderResponse;
78  import javax.portlet.WindowState;
79  
80  import javax.servlet.jsp.PageContext;
81  
82  /**
83   * <a href="ShoppingUtil.java.html"><b><i>View Source</i></b></a>
84   *
85   * @author Brian Wing Shun Chan
86   *
87   */
88  public class ShoppingUtil {
89  
90      public static double calculateActualPrice(ShoppingItem item) {
91          return item.getPrice() - calculateDiscountPrice(item);
92      }
93  
94      public static double calculateActualPrice(ShoppingItem item, int count)
95          throws PortalException, SystemException {
96  
97          return calculatePrice(item, count) -
98              calculateDiscountPrice(item, count);
99      }
100 
101     public static double calculateActualPrice(ShoppingItemPrice itemPrice) {
102         return itemPrice.getPrice() - calculateDiscountPrice(itemPrice);
103     }
104 
105     public static double calculateActualSubtotal(Map items)
106         throws PortalException, SystemException {
107 
108         return calculateSubtotal(items) - calculateDiscountSubtotal(items);
109     }
110 
111     public static double calculateActualSubtotal(List orderItems) {
112         double subtotal = 0.0;
113 
114         Iterator itr = orderItems.iterator();
115 
116         while (itr.hasNext()) {
117             ShoppingOrderItem orderItem = (ShoppingOrderItem)itr.next();
118 
119             subtotal += orderItem.getPrice() * orderItem.getQuantity();
120         }
121 
122         return subtotal;
123     }
124 
125     public static double calculateAlternativeShipping(
126             Map items, int altShipping)
127         throws PortalException, SystemException {
128 
129         double shipping = calculateShipping(items);
130         double alternativeShipping = shipping;
131 
132         ShoppingPreferences prefs = null;
133 
134         Iterator itr = items.entrySet().iterator();
135 
136         while (itr.hasNext()) {
137             Map.Entry entry = (Map.Entry)itr.next();
138 
139             ShoppingCartItem cartItem = (ShoppingCartItem)entry.getKey();
140 
141             ShoppingItem item = cartItem.getItem();
142 
143             if (prefs == null) {
144                 ShoppingCategory category = item.getCategory();
145 
146                 prefs = ShoppingPreferences.getInstance(
147                     category.getCompanyId(), category.getGroupId());
148 
149                 break;
150             }
151         }
152 
153         // Calculate alternative shipping if shopping is configured to use
154         // alternative shipping and shipping price is greater than 0
155 
156         if ((prefs != null) &&
157             (prefs.useAlternativeShipping()) && (shipping > 0)) {
158 
159             double altShippingDelta = 0.0;
160 
161             try {
162                 altShippingDelta = GetterUtil.getDouble(
163                     prefs.getAlternativeShipping()[1][altShipping]);
164             }
165             catch (Exception e) {
166                 return alternativeShipping;
167             }
168 
169             if (altShippingDelta > 0) {
170                 alternativeShipping = shipping * altShippingDelta;
171             }
172         }
173 
174         return alternativeShipping;
175     }
176 
177     public static double calculateCouponDiscount(
178             Map items, ShoppingCoupon coupon)
179         throws PortalException, SystemException {
180 
181         return calculateCouponDiscount(items, null, coupon);
182     }
183 
184     public static double calculateCouponDiscount(
185             Map items, String stateId, ShoppingCoupon coupon)
186         throws PortalException, SystemException {
187 
188         double discount = 0.0;
189 
190         if ((coupon == null) || !coupon.isActive() ||
191             !coupon.hasValidDateRange()) {
192 
193             return discount;
194         }
195 
196         String[] categoryIds = StringUtil.split(coupon.getLimitCategories());
197         String[] skus = StringUtil.split(coupon.getLimitSkus());
198 
199         if ((categoryIds.length > 0) || (skus.length > 0)) {
200             Set categoryIdsSet = new HashSet();
201 
202             for (int i = 0; i < categoryIds.length; i++) {
203                 categoryIdsSet.add(categoryIds[i]);
204             }
205 
206             Set skusSet = new HashSet();
207 
208             for (int i = 0; i < skus.length; i++) {
209                 skusSet.add(skus[i]);
210             }
211 
212             Map newItems = new HashMap();
213 
214             Iterator itr = items.entrySet().iterator();
215 
216             while (itr.hasNext()) {
217                 Map.Entry entry = (Map.Entry)itr.next();
218 
219                 ShoppingCartItem cartItem = (ShoppingCartItem)entry.getKey();
220                 Integer count = (Integer)entry.getValue();
221 
222                 ShoppingItem item = cartItem.getItem();
223 
224                 if (((categoryIdsSet.size() > 0) &&
225                      (categoryIdsSet.contains(
226                         new Long(item.getCategoryId())))) ||
227                     ((skusSet.size() > 0) &&
228                      (skusSet.contains(item.getSku())))) {
229 
230                     newItems.put(cartItem, count);
231                 }
232             }
233 
234             items = newItems;
235         }
236 
237         double actualSubtotal = calculateActualSubtotal(items);
238 
239         if ((coupon.getMinOrder() > 0) &&
240             (coupon.getMinOrder() > actualSubtotal)) {
241 
242             return discount;
243         }
244 
245         String type = coupon.getDiscountType();
246 
247         if (type.equals(ShoppingCouponImpl.DISCOUNT_TYPE_PERCENTAGE)) {
248             discount = actualSubtotal * coupon.getDiscount();
249         }
250         else if (type.equals(ShoppingCouponImpl.DISCOUNT_TYPE_ACTUAL)) {
251             discount = coupon.getDiscount();
252         }
253         else if (type.equals(ShoppingCouponImpl.DISCOUNT_TYPE_FREE_SHIPPING)) {
254             discount = calculateShipping(items);
255         }
256         else if (type.equals(ShoppingCouponImpl.DISCOUNT_TYPE_TAX_FREE)) {
257             if (stateId != null) {
258                 discount = calculateTax(items, stateId);
259             }
260         }
261 
262         return discount;
263     }
264 
265     public static double calculateDiscountPercent(Map items)
266         throws PortalException, SystemException {
267 
268         double discount =
269             calculateDiscountSubtotal(items) / calculateSubtotal(items);
270 
271         if (Double.isNaN(discount) || Double.isInfinite(discount)) {
272             discount = 0.0;
273         }
274 
275         return discount;
276     }
277 
278     public static double calculateDiscountPrice(ShoppingItem item) {
279         return item.getPrice() * item.getDiscount();
280     }
281 
282     public static double calculateDiscountPrice(ShoppingItem item, int count)
283         throws PortalException, SystemException {
284 
285         ShoppingItemPrice itemPrice = _getItemPrice(item, count);
286 
287         return itemPrice.getPrice() * itemPrice.getDiscount() * count;
288     }
289 
290     public static double calculateDiscountPrice(ShoppingItemPrice itemPrice) {
291         return itemPrice.getPrice() * itemPrice.getDiscount();
292     }
293 
294     public static double calculateDiscountSubtotal(Map items)
295         throws PortalException, SystemException {
296 
297         double subtotal = 0.0;
298 
299         Iterator itr = items.entrySet().iterator();
300 
301         while (itr.hasNext()) {
302             Map.Entry entry = (Map.Entry)itr.next();
303 
304             ShoppingCartItem cartItem = (ShoppingCartItem)entry.getKey();
305             Integer count = (Integer)entry.getValue();
306 
307             ShoppingItem item = cartItem.getItem();
308 
309             subtotal += calculateDiscountPrice(item, count.intValue());
310         }
311 
312         return subtotal;
313     }
314 
315     public static double calculateInsurance(Map items)
316         throws PortalException, SystemException {
317 
318         double insurance = 0.0;
319         double subtotal = 0.0;
320 
321         ShoppingPreferences prefs = null;
322 
323         Iterator itr = items.entrySet().iterator();
324 
325         while (itr.hasNext()) {
326             Map.Entry entry = (Map.Entry)itr.next();
327 
328             ShoppingCartItem cartItem = (ShoppingCartItem)entry.getKey();
329             Integer count = (Integer)entry.getValue();
330 
331             ShoppingItem item = cartItem.getItem();
332 
333             if (prefs == null) {
334                 ShoppingCategory category = item.getCategory();
335 
336                 prefs = ShoppingPreferences.getInstance(
337                     category.getCompanyId(), category.getGroupId());
338             }
339 
340             ShoppingItemPrice itemPrice =
341                 _getItemPrice(item, count.intValue());
342 
343             subtotal += calculateActualPrice(itemPrice) * count.intValue();
344         }
345 
346         if ((prefs != null) && (subtotal > 0)) {
347             double insuranceRate = 0.0;
348 
349             double[] range = ShoppingPreferences.INSURANCE_RANGE;
350 
351             for (int i = 0; i < range.length - 1; i++) {
352                 if (subtotal > range[i] && subtotal <= range[i + 1]) {
353                     int rangeId = i / 2;
354                     if (MathUtil.isOdd(i)) {
355                         rangeId = (i + 1) / 2;
356                     }
357 
358                     insuranceRate = GetterUtil.getDouble(
359                         prefs.getInsurance()[rangeId]);
360                 }
361             }
362 
363             String formula = prefs.getInsuranceFormula();
364 
365             if (formula.equals("flat")) {
366                 insurance += insuranceRate;
367             }
368             else if (formula.equals("percentage")) {
369                 insurance += subtotal * insuranceRate;
370             }
371         }
372 
373         return insurance;
374     }
375 
376     public static double calculatePrice(ShoppingItem item, int count)
377         throws PortalException, SystemException {
378 
379         ShoppingItemPrice itemPrice = _getItemPrice(item, count);
380 
381         return itemPrice.getPrice() * count;
382     }
383 
384     public static double calculateShipping(Map items)
385         throws PortalException, SystemException {
386 
387         double shipping = 0.0;
388         double subtotal = 0.0;
389 
390         ShoppingPreferences prefs = null;
391 
392         Iterator itr = items.entrySet().iterator();
393 
394         while (itr.hasNext()) {
395             Map.Entry entry = (Map.Entry)itr.next();
396 
397             ShoppingCartItem cartItem = (ShoppingCartItem)entry.getKey();
398             Integer count = (Integer)entry.getValue();
399 
400             ShoppingItem item = cartItem.getItem();
401 
402             if (prefs == null) {
403                 ShoppingCategory category = item.getCategory();
404 
405                 prefs = ShoppingPreferences.getInstance(
406                     category.getCompanyId(), category.getGroupId());
407             }
408 
409             if (item.isRequiresShipping()) {
410                 ShoppingItemPrice itemPrice =
411                     _getItemPrice(item, count.intValue());
412 
413                 if (itemPrice.isUseShippingFormula()) {
414                     subtotal +=
415                         calculateActualPrice(itemPrice) * count.intValue();
416                 }
417                 else {
418                     shipping += itemPrice.getShipping() * count.intValue();
419                 }
420             }
421         }
422 
423         if ((prefs != null) && (subtotal > 0)) {
424             double shippingRate = 0.0;
425 
426             double[] range = ShoppingPreferences.SHIPPING_RANGE;
427 
428             for (int i = 0; i < range.length - 1; i++) {
429                 if (subtotal > range[i] && subtotal <= range[i + 1]) {
430                     int rangeId = i / 2;
431                     if (MathUtil.isOdd(i)) {
432                         rangeId = (i + 1) / 2;
433                     }
434 
435                     shippingRate = GetterUtil.getDouble(
436                         prefs.getShipping()[rangeId]);
437                 }
438             }
439 
440             String formula = prefs.getShippingFormula();
441 
442             if (formula.equals("flat")) {
443                 shipping += shippingRate;
444             }
445             else if (formula.equals("percentage")) {
446                 shipping += subtotal * shippingRate;
447             }
448         }
449 
450         return shipping;
451     }
452 
453     public static double calculateSubtotal(Map items)
454         throws PortalException, SystemException {
455 
456         double subtotal = 0.0;
457 
458         Iterator itr = items.entrySet().iterator();
459 
460         while (itr.hasNext()) {
461             Map.Entry entry = (Map.Entry)itr.next();
462 
463             ShoppingCartItem cartItem = (ShoppingCartItem)entry.getKey();
464             Integer count = (Integer)entry.getValue();
465 
466             ShoppingItem item = cartItem.getItem();
467 
468             subtotal += calculatePrice(item, count.intValue());
469         }
470 
471         return subtotal;
472     }
473 
474     public static double calculateTax(Map items, String stateId)
475         throws PortalException, SystemException {
476 
477         double tax = 0.0;
478 
479         ShoppingPreferences prefs = null;
480 
481         Iterator itr = items.entrySet().iterator();
482 
483         while (itr.hasNext()) {
484             Map.Entry entry = (Map.Entry)itr.next();
485 
486             ShoppingCartItem cartItem = (ShoppingCartItem)entry.getKey();
487 
488             ShoppingItem item = cartItem.getItem();
489 
490             if (prefs == null) {
491                 ShoppingCategory category = item.getCategory();
492 
493                 prefs = ShoppingPreferences.getInstance(
494                     category.getCompanyId(), category.getGroupId());
495 
496                 break;
497             }
498         }
499 
500         if ((prefs != null) &&
501             (prefs.getTaxState().equals(stateId))) {
502 
503             double subtotal = 0.0;
504 
505             itr = items.entrySet().iterator();
506 
507             while (itr.hasNext()) {
508                 Map.Entry entry = (Map.Entry)itr.next();
509 
510                 ShoppingCartItem cartItem = (ShoppingCartItem)entry.getKey();
511                 Integer count = (Integer)entry.getValue();
512 
513                 ShoppingItem item = cartItem.getItem();
514 
515                 if (item.isTaxable()) {
516                     subtotal += calculatePrice(item, count.intValue());
517                 }
518             }
519 
520             tax = prefs.getTaxRate() * subtotal;
521         }
522 
523         return tax;
524     }
525 
526     public static double calculateTotal(
527             Map items, String stateId, ShoppingCoupon coupon, int altShipping,
528             boolean insure)
529         throws PortalException, SystemException {
530 
531         double actualSubtotal = calculateActualSubtotal(items);
532         double tax = calculateTax(items, stateId);
533         double shipping = calculateAlternativeShipping(items, altShipping);
534 
535         double insurance = 0.0;
536         if (insure) {
537             insurance = calculateInsurance(items);
538         }
539 
540         double couponDiscount = calculateCouponDiscount(items, stateId, coupon);
541 
542         double total =
543             actualSubtotal + tax + shipping + insurance - couponDiscount;
544 
545         if (total < 0) {
546             total = 0.0;
547         }
548 
549         return total;
550     }
551 
552     public static double calculateTotal(ShoppingOrder order)
553         throws PortalException, SystemException {
554 
555         List orderItems = ShoppingOrderItemLocalServiceUtil.getOrderItems(
556             order.getOrderId());
557 
558         double total =
559             calculateActualSubtotal(orderItems) + order.getTax() +
560                 order.getShipping() + order.getInsurance() -
561                     order.getCouponDiscount();
562 
563         if (total < 0) {
564             total = 0.0;
565         }
566 
567         return total;
568     }
569 
570     public static String getBreadcrumbs(
571             long categoryId, PageContext pageContext, RenderRequest req,
572             RenderResponse res)
573         throws Exception {
574 
575         ShoppingCategory category = null;
576 
577         try {
578             category = ShoppingCategoryLocalServiceUtil.getCategory(categoryId);
579         }
580         catch (Exception e) {
581         }
582 
583         return getBreadcrumbs(category, pageContext, req, res);
584     }
585 
586     public static String getBreadcrumbs(
587             ShoppingCategory category, PageContext pageContext,
588             RenderRequest req, RenderResponse res)
589         throws Exception {
590 
591         PortletURL categoriesURL = res.createRenderURL();
592 
593         WindowState windowState = req.getWindowState();
594 
595         if (windowState.equals(LiferayWindowState.POP_UP)) {
596             categoriesURL.setWindowState(LiferayWindowState.POP_UP);
597 
598             categoriesURL.setParameter(
599                 "struts_action", "/shopping/select_category");
600         }
601         else {
602             categoriesURL.setWindowState(WindowState.MAXIMIZED);
603 
604             categoriesURL.setParameter("struts_action", "/shopping/view");
605             categoriesURL.setParameter("tabs1", "categories");
606         }
607 
608         String categoriesLink =
609             "<a href=\"" + categoriesURL.toString() + "\">" +
610                 LanguageUtil.get(pageContext, "categories") + "</a>";
611 
612         if (category == null) {
613             return categoriesLink;
614         }
615 
616         String breadcrumbs = StringPool.BLANK;
617 
618         if (category != null) {
619             for (int i = 0;; i++) {
620                 PortletURL portletURL = res.createRenderURL();
621 
622                 if (windowState.equals(LiferayWindowState.POP_UP)) {
623                     portletURL.setWindowState(LiferayWindowState.POP_UP);
624 
625                     portletURL.setParameter(
626                         "struts_action", "/shopping/select_category");
627                     portletURL.setParameter(
628                         "categoryId", String.valueOf(category.getCategoryId()));
629                 }
630                 else {
631                     portletURL.setWindowState(WindowState.MAXIMIZED);
632 
633                     portletURL.setParameter("struts_action", "/shopping/view");
634                     portletURL.setParameter("tabs1", "categories");
635                     portletURL.setParameter(
636                         "categoryId", String.valueOf(category.getCategoryId()));
637                 }
638 
639                 String categoryLink =
640                     "<a href=\"" + portletURL.toString() + "\">" +
641                         category.getName() + "</a>";
642 
643                 if (i == 0) {
644                     breadcrumbs = categoryLink;
645                 }
646                 else {
647                     breadcrumbs = categoryLink + " &raquo; " + breadcrumbs;
648                 }
649 
650                 if (category.isRoot()) {
651                     break;
652                 }
653 
654                 category = ShoppingCategoryLocalServiceUtil.getCategory(
655                     category.getParentCategoryId());
656             }
657         }
658 
659         breadcrumbs = categoriesLink + " &raquo; " + breadcrumbs;
660 
661         return breadcrumbs;
662     }
663 
664     public static ShoppingCart getCart(ThemeDisplay themeDisplay) {
665         ShoppingCart cart = new ShoppingCartImpl();
666 
667         cart.setGroupId(themeDisplay.getPortletGroupId());
668         cart.setCompanyId(themeDisplay.getCompanyId());
669         cart.setUserId(themeDisplay.getUserId());
670         cart.setItemIds(StringPool.BLANK);
671         cart.setCouponCodes(StringPool.BLANK);
672         cart.setAltShipping(0);
673         cart.setInsure(false);
674 
675         return cart;
676     }
677 
678     public static ShoppingCart getCart(PortletRequest req)
679         throws PortalException, SystemException {
680 
681         PortletSession ses = req.getPortletSession();
682 
683         ThemeDisplay themeDisplay =
684             (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
685 
686         String sesCartId =
687             ShoppingCart.class.getName() + themeDisplay.getPortletGroupId();
688 
689         if (themeDisplay.isSignedIn()) {
690             ShoppingCart cart = (ShoppingCart)ses.getAttribute(sesCartId);
691 
692             if (cart != null) {
693                 ses.removeAttribute(sesCartId);
694             }
695 
696             if ((cart != null) && (cart.getItemsSize() > 0)) {
697                 cart = ShoppingCartLocalServiceUtil.updateCart(
698                     themeDisplay.getUserId(), themeDisplay.getPortletGroupId(),
699                     cart.getItemIds(), cart.getCouponCodes(),
700                     cart.getAltShipping(), cart.isInsure());
701             }
702             else {
703                 try {
704                     cart = ShoppingCartLocalServiceUtil.getCart(
705                         themeDisplay.getUserId(),
706                         themeDisplay.getPortletGroupId());
707                 }
708                 catch (NoSuchCartException nsce) {
709                     cart = getCart(themeDisplay);
710 
711                     cart = ShoppingCartLocalServiceUtil.updateCart(
712                         themeDisplay.getUserId(),
713                         themeDisplay.getPortletGroupId(), cart.getItemIds(),
714                         cart.getCouponCodes(), cart.getAltShipping(),
715                         cart.isInsure());
716                 }
717             }
718 
719             return cart;
720         }
721         else {
722             ShoppingCart cart = (ShoppingCart)ses.getAttribute(sesCartId);
723 
724             if (cart == null) {
725                 cart = getCart(themeDisplay);
726 
727                 ses.setAttribute(sesCartId, cart);
728             }
729 
730             return cart;
731         }
732     }
733 
734     public static int getFieldsQuantitiesPos(
735         ShoppingItem item, ShoppingItemField[] itemFields,
736         String[] fieldsArray) {
737 
738         Set fieldsValues = new HashSet();
739 
740         for (int i = 0; i < fieldsArray.length; i++) {
741             int pos = fieldsArray[i].indexOf("=");
742 
743             String fieldValue = fieldsArray[i].substring(
744                 pos + 1, fieldsArray[i].length()).trim();
745 
746             fieldsValues.add(fieldValue);
747         }
748 
749         List names = new ArrayList();
750         List values = new ArrayList();
751 
752         for (int i = 0; i < itemFields.length; i++) {
753             names.add(itemFields[i].getName());
754             values.add(StringUtil.split(itemFields[i].getValues()));
755         }
756 
757         int numOfRows = 1;
758 
759         for (int i = 0; i < values.size(); i++) {
760             String[] vArray = (String[])values.get(i);
761 
762             numOfRows = numOfRows * vArray.length;
763         }
764 
765         int rowPos = 0;
766 
767         for (int i = 0; i < numOfRows; i++) {
768             boolean match = true;
769 
770             for (int j = 0; j < names.size(); j++) {
771                 int numOfRepeats = 1;
772 
773                 for (int k = j + 1; k < values.size(); k++) {
774                     String[] vArray = (String[])values.get(k);
775 
776                     numOfRepeats = numOfRepeats * vArray.length;
777                 }
778 
779                 String[] vArray = (String[])values.get(j);
780 
781                 int arrayPos;
782                 for (arrayPos = i / numOfRepeats;
783                      arrayPos >= vArray.length;
784                      arrayPos = arrayPos - vArray.length) {
785                 }
786 
787                 if (!fieldsValues.contains(vArray[arrayPos].trim())) {
788                     match = false;
789 
790                     break;
791                 }
792             }
793 
794             if (match) {
795                 rowPos = i;
796 
797                 break;
798             }
799         }
800 
801         return rowPos;
802     }
803 
804     public static long getItemId(String itemId) {
805         int pos = itemId.indexOf(StringPool.PIPE);
806 
807         if (pos != -1) {
808             itemId = itemId.substring(0, pos);
809         }
810 
811         return GetterUtil.getLong(itemId);
812     }
813 
814     public static String getItemFields(String itemId) {
815         int pos = itemId.indexOf(StringPool.PIPE);
816 
817         if (pos == -1) {
818             return StringPool.BLANK;
819         }
820         else {
821             return itemId.substring(pos + 1, itemId.length());
822         }
823     }
824 
825     public static OrderByComparator getItemOrderByComparator(
826         String orderByCol, String orderByType) {
827 
828         boolean orderByAsc = false;
829 
830         if (orderByType.equals("asc")) {
831             orderByAsc = true;
832         }
833 
834         OrderByComparator orderByComparator = null;
835 
836         if (orderByCol.equals("min-qty")) {
837             orderByComparator = new ItemMinQuantityComparator(orderByAsc);
838         }
839         else if (orderByCol.equals("name")) {
840             orderByComparator = new ItemNameComparator(orderByAsc);
841         }
842         else if (orderByCol.equals("price")) {
843             orderByComparator = new ItemPriceComparator(orderByAsc);
844         }
845         else if (orderByCol.equals("sku")) {
846             orderByComparator = new ItemSKUComparator(orderByAsc);
847         }
848         else if (orderByCol.equals("order-date")) {
849             orderByComparator = new OrderDateComparator(orderByAsc);
850         }
851 
852         return orderByComparator;
853     }
854 
855     public static int getMinQuantity(ShoppingItem item)
856         throws PortalException, SystemException {
857 
858         int minQuantity = item.getMinQuantity();
859 
860         List itemPrices = item.getItemPrices();
861 
862         for (int i = 0; i < itemPrices.size(); i++) {
863             ShoppingItemPrice itemPrice =
864                 (ShoppingItemPrice)itemPrices.get(i);
865 
866             if (minQuantity > itemPrice.getMinQuantity()) {
867                 minQuantity = itemPrice.getMinQuantity();
868             }
869         }
870 
871         return minQuantity;
872     }
873 
874     public static String getPayPalNotifyURL(ThemeDisplay themeDisplay) {
875         return themeDisplay.getURLPortal() + themeDisplay.getPathMain() +
876             "/shopping/notify";
877     }
878 
879     public static String getPayPalRedirectURL(
880             ShoppingPreferences prefs, ShoppingOrder order, double total,
881             String returnURL, String notifyURL)
882         throws PortalException, SystemException {
883 
884         String payPalEmailAddress = HttpUtil.encodeURL(
885             prefs.getPayPalEmailAddress());
886 
887         NumberFormat doubleFormat = NumberFormat.getNumberInstance();
888 
889         doubleFormat.setMaximumFractionDigits(2);
890         doubleFormat.setMinimumFractionDigits(2);
891 
892         String amount = doubleFormat.format(total);
893 
894         returnURL = HttpUtil.encodeURL(returnURL);
895         notifyURL = HttpUtil.encodeURL(notifyURL);
896 
897         String firstName = HttpUtil.encodeURL(order.getBillingFirstName());
898         String lastName = HttpUtil.encodeURL(order.getBillingLastName());
899         String address1 = HttpUtil.encodeURL(order.getBillingStreet());
900         String city = HttpUtil.encodeURL(order.getBillingCity());
901         String state = HttpUtil.encodeURL(order.getBillingState());
902         String zip = HttpUtil.encodeURL(order.getBillingZip());
903 
904         String currencyCode = prefs.getCurrencyId();
905 
906         StringMaker sm = new StringMaker();
907 
908         sm.append("https://www.paypal.com/cgi-bin/webscr?");
909         sm.append("cmd=_xclick&");
910         sm.append("business=").append(payPalEmailAddress).append("&");
911         sm.append("item_name=").append(order.getOrderId()).append("&");
912         sm.append("item_number=").append(order.getOrderId()).append("&");
913         sm.append("invoice=").append(order.getOrderId()).append("&");
914         sm.append("amount=").append(amount).append("&");
915         sm.append("return=").append(returnURL).append("&");
916         sm.append("notify_url=").append(notifyURL).append("&");
917         sm.append("first_name=").append(firstName).append("&");
918         sm.append("last_name=").append(lastName).append("&");
919         sm.append("address1=").append(address1).append("&");
920         sm.append("city=").append(city).append("&");
921         sm.append("state=").append(state).append("&");
922         sm.append("zip=").append(zip).append("&");
923         sm.append("no_note=1&");
924         sm.append("currency_code=").append(currencyCode).append("");
925 
926         return sm.toString();
927     }
928 
929     public static String getPayPalReturnURL(
930         PortletURL portletURL, ShoppingOrder order) {
931 
932         portletURL.setParameter(
933             "struts_action", "/shopping/checkout");
934         portletURL.setParameter(Constants.CMD, Constants.VIEW);
935         portletURL.setParameter("orderId", String.valueOf(order.getOrderId()));
936 
937         return portletURL.toString();
938     }
939 
940     public static String getPpPaymentStatus(String ppPaymentStatus) {
941         if ((ppPaymentStatus == null) || (ppPaymentStatus.length() < 2) ||
942             (ppPaymentStatus.equals("checkout"))) {
943 
944             return ShoppingOrderImpl.STATUS_CHECKOUT;
945         }
946         else {
947             return Character.toUpperCase(ppPaymentStatus.charAt(0)) +
948                 ppPaymentStatus.substring(1, ppPaymentStatus.length());
949         }
950     }
951 
952     public static String getPpPaymentStatus(
953             ShoppingOrder order, PageContext pageContext)
954         throws PortalException {
955 
956         String ppPaymentStatus = order.getPpPaymentStatus();
957 
958         if (ppPaymentStatus.equals(ShoppingOrderImpl.STATUS_CHECKOUT)) {
959             ppPaymentStatus = "checkout";
960         }
961         else {
962             ppPaymentStatus = ppPaymentStatus.toLowerCase();
963         }
964 
965         return LanguageUtil.get(pageContext, ppPaymentStatus);
966     }
967 
968     public static boolean isInStock(ShoppingItem item) {
969         if (!item.isFields()) {
970             if (item.getStockQuantity() > 0) {
971                 return true;
972             }
973             else {
974                 return false;
975             }
976         }
977         else {
978             String[] fieldsQuantities = item.getFieldsQuantitiesArray();
979 
980             for (int i = 0; i < fieldsQuantities.length; i++) {
981                 if (GetterUtil.getInteger(fieldsQuantities[i]) > 0) {
982                     return true;
983                 }
984             }
985 
986             return false;
987         }
988     }
989 
990     public static boolean isInStock(
991         ShoppingItem item, ShoppingItemField[] itemFields,
992         String[] fieldsArray, Integer orderedQuantity) {
993 
994         if (!item.isFields()) {
995             int stockQuantity = item.getStockQuantity();
996 
997             if ((stockQuantity > 0)  &&
998                 (stockQuantity >= orderedQuantity.intValue())) {
999 
1000                return true;
1001            }
1002            else {
1003                return false;
1004            }
1005        }
1006        else {
1007            int rowPos = getFieldsQuantitiesPos(item, itemFields, fieldsArray);
1008
1009            String[] fieldsQuantities = item.getFieldsQuantitiesArray();
1010
1011            int stockQuantity = GetterUtil.getInteger(fieldsQuantities[rowPos]);
1012
1013            try {
1014                if ((stockQuantity > 0) &&
1015                    (stockQuantity >= orderedQuantity.intValue())) {
1016
1017                    return true;
1018                }
1019            }
1020            catch (Exception e) {
1021            }
1022
1023            return false;
1024        }
1025    }
1026
1027    public static boolean meetsMinOrder(ShoppingPreferences prefs, Map items)
1028        throws PortalException, SystemException {
1029
1030        if ((prefs.getMinOrder() > 0) &&
1031            (calculateSubtotal(items) < prefs.getMinOrder())) {
1032
1033            return false;
1034        }
1035        else {
1036            return true;
1037        }
1038    }
1039
1040    private static ShoppingItemPrice _getItemPrice(ShoppingItem item, int count)
1041        throws PortalException, SystemException {
1042
1043        ShoppingItemPrice itemPrice = null;
1044
1045        List itemPrices = item.getItemPrices();
1046
1047        for (int i = 0; i < itemPrices.size(); i++) {
1048            ShoppingItemPrice temp =
1049                (ShoppingItemPrice)itemPrices.get(i);
1050
1051            int minQty = temp.getMinQuantity();
1052            int maxQty = temp.getMaxQuantity();
1053
1054            if ((temp.getStatus() !=
1055                    ShoppingItemPriceImpl.STATUS_INACTIVE) &&
1056                (count >= minQty) && (count < maxQty || maxQty == 0))  {
1057
1058                itemPrice = temp;
1059            }
1060        }
1061
1062        if (itemPrice == null) {
1063            return ShoppingItemPriceUtil.create(0);
1064        }
1065
1066        return itemPrice;
1067    }
1068
1069}