001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portlet.shopping.util;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.language.LanguageUtil;
020    import com.liferay.portal.kernel.portlet.LiferayWindowState;
021    import com.liferay.portal.kernel.util.CharPool;
022    import com.liferay.portal.kernel.util.Constants;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.HttpUtil;
025    import com.liferay.portal.kernel.util.MathUtil;
026    import com.liferay.portal.kernel.util.OrderByComparator;
027    import com.liferay.portal.kernel.util.StringBundler;
028    import com.liferay.portal.kernel.util.StringPool;
029    import com.liferay.portal.kernel.util.StringUtil;
030    import com.liferay.portal.theme.ThemeDisplay;
031    import com.liferay.portal.util.WebKeys;
032    import com.liferay.portlet.shopping.NoSuchCartException;
033    import com.liferay.portlet.shopping.model.ShoppingCart;
034    import com.liferay.portlet.shopping.model.ShoppingCartItem;
035    import com.liferay.portlet.shopping.model.ShoppingCategory;
036    import com.liferay.portlet.shopping.model.ShoppingCoupon;
037    import com.liferay.portlet.shopping.model.ShoppingCouponConstants;
038    import com.liferay.portlet.shopping.model.ShoppingItem;
039    import com.liferay.portlet.shopping.model.ShoppingItemField;
040    import com.liferay.portlet.shopping.model.ShoppingItemPrice;
041    import com.liferay.portlet.shopping.model.ShoppingItemPriceConstants;
042    import com.liferay.portlet.shopping.model.ShoppingOrder;
043    import com.liferay.portlet.shopping.model.ShoppingOrderConstants;
044    import com.liferay.portlet.shopping.model.ShoppingOrderItem;
045    import com.liferay.portlet.shopping.model.impl.ShoppingCartImpl;
046    import com.liferay.portlet.shopping.service.ShoppingCartLocalServiceUtil;
047    import com.liferay.portlet.shopping.service.ShoppingCategoryLocalServiceUtil;
048    import com.liferay.portlet.shopping.service.ShoppingOrderItemLocalServiceUtil;
049    import com.liferay.portlet.shopping.service.persistence.ShoppingItemPriceUtil;
050    import com.liferay.portlet.shopping.util.comparator.ItemMinQuantityComparator;
051    import com.liferay.portlet.shopping.util.comparator.ItemNameComparator;
052    import com.liferay.portlet.shopping.util.comparator.ItemPriceComparator;
053    import com.liferay.portlet.shopping.util.comparator.ItemSKUComparator;
054    import com.liferay.portlet.shopping.util.comparator.OrderDateComparator;
055    
056    import java.text.NumberFormat;
057    
058    import java.util.ArrayList;
059    import java.util.HashMap;
060    import java.util.HashSet;
061    import java.util.Iterator;
062    import java.util.List;
063    import java.util.Locale;
064    import java.util.Map;
065    import java.util.Set;
066    
067    import javax.portlet.PortletRequest;
068    import javax.portlet.PortletSession;
069    import javax.portlet.PortletURL;
070    import javax.portlet.RenderRequest;
071    import javax.portlet.RenderResponse;
072    import javax.portlet.WindowState;
073    
074    import javax.servlet.jsp.PageContext;
075    
076    /**
077     * @author Brian Wing Shun Chan
078     */
079    public class ShoppingUtil {
080    
081            public static double calculateActualPrice(ShoppingItem item) {
082                    return item.getPrice() - calculateDiscountPrice(item);
083            }
084    
085            public static double calculateActualPrice(ShoppingItem item, int count)
086                    throws PortalException, SystemException {
087    
088                    return calculatePrice(item, count) -
089                            calculateDiscountPrice(item, count);
090            }
091    
092            public static double calculateActualPrice(ShoppingItemPrice itemPrice) {
093                    return itemPrice.getPrice() - calculateDiscountPrice(itemPrice);
094            }
095    
096            public static double calculateActualSubtotal(
097                            Map<ShoppingCartItem, Integer> items)
098                    throws PortalException, SystemException {
099    
100                    return calculateSubtotal(items) - calculateDiscountSubtotal(items);
101            }
102    
103            public static double calculateActualSubtotal(
104                    List<ShoppingOrderItem> orderItems) {
105    
106                    double subtotal = 0.0;
107    
108                    for (ShoppingOrderItem orderItem : orderItems) {
109                            subtotal += orderItem.getPrice() * orderItem.getQuantity();
110                    }
111    
112                    return subtotal;
113            }
114    
115            public static double calculateAlternativeShipping(
116                            Map<ShoppingCartItem, Integer> items, int altShipping)
117                    throws PortalException, SystemException {
118    
119                    double shipping = calculateShipping(items);
120                    double alternativeShipping = shipping;
121    
122                    ShoppingPreferences preferences = null;
123    
124                    Iterator<Map.Entry<ShoppingCartItem, Integer>> itr =
125                            items.entrySet().iterator();
126    
127                    while (itr.hasNext()) {
128                            Map.Entry<ShoppingCartItem, Integer> entry = itr.next();
129    
130                            ShoppingCartItem cartItem = entry.getKey();
131    
132                            ShoppingItem item = cartItem.getItem();
133    
134                            if (preferences == null) {
135                                    ShoppingCategory category = item.getCategory();
136    
137                                    preferences = ShoppingPreferences.getInstance(
138                                            category.getCompanyId(), category.getGroupId());
139    
140                                    break;
141                            }
142                    }
143    
144                    // Calculate alternative shipping if shopping is configured to use
145                    // alternative shipping and shipping price is greater than 0
146    
147                    if ((preferences != null) &&
148                            (preferences.useAlternativeShipping()) && (shipping > 0)) {
149    
150                            double altShippingDelta = 0.0;
151    
152                            try {
153                                    altShippingDelta = GetterUtil.getDouble(
154                                            preferences.getAlternativeShipping()[1][altShipping]);
155                            }
156                            catch (Exception e) {
157                                    return alternativeShipping;
158                            }
159    
160                            if (altShippingDelta > 0) {
161                                    alternativeShipping = shipping * altShippingDelta;
162                            }
163                    }
164    
165                    return alternativeShipping;
166            }
167    
168            public static double calculateCouponDiscount(
169                            Map<ShoppingCartItem, Integer> items, ShoppingCoupon coupon)
170                    throws PortalException, SystemException {
171    
172                    return calculateCouponDiscount(items, null, coupon);
173            }
174    
175            public static double calculateCouponDiscount(
176                            Map<ShoppingCartItem, Integer> items, String stateId,
177                            ShoppingCoupon coupon)
178                    throws PortalException, SystemException {
179    
180                    double discount = 0.0;
181    
182                    if ((coupon == null) || !coupon.isActive() ||
183                            !coupon.hasValidDateRange()) {
184    
185                            return discount;
186                    }
187    
188                    String[] categoryIds = StringUtil.split(coupon.getLimitCategories());
189                    String[] skus = StringUtil.split(coupon.getLimitSkus());
190    
191                    if ((categoryIds.length > 0) || (skus.length > 0)) {
192                            Set<String> categoryIdsSet = new HashSet<String>();
193    
194                            for (String categoryId : categoryIds) {
195                                    categoryIdsSet.add(categoryId);
196                            }
197    
198                            Set<String> skusSet = new HashSet<String>();
199    
200                            for (String sku : skus) {
201                                    skusSet.add(sku);
202                            }
203    
204                            Map<ShoppingCartItem, Integer> newItems =
205                                    new HashMap<ShoppingCartItem, Integer>();
206    
207                            Iterator<Map.Entry<ShoppingCartItem, Integer>> itr =
208                                    items.entrySet().iterator();
209    
210                            while (itr.hasNext()) {
211                                    Map.Entry<ShoppingCartItem, Integer> entry = itr.next();
212    
213                                    ShoppingCartItem cartItem = entry.getKey();
214                                    Integer count = entry.getValue();
215    
216                                    ShoppingItem item = cartItem.getItem();
217    
218                                    if (((categoryIdsSet.size() > 0) &&
219                                             (categoryIdsSet.contains(
220                                                    String.valueOf(item.getCategoryId())))) ||
221                                            ((skusSet.size() > 0) &&
222                                             (skusSet.contains(item.getSku())))) {
223    
224                                            newItems.put(cartItem, count);
225                                    }
226                            }
227    
228                            items = newItems;
229                    }
230    
231                    double actualSubtotal = calculateActualSubtotal(items);
232    
233                    if ((coupon.getMinOrder() > 0) &&
234                            (coupon.getMinOrder() > actualSubtotal)) {
235    
236                            return discount;
237                    }
238    
239                    String type = coupon.getDiscountType();
240    
241                    if (type.equals(ShoppingCouponConstants.DISCOUNT_TYPE_PERCENTAGE)) {
242                            discount = actualSubtotal * coupon.getDiscount();
243                    }
244                    else if (type.equals(ShoppingCouponConstants.DISCOUNT_TYPE_ACTUAL)) {
245                            discount = coupon.getDiscount();
246                    }
247                    else if (type.equals(
248                                            ShoppingCouponConstants.DISCOUNT_TYPE_FREE_SHIPPING)) {
249    
250                            discount = calculateShipping(items);
251                    }
252                    else if (type.equals(ShoppingCouponConstants.DISCOUNT_TYPE_TAX_FREE)) {
253                            if (stateId != null) {
254                                    discount = calculateTax(items, stateId);
255                            }
256                    }
257    
258                    return discount;
259            }
260    
261            public static double calculateDiscountPercent(
262                            Map<ShoppingCartItem, Integer> items)
263                    throws PortalException, SystemException {
264    
265                    double discount =
266                            calculateDiscountSubtotal(items) / calculateSubtotal(items);
267    
268                    if (Double.isNaN(discount) || Double.isInfinite(discount)) {
269                            discount = 0.0;
270                    }
271    
272                    return discount;
273            }
274    
275            public static double calculateDiscountPrice(ShoppingItem item) {
276                    return item.getPrice() * item.getDiscount();
277            }
278    
279            public static double calculateDiscountPrice(ShoppingItem item, int count)
280                    throws PortalException, SystemException {
281    
282                    ShoppingItemPrice itemPrice = _getItemPrice(item, count);
283    
284                    return itemPrice.getPrice() * itemPrice.getDiscount() * count;
285            }
286    
287            public static double calculateDiscountPrice(ShoppingItemPrice itemPrice) {
288                    return itemPrice.getPrice() * itemPrice.getDiscount();
289            }
290    
291            public static double calculateDiscountSubtotal(
292                            Map<ShoppingCartItem, Integer> items)
293                    throws PortalException, SystemException {
294    
295                    double subtotal = 0.0;
296    
297                    Iterator<Map.Entry<ShoppingCartItem, Integer>> itr =
298                            items.entrySet().iterator();
299    
300                    while (itr.hasNext()) {
301                            Map.Entry<ShoppingCartItem, Integer> entry = itr.next();
302    
303                            ShoppingCartItem cartItem = entry.getKey();
304                            Integer count = entry.getValue();
305    
306                            ShoppingItem item = cartItem.getItem();
307    
308                            subtotal += calculateDiscountPrice(item, count.intValue());
309                    }
310    
311                    return subtotal;
312            }
313    
314            public static double calculateInsurance(
315                            Map<ShoppingCartItem, Integer> items)
316                    throws PortalException, SystemException {
317    
318                    double insurance = 0.0;
319                    double subtotal = 0.0;
320    
321                    ShoppingPreferences preferences = null;
322    
323                    Iterator<Map.Entry<ShoppingCartItem, Integer>> itr =
324                            items.entrySet().iterator();
325    
326                    while (itr.hasNext()) {
327                            Map.Entry<ShoppingCartItem, Integer> entry = itr.next();
328    
329                            ShoppingCartItem cartItem = entry.getKey();
330                            Integer count = entry.getValue();
331    
332                            ShoppingItem item = cartItem.getItem();
333    
334                            if (preferences == null) {
335                                    ShoppingCategory category = item.getCategory();
336    
337                                    preferences = ShoppingPreferences.getInstance(
338                                            category.getCompanyId(), category.getGroupId());
339                            }
340    
341                            ShoppingItemPrice itemPrice =
342                                    _getItemPrice(item, count.intValue());
343    
344                            subtotal += calculateActualPrice(itemPrice) * count.intValue();
345                    }
346    
347                    if ((preferences != null) && (subtotal > 0)) {
348                            double insuranceRate = 0.0;
349    
350                            double[] range = ShoppingPreferences.INSURANCE_RANGE;
351    
352                            for (int i = 0; i < range.length - 1; i++) {
353                                    if (subtotal > range[i] && subtotal <= range[i + 1]) {
354                                            int rangeId = i / 2;
355                                            if (MathUtil.isOdd(i)) {
356                                                    rangeId = (i + 1) / 2;
357                                            }
358    
359                                            insuranceRate = GetterUtil.getDouble(
360                                                    preferences.getInsurance()[rangeId]);
361                                    }
362                            }
363    
364                            String formula = preferences.getInsuranceFormula();
365    
366                            if (formula.equals("flat")) {
367                                    insurance += insuranceRate;
368                            }
369                            else if (formula.equals("percentage")) {
370                                    insurance += subtotal * insuranceRate;
371                            }
372                    }
373    
374                    return insurance;
375            }
376    
377            public static double calculatePrice(ShoppingItem item, int count)
378                    throws PortalException, SystemException {
379    
380                    ShoppingItemPrice itemPrice = _getItemPrice(item, count);
381    
382                    return itemPrice.getPrice() * count;
383            }
384    
385            public static double calculateShipping(Map<ShoppingCartItem, Integer> items)
386                    throws PortalException, SystemException {
387    
388                    double shipping = 0.0;
389                    double subtotal = 0.0;
390    
391                    ShoppingPreferences preferences = null;
392    
393                    Iterator<Map.Entry<ShoppingCartItem, Integer>> itr =
394                            items.entrySet().iterator();
395    
396                    while (itr.hasNext()) {
397                            Map.Entry<ShoppingCartItem, Integer> entry = itr.next();
398    
399                            ShoppingCartItem cartItem = entry.getKey();
400                            Integer count = entry.getValue();
401    
402                            ShoppingItem item = cartItem.getItem();
403    
404                            if (preferences == null) {
405                                    ShoppingCategory category = item.getCategory();
406    
407                                    preferences = ShoppingPreferences.getInstance(
408                                            category.getCompanyId(), category.getGroupId());
409                            }
410    
411                            if (item.isRequiresShipping()) {
412                                    ShoppingItemPrice itemPrice =
413                                            _getItemPrice(item, count.intValue());
414    
415                                    if (itemPrice.isUseShippingFormula()) {
416                                            subtotal +=
417                                                    calculateActualPrice(itemPrice) * count.intValue();
418                                    }
419                                    else {
420                                            shipping += itemPrice.getShipping() * count.intValue();
421                                    }
422                            }
423                    }
424    
425                    if ((preferences != null) && (subtotal > 0)) {
426                            double shippingRate = 0.0;
427    
428                            double[] range = ShoppingPreferences.SHIPPING_RANGE;
429    
430                            for (int i = 0; i < range.length - 1; i++) {
431                                    if (subtotal > range[i] && subtotal <= range[i + 1]) {
432                                            int rangeId = i / 2;
433                                            if (MathUtil.isOdd(i)) {
434                                                    rangeId = (i + 1) / 2;
435                                            }
436    
437                                            shippingRate = GetterUtil.getDouble(
438                                                    preferences.getShipping()[rangeId]);
439                                    }
440                            }
441    
442                            String formula = preferences.getShippingFormula();
443    
444                            if (formula.equals("flat")) {
445                                    shipping += shippingRate;
446                            }
447                            else if (formula.equals("percentage")) {
448                                    shipping += subtotal * shippingRate;
449                            }
450                    }
451    
452                    return shipping;
453            }
454    
455            public static double calculateSubtotal(Map<ShoppingCartItem, Integer> items)
456                    throws PortalException, SystemException {
457    
458                    double subtotal = 0.0;
459    
460                    Iterator<Map.Entry<ShoppingCartItem, Integer>> itr =
461                            items.entrySet().iterator();
462    
463                    while (itr.hasNext()) {
464                            Map.Entry<ShoppingCartItem, Integer> entry = itr.next();
465    
466                            ShoppingCartItem cartItem = entry.getKey();
467                            Integer count = entry.getValue();
468    
469                            ShoppingItem item = cartItem.getItem();
470    
471                            subtotal += calculatePrice(item, count.intValue());
472                    }
473    
474                    return subtotal;
475            }
476    
477            public static double calculateTax(
478                            Map<ShoppingCartItem, Integer> items, String stateId)
479                    throws PortalException, SystemException {
480    
481                    double tax = 0.0;
482    
483                    ShoppingPreferences preferences = null;
484    
485                    Iterator<Map.Entry<ShoppingCartItem, Integer>> itr =
486                            items.entrySet().iterator();
487    
488                    while (itr.hasNext()) {
489                            Map.Entry<ShoppingCartItem, Integer> entry = itr.next();
490    
491                            ShoppingCartItem cartItem = entry.getKey();
492    
493                            ShoppingItem item = cartItem.getItem();
494    
495                            if (preferences == null) {
496                                    ShoppingCategory category = item.getCategory();
497    
498                                    preferences = ShoppingPreferences.getInstance(
499                                            category.getCompanyId(), category.getGroupId());
500    
501                                    break;
502                            }
503                    }
504    
505                    if ((preferences != null) &&
506                            (preferences.getTaxState().equals(stateId))) {
507    
508                            double subtotal = 0.0;
509    
510                            itr = items.entrySet().iterator();
511    
512                            while (itr.hasNext()) {
513                                    Map.Entry<ShoppingCartItem, Integer> entry = itr.next();
514    
515                                    ShoppingCartItem cartItem = entry.getKey();
516                                    Integer count = entry.getValue();
517    
518                                    ShoppingItem item = cartItem.getItem();
519    
520                                    if (item.isTaxable()) {
521                                            subtotal += calculatePrice(item, count.intValue());
522                                    }
523                            }
524    
525                            tax = preferences.getTaxRate() * subtotal;
526                    }
527    
528                    return tax;
529            }
530    
531            public static double calculateTotal(
532                            Map<ShoppingCartItem, Integer> items, String stateId,
533                            ShoppingCoupon coupon, int altShipping, boolean insure)
534                    throws PortalException, SystemException {
535    
536                    double actualSubtotal = calculateActualSubtotal(items);
537                    double tax = calculateTax(items, stateId);
538                    double shipping = calculateAlternativeShipping(items, altShipping);
539    
540                    double insurance = 0.0;
541                    if (insure) {
542                            insurance = calculateInsurance(items);
543                    }
544    
545                    double couponDiscount = calculateCouponDiscount(items, stateId, coupon);
546    
547                    double total =
548                            actualSubtotal + tax + shipping + insurance - couponDiscount;
549    
550                    if (total < 0) {
551                            total = 0.0;
552                    }
553    
554                    return total;
555            }
556    
557            public static double calculateTotal(ShoppingOrder order)
558                    throws SystemException {
559    
560                    List<ShoppingOrderItem> orderItems =
561                            ShoppingOrderItemLocalServiceUtil.getOrderItems(order.getOrderId());
562    
563                    double total =
564                            calculateActualSubtotal(orderItems) + order.getTax() +
565                                    order.getShipping() + order.getInsurance() -
566                                            order.getCouponDiscount();
567    
568                    if (total < 0) {
569                            total = 0.0;
570                    }
571    
572                    return total;
573            }
574    
575            public static String getBreadcrumbs(
576                            long categoryId, PageContext pageContext,
577                            RenderRequest renderRequest, RenderResponse renderResponse)
578                    throws Exception {
579    
580                    ShoppingCategory category = null;
581    
582                    try {
583                            category = ShoppingCategoryLocalServiceUtil.getCategory(categoryId);
584                    }
585                    catch (Exception e) {
586                    }
587    
588                    return getBreadcrumbs(
589                            category, pageContext, renderRequest, renderResponse);
590            }
591    
592            public static String getBreadcrumbs(
593                            ShoppingCategory category, PageContext pageContext,
594                            RenderRequest renderRequest, RenderResponse renderResponse)
595                    throws Exception {
596    
597                    PortletURL categoriesURL = renderResponse.createRenderURL();
598    
599                    WindowState windowState = renderRequest.getWindowState();
600    
601                    if (windowState.equals(LiferayWindowState.POP_UP)) {
602                            categoriesURL.setWindowState(LiferayWindowState.POP_UP);
603    
604                            categoriesURL.setParameter(
605                                    "struts_action", "/shopping/select_category");
606                    }
607                    else {
608                            //categoriesURL.setWindowState(WindowState.MAXIMIZED);
609    
610                            categoriesURL.setParameter("struts_action", "/shopping/view");
611                            categoriesURL.setParameter("tabs1", "categories");
612                    }
613    
614                    String categoriesLink =
615                            "<a href=\"" + categoriesURL.toString() + "\">" +
616                                    LanguageUtil.get(pageContext, "categories") + "</a>";
617    
618                    if (category == null) {
619                            return "<span class=\"first last\">" + categoriesLink + "</span>";
620                    }
621    
622                    String breadcrumbs = StringPool.BLANK;
623    
624                    if (category != null) {
625                            for (int i = 0;; i++) {
626                                    category = category.toEscapedModel();
627    
628                                    PortletURL portletURL = renderResponse.createRenderURL();
629    
630                                    if (windowState.equals(LiferayWindowState.POP_UP)) {
631                                            portletURL.setWindowState(LiferayWindowState.POP_UP);
632    
633                                            portletURL.setParameter(
634                                                    "struts_action", "/shopping/select_category");
635                                            portletURL.setParameter(
636                                                    "categoryId", String.valueOf(category.getCategoryId()));
637                                    }
638                                    else {
639                                            //portletURL.setWindowState(WindowState.MAXIMIZED);
640    
641                                            portletURL.setParameter("struts_action", "/shopping/view");
642                                            portletURL.setParameter("tabs1", "categories");
643                                            portletURL.setParameter(
644                                                    "categoryId", String.valueOf(category.getCategoryId()));
645                                    }
646    
647                                    String categoryLink =
648                                            "<a href=\"" + portletURL.toString() + "\">" +
649                                                    category.getName() + "</a>";
650    
651                                    if (i == 0) {
652                                            breadcrumbs =
653                                                    "<span class=\"last\">" + categoryLink + "</span>";
654                                    }
655                                    else {
656                                            breadcrumbs = categoryLink + " &raquo; " + breadcrumbs;
657                                    }
658    
659                                    if (category.isRoot()) {
660                                            break;
661                                    }
662    
663                                    category = ShoppingCategoryLocalServiceUtil.getCategory(
664                                            category.getParentCategoryId());
665                            }
666                    }
667    
668                    breadcrumbs =
669                            "<span class=\"first\">" + categoriesLink + " &raquo; </span>" +
670                                    breadcrumbs;
671    
672                    return breadcrumbs;
673            }
674    
675            public static ShoppingCart getCart(ThemeDisplay themeDisplay) {
676                    ShoppingCart cart = new ShoppingCartImpl();
677    
678                    cart.setGroupId(themeDisplay.getScopeGroupId());
679                    cart.setCompanyId(themeDisplay.getCompanyId());
680                    cart.setUserId(themeDisplay.getUserId());
681                    cart.setItemIds(StringPool.BLANK);
682                    cart.setCouponCodes(StringPool.BLANK);
683                    cart.setAltShipping(0);
684                    cart.setInsure(false);
685    
686                    return cart;
687            }
688    
689            public static ShoppingCart getCart(PortletRequest portletRequest)
690                    throws PortalException, SystemException {
691    
692                    PortletSession portletSession = portletRequest.getPortletSession();
693    
694                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
695                            WebKeys.THEME_DISPLAY);
696    
697                    String sessionCartId =
698                            ShoppingCart.class.getName() + themeDisplay.getScopeGroupId();
699    
700                    if (themeDisplay.isSignedIn()) {
701                            ShoppingCart cart = (ShoppingCart)portletSession.getAttribute(
702                                    sessionCartId);
703    
704                            if (cart != null) {
705                                    portletSession.removeAttribute(sessionCartId);
706                            }
707    
708                            if ((cart != null) && (cart.getItemsSize() > 0)) {
709                                    cart = ShoppingCartLocalServiceUtil.updateCart(
710                                            themeDisplay.getUserId(), themeDisplay.getScopeGroupId(),
711                                            cart.getItemIds(), cart.getCouponCodes(),
712                                            cart.getAltShipping(), cart.isInsure());
713                            }
714                            else {
715                                    try {
716                                            cart = ShoppingCartLocalServiceUtil.getCart(
717                                                    themeDisplay.getUserId(),
718                                                    themeDisplay.getScopeGroupId());
719                                    }
720                                    catch (NoSuchCartException nsce) {
721                                            cart = getCart(themeDisplay);
722    
723                                            cart = ShoppingCartLocalServiceUtil.updateCart(
724                                                    themeDisplay.getUserId(),
725                                                    themeDisplay.getScopeGroupId(), cart.getItemIds(),
726                                                    cart.getCouponCodes(), cart.getAltShipping(),
727                                                    cart.isInsure());
728                                    }
729                            }
730    
731                            return cart;
732                    }
733                    else {
734                            ShoppingCart cart = (ShoppingCart)portletSession.getAttribute(
735                                    sessionCartId);
736    
737                            if (cart == null) {
738                                    cart = getCart(themeDisplay);
739    
740                                    portletSession.setAttribute(sessionCartId, cart);
741                            }
742    
743                            return cart;
744                    }
745            }
746    
747            public static int getFieldsQuantitiesPos(
748                    ShoppingItem item, ShoppingItemField[] itemFields,
749                    String[] fieldsArray) {
750    
751                    Set<String> fieldsValues = new HashSet<String>();
752    
753                    for (String fields : fieldsArray) {
754                            int pos = fields.indexOf("=");
755    
756                            String fieldValue = fields.substring(
757                                    pos + 1, fields.length()).trim();
758    
759                            fieldsValues.add(fieldValue);
760                    }
761    
762                    List<String> names = new ArrayList<String>();
763                    List<String[]> values = new ArrayList<String[]>();
764    
765                    for (int i = 0; i < itemFields.length; i++) {
766                            names.add(itemFields[i].getName());
767                            values.add(StringUtil.split(itemFields[i].getValues()));
768                    }
769    
770                    int numOfRows = 1;
771    
772                    for (String[] vArray : values) {
773                            numOfRows = numOfRows * vArray.length;
774                    }
775    
776                    int rowPos = 0;
777    
778                    for (int i = 0; i < numOfRows; i++) {
779                            boolean match = true;
780    
781                            for (int j = 0; j < names.size(); j++) {
782                                    int numOfRepeats = 1;
783    
784                                    for (int k = j + 1; k < values.size(); k++) {
785                                            String[] vArray = values.get(k);
786    
787                                            numOfRepeats = numOfRepeats * vArray.length;
788                                    }
789    
790                                    String[] vArray = values.get(j);
791    
792                                    int arrayPos;
793                                    for (arrayPos = i / numOfRepeats;
794                                             arrayPos >= vArray.length;
795                                             arrayPos = arrayPos - vArray.length) {
796                                    }
797    
798                                    if (!fieldsValues.contains(vArray[arrayPos].trim())) {
799                                            match = false;
800    
801                                            break;
802                                    }
803                            }
804    
805                            if (match) {
806                                    rowPos = i;
807    
808                                    break;
809                            }
810                    }
811    
812                    return rowPos;
813            }
814    
815            public static long getItemId(String itemId) {
816                    int pos = itemId.indexOf(CharPool.PIPE);
817    
818                    if (pos != -1) {
819                            itemId = itemId.substring(0, pos);
820                    }
821    
822                    return GetterUtil.getLong(itemId);
823            }
824    
825            public static String getItemFields(String itemId) {
826                    int pos = itemId.indexOf(CharPool.PIPE);
827    
828                    if (pos == -1) {
829                            return StringPool.BLANK;
830                    }
831                    else {
832                            return itemId.substring(pos + 1, itemId.length());
833                    }
834            }
835    
836            public static OrderByComparator getItemOrderByComparator(
837                    String orderByCol, String orderByType) {
838    
839                    boolean orderByAsc = false;
840    
841                    if (orderByType.equals("asc")) {
842                            orderByAsc = true;
843                    }
844    
845                    OrderByComparator orderByComparator = null;
846    
847                    if (orderByCol.equals("min-qty")) {
848                            orderByComparator = new ItemMinQuantityComparator(orderByAsc);
849                    }
850                    else if (orderByCol.equals("name")) {
851                            orderByComparator = new ItemNameComparator(orderByAsc);
852                    }
853                    else if (orderByCol.equals("price")) {
854                            orderByComparator = new ItemPriceComparator(orderByAsc);
855                    }
856                    else if (orderByCol.equals("sku")) {
857                            orderByComparator = new ItemSKUComparator(orderByAsc);
858                    }
859                    else if (orderByCol.equals("order-date")) {
860                            orderByComparator = new OrderDateComparator(orderByAsc);
861                    }
862    
863                    return orderByComparator;
864            }
865    
866            public static int getMinQuantity(ShoppingItem item)
867                    throws PortalException, SystemException {
868    
869                    int minQuantity = item.getMinQuantity();
870    
871                    List<ShoppingItemPrice> itemPrices = item.getItemPrices();
872    
873                    for (ShoppingItemPrice itemPrice : itemPrices) {
874                            if (minQuantity > itemPrice.getMinQuantity()) {
875                                    minQuantity = itemPrice.getMinQuantity();
876                            }
877                    }
878    
879                    return minQuantity;
880            }
881    
882            public static String getPayPalNotifyURL(ThemeDisplay themeDisplay) {
883                    return themeDisplay.getPortalURL() + themeDisplay.getPathMain() +
884                            "/shopping/notify";
885            }
886    
887            public static String getPayPalRedirectURL(
888                    ShoppingPreferences preferences, ShoppingOrder order, double total,
889                    String returnURL, String notifyURL) {
890    
891                    String payPalEmailAddress = HttpUtil.encodeURL(
892                            preferences.getPayPalEmailAddress());
893    
894                    NumberFormat doubleFormat = NumberFormat.getNumberInstance(
895                            Locale.ENGLISH);
896    
897                    doubleFormat.setMaximumFractionDigits(2);
898                    doubleFormat.setMinimumFractionDigits(2);
899    
900                    String amount = doubleFormat.format(total);
901    
902                    returnURL = HttpUtil.encodeURL(returnURL);
903                    notifyURL = HttpUtil.encodeURL(notifyURL);
904    
905                    String firstName = HttpUtil.encodeURL(order.getBillingFirstName());
906                    String lastName = HttpUtil.encodeURL(order.getBillingLastName());
907                    String address1 = HttpUtil.encodeURL(order.getBillingStreet());
908                    String city = HttpUtil.encodeURL(order.getBillingCity());
909                    String state = HttpUtil.encodeURL(order.getBillingState());
910                    String zip = HttpUtil.encodeURL(order.getBillingZip());
911    
912                    String currencyCode = preferences.getCurrencyId();
913    
914                    StringBundler sb = new StringBundler(45);
915    
916                    sb.append("https://www.paypal.com/cgi-bin/webscr?");
917                    sb.append("cmd=_xclick&");
918                    sb.append("business=").append(payPalEmailAddress).append("&");
919                    sb.append("item_name=").append(order.getNumber()).append("&");
920                    sb.append("item_number=").append(order.getNumber()).append("&");
921                    sb.append("invoice=").append(order.getNumber()).append("&");
922                    sb.append("amount=").append(amount).append("&");
923                    sb.append("return=").append(returnURL).append("&");
924                    sb.append("notify_url=").append(notifyURL).append("&");
925                    sb.append("first_name=").append(firstName).append("&");
926                    sb.append("last_name=").append(lastName).append("&");
927                    sb.append("address1=").append(address1).append("&");
928                    sb.append("city=").append(city).append("&");
929                    sb.append("state=").append(state).append("&");
930                    sb.append("zip=").append(zip).append("&");
931                    sb.append("no_note=1&");
932                    sb.append("currency_code=").append(currencyCode).append("");
933    
934                    return sb.toString();
935            }
936    
937            public static String getPayPalReturnURL(
938                    PortletURL portletURL, ShoppingOrder order) {
939    
940                    portletURL.setParameter(
941                            "struts_action", "/shopping/checkout");
942                    portletURL.setParameter(Constants.CMD, Constants.VIEW);
943                    portletURL.setParameter("orderId", String.valueOf(order.getOrderId()));
944    
945                    return portletURL.toString();
946            }
947    
948            public static String getPpPaymentStatus(String ppPaymentStatus) {
949                    if ((ppPaymentStatus == null) || (ppPaymentStatus.length() < 2) ||
950                            (ppPaymentStatus.equals("checkout"))) {
951    
952                            return ShoppingOrderConstants.STATUS_CHECKOUT;
953                    }
954                    else {
955                            return Character.toUpperCase(ppPaymentStatus.charAt(0)) +
956                                    ppPaymentStatus.substring(1, ppPaymentStatus.length());
957                    }
958            }
959    
960            public static String getPpPaymentStatus(
961                    ShoppingOrder order, PageContext pageContext) {
962    
963                    String ppPaymentStatus = order.getPpPaymentStatus();
964    
965                    if (ppPaymentStatus.equals(ShoppingOrderConstants.STATUS_CHECKOUT)) {
966                            ppPaymentStatus = "checkout";
967                    }
968                    else {
969                            ppPaymentStatus = ppPaymentStatus.toLowerCase();
970                    }
971    
972                    return LanguageUtil.get(pageContext, ppPaymentStatus);
973            }
974    
975            public static boolean isInStock(ShoppingItem item) {
976                    if (!item.isFields()) {
977                            if (item.getStockQuantity() > 0) {
978                                    return true;
979                            }
980                            else {
981                                    return false;
982                            }
983                    }
984                    else {
985                            String[] fieldsQuantities = item.getFieldsQuantitiesArray();
986    
987                            for (int i = 0; i < fieldsQuantities.length; i++) {
988                                    if (GetterUtil.getInteger(fieldsQuantities[i]) > 0) {
989                                            return true;
990                                    }
991                            }
992    
993                            return false;
994                    }
995            }
996    
997            public static boolean isInStock(
998                    ShoppingItem item, ShoppingItemField[] itemFields,
999                    String[] fieldsArray, Integer orderedQuantity) {
1000    
1001                    if (!item.isFields()) {
1002                            int stockQuantity = item.getStockQuantity();
1003    
1004                            if ((stockQuantity > 0)  &&
1005                                    (stockQuantity >= orderedQuantity.intValue())) {
1006    
1007                                    return true;
1008                            }
1009                            else {
1010                                    return false;
1011                            }
1012                    }
1013                    else {
1014                            int rowPos = getFieldsQuantitiesPos(item, itemFields, fieldsArray);
1015    
1016                            String[] fieldsQuantities = item.getFieldsQuantitiesArray();
1017    
1018                            int stockQuantity = GetterUtil.getInteger(fieldsQuantities[rowPos]);
1019    
1020                            try {
1021                                    if ((stockQuantity > 0) &&
1022                                            (stockQuantity >= orderedQuantity.intValue())) {
1023    
1024                                            return true;
1025                                    }
1026                            }
1027                            catch (Exception e) {
1028                            }
1029    
1030                            return false;
1031                    }
1032            }
1033    
1034            public static boolean meetsMinOrder(
1035                            ShoppingPreferences preferences,
1036                            Map<ShoppingCartItem, Integer> items)
1037                    throws PortalException, SystemException {
1038    
1039                    if ((preferences.getMinOrder() > 0) &&
1040                            (calculateSubtotal(items) < preferences.getMinOrder())) {
1041    
1042                            return false;
1043                    }
1044                    else {
1045                            return true;
1046                    }
1047            }
1048    
1049            private static ShoppingItemPrice _getItemPrice(ShoppingItem item, int count)
1050                    throws PortalException, SystemException {
1051    
1052                    ShoppingItemPrice itemPrice = null;
1053    
1054                    List<ShoppingItemPrice> itemPrices = item.getItemPrices();
1055    
1056                    for (ShoppingItemPrice temp : itemPrices) {
1057                            int minQty = temp.getMinQuantity();
1058                            int maxQty = temp.getMaxQuantity();
1059    
1060                            if ((temp.getStatus() !=
1061                                            ShoppingItemPriceConstants.STATUS_INACTIVE)) {
1062    
1063                                    if ((count >= minQty) && ((count <= maxQty) || (maxQty == 0))) {
1064                                            return temp;
1065                                    }
1066    
1067                                    if ((count > maxQty) &&
1068                                            ((itemPrice == null) ||
1069                                             (itemPrice.getMaxQuantity() < maxQty))) {
1070    
1071                                            itemPrice = temp;
1072                                    }
1073                            }
1074                    }
1075    
1076                    if (itemPrice == null) {
1077                            return ShoppingItemPriceUtil.create(0);
1078                    }
1079    
1080                    return itemPrice;
1081            }
1082    
1083    }