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;
823 arrayPos >= vArray.length;
824 arrayPos = arrayPos - vArray.length) {
825 }
826
827 if (!fieldsValues.contains(vArray[arrayPos].trim())) {
828 match = false;
829
830 break;
831 }
832 }
833
834 if (match) {
835 rowPos = i;
836
837 break;
838 }
839 }
840
841 return rowPos;
842 }
843
844 public static String getItemFields(String itemId) {
845 int pos = itemId.indexOf(CharPool.PIPE);
846
847 if (pos == -1) {
848 return StringPool.BLANK;
849 }
850 else {
851 return itemId.substring(pos + 1);
852 }
853 }
854
855 public static long getItemId(String itemId) {
856 int pos = itemId.indexOf(CharPool.PIPE);
857
858 if (pos != -1) {
859 itemId = itemId.substring(0, pos);
860 }
861
862 return GetterUtil.getLong(itemId);
863 }
864
865 public static OrderByComparator<ShoppingItem> getItemOrderByComparator(
866 String orderByCol, String orderByType) {
867
868 boolean orderByAsc = false;
869
870 if (orderByType.equals("asc")) {
871 orderByAsc = true;
872 }
873
874 OrderByComparator<ShoppingItem> orderByComparator = null;
875
876 if (orderByCol.equals("min-qty")) {
877 orderByComparator = new ItemMinQuantityComparator(orderByAsc);
878 }
879 else if (orderByCol.equals("name")) {
880 orderByComparator = new ItemNameComparator(orderByAsc);
881 }
882 else if (orderByCol.equals("price")) {
883 orderByComparator = new ItemPriceComparator(orderByAsc);
884 }
885 else if (orderByCol.equals("sku")) {
886 orderByComparator = new ItemSKUComparator(orderByAsc);
887 }
888
889 return orderByComparator;
890 }
891
892 public static int getMinQuantity(ShoppingItem item) throws PortalException {
893 int minQuantity = item.getMinQuantity();
894
895 List<ShoppingItemPrice> itemPrices = item.getItemPrices();
896
897 for (ShoppingItemPrice itemPrice : itemPrices) {
898 if (minQuantity > itemPrice.getMinQuantity()) {
899 minQuantity = itemPrice.getMinQuantity();
900 }
901 }
902
903 return minQuantity;
904 }
905
906 public static String getPayPalNotifyURL(ThemeDisplay themeDisplay) {
907 return themeDisplay.getPortalURL() + themeDisplay.getPathMain() +
908 "/shopping/notify";
909 }
910
911 public static String getPayPalRedirectURL(
912 ShoppingSettings shoppingSettings, ShoppingOrder order, double total,
913 String returnURL, String notifyURL) {
914
915 String payPalEmailAddress = HttpUtil.encodeURL(
916 shoppingSettings.getPayPalEmailAddress());
917
918 NumberFormat doubleFormat = NumberFormat.getNumberInstance(
919 LocaleUtil.ENGLISH);
920
921 doubleFormat.setMaximumFractionDigits(2);
922 doubleFormat.setMinimumFractionDigits(2);
923
924 String amount = doubleFormat.format(total);
925
926 returnURL = HttpUtil.encodeURL(returnURL);
927 notifyURL = HttpUtil.encodeURL(notifyURL);
928
929 String firstName = HttpUtil.encodeURL(order.getBillingFirstName());
930 String lastName = HttpUtil.encodeURL(order.getBillingLastName());
931 String address1 = HttpUtil.encodeURL(order.getBillingStreet());
932 String city = HttpUtil.encodeURL(order.getBillingCity());
933 String state = HttpUtil.encodeURL(order.getBillingState());
934 String zip = HttpUtil.encodeURL(order.getBillingZip());
935
936 String currencyCode = shoppingSettings.getCurrencyId();
937
938 StringBundler sb = new StringBundler(45);
939
940 sb.append("https:
941 sb.append("cmd=_xclick&");
942 sb.append("business=").append(payPalEmailAddress).append("&");
943 sb.append("item_name=").append(order.getNumber()).append("&");
944 sb.append("item_number=").append(order.getNumber()).append("&");
945 sb.append("invoice=").append(order.getNumber()).append("&");
946 sb.append("amount=").append(amount).append("&");
947 sb.append("return=").append(returnURL).append("&");
948 sb.append("notify_url=").append(notifyURL).append("&");
949 sb.append("first_name=").append(firstName).append("&");
950 sb.append("last_name=").append(lastName).append("&");
951 sb.append("address1=").append(address1).append("&");
952 sb.append("city=").append(city).append("&");
953 sb.append("state=").append(state).append("&");
954 sb.append("zip=").append(zip).append("&");
955 sb.append("no_note=1&");
956 sb.append("currency_code=").append(currencyCode).append("");
957
958 return sb.toString();
959 }
960
961 public static String getPayPalReturnURL(
962 PortletURL portletURL, ShoppingOrder order) {
963
964 portletURL.setParameter("struts_action", "/shopping/checkout");
965 portletURL.setParameter(Constants.CMD, Constants.VIEW);
966 portletURL.setParameter("orderId", String.valueOf(order.getOrderId()));
967
968 return portletURL.toString();
969 }
970
971 public static String getPpPaymentStatus(
972 ShoppingOrder order, HttpServletRequest request) {
973
974 String ppPaymentStatus = order.getPpPaymentStatus();
975
976 if (ppPaymentStatus.equals(ShoppingOrderConstants.STATUS_CHECKOUT)) {
977 ppPaymentStatus = "checkout";
978 }
979 else {
980 ppPaymentStatus = StringUtil.toLowerCase(ppPaymentStatus);
981 }
982
983 return LanguageUtil.get(request, HtmlUtil.escape(ppPaymentStatus));
984 }
985
986 public static String getPpPaymentStatus(String ppPaymentStatus) {
987 if ((ppPaymentStatus == null) || (ppPaymentStatus.length() < 2) ||
988 ppPaymentStatus.equals("checkout")) {
989
990 return ShoppingOrderConstants.STATUS_CHECKOUT;
991 }
992 else {
993 return Character.toUpperCase(ppPaymentStatus.charAt(0)) +
994 ppPaymentStatus.substring(1);
995 }
996 }
997
998 public static boolean isInStock(ShoppingItem item) {
999 if (item.isInfiniteStock()) {
1000 return true;
1001 }
1002
1003 if (!item.isFields()) {
1004 if (item.getStockQuantity() > 0) {
1005 return true;
1006 }
1007 else {
1008 return false;
1009 }
1010 }
1011 else {
1012 String[] fieldsQuantities = item.getFieldsQuantitiesArray();
1013
1014 for (int i = 0; i < fieldsQuantities.length; i++) {
1015 if (GetterUtil.getInteger(fieldsQuantities[i]) > 0) {
1016 return true;
1017 }
1018 }
1019
1020 return false;
1021 }
1022 }
1023
1024 public static boolean isInStock(
1025 ShoppingItem item, ShoppingItemField[] itemFields, String[] fieldsArray,
1026 Integer orderedQuantity) {
1027
1028 if (item.isInfiniteStock()) {
1029 return true;
1030 }
1031
1032 if (!item.isFields()) {
1033 int stockQuantity = item.getStockQuantity();
1034
1035 if ((stockQuantity > 0) &&
1036 (stockQuantity >= orderedQuantity.intValue())) {
1037
1038 return true;
1039 }
1040 else {
1041 return false;
1042 }
1043 }
1044 else {
1045 String[] fieldsQuantities = item.getFieldsQuantitiesArray();
1046
1047 int stockQuantity = 0;
1048
1049 if (fieldsQuantities.length > 0) {
1050 int rowPos = getFieldsQuantitiesPos(
1051 item, itemFields, fieldsArray);
1052
1053 stockQuantity = GetterUtil.getInteger(fieldsQuantities[rowPos]);
1054 }
1055
1056 try {
1057 if ((stockQuantity > 0) &&
1058 (stockQuantity >= orderedQuantity.intValue())) {
1059
1060 return true;
1061 }
1062 }
1063 catch (Exception e) {
1064 }
1065
1066 return false;
1067 }
1068 }
1069
1070 public static boolean meetsMinOrder(
1071 ShoppingSettings shoppingSettings,
1072 Map<ShoppingCartItem, Integer> items)
1073 throws PortalException {
1074
1075 if ((shoppingSettings.getMinOrder() > 0) &&
1076 (calculateSubtotal(items) < shoppingSettings.getMinOrder())) {
1077
1078 return false;
1079 }
1080 else {
1081 return true;
1082 }
1083 }
1084
1085 private static ShoppingItemPrice _getItemPrice(ShoppingItem item, int count)
1086 throws PortalException {
1087
1088 ShoppingItemPrice itemPrice = null;
1089
1090 List<ShoppingItemPrice> itemPrices = item.getItemPrices();
1091
1092 for (ShoppingItemPrice temp : itemPrices) {
1093 int minQty = temp.getMinQuantity();
1094 int maxQty = temp.getMaxQuantity();
1095
1096 if (temp.getStatus() !=
1097 ShoppingItemPriceConstants.STATUS_INACTIVE) {
1098
1099 if ((count >= minQty) && ((count <= maxQty) || (maxQty == 0))) {
1100 return temp;
1101 }
1102
1103 if ((count > maxQty) &&
1104 ((itemPrice == null) ||
1105 (itemPrice.getMaxQuantity() < maxQty))) {
1106
1107 itemPrice = temp;
1108 }
1109 }
1110 }
1111
1112 if (itemPrice == null) {
1113 return ShoppingItemPriceUtil.create(0);
1114 }
1115
1116 return itemPrice;
1117 }
1118
1119 }