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