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