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