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