001    /**
002     * Copyright (c) 2000-present 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.service.impl;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.settings.LocalizedValuesMap;
019    import com.liferay.portal.kernel.util.GetterUtil;
020    import com.liferay.portal.kernel.util.PwdGenerator;
021    import com.liferay.portal.kernel.util.Validator;
022    import com.liferay.portal.kernel.workflow.WorkflowConstants;
023    import com.liferay.portal.model.User;
024    import com.liferay.portal.service.ServiceContext;
025    import com.liferay.portal.util.PortletKeys;
026    import com.liferay.portal.util.PropsValues;
027    import com.liferay.portal.util.SubscriptionSender;
028    import com.liferay.portlet.shopping.BillingCityException;
029    import com.liferay.portlet.shopping.BillingCountryException;
030    import com.liferay.portlet.shopping.BillingEmailAddressException;
031    import com.liferay.portlet.shopping.BillingFirstNameException;
032    import com.liferay.portlet.shopping.BillingLastNameException;
033    import com.liferay.portlet.shopping.BillingPhoneException;
034    import com.liferay.portlet.shopping.BillingStateException;
035    import com.liferay.portlet.shopping.BillingStreetException;
036    import com.liferay.portlet.shopping.BillingZipException;
037    import com.liferay.portlet.shopping.CCExpirationException;
038    import com.liferay.portlet.shopping.CCNameException;
039    import com.liferay.portlet.shopping.CCNumberException;
040    import com.liferay.portlet.shopping.CCTypeException;
041    import com.liferay.portlet.shopping.CartMinOrderException;
042    import com.liferay.portlet.shopping.ShippingCityException;
043    import com.liferay.portlet.shopping.ShippingCountryException;
044    import com.liferay.portlet.shopping.ShippingEmailAddressException;
045    import com.liferay.portlet.shopping.ShippingFirstNameException;
046    import com.liferay.portlet.shopping.ShippingLastNameException;
047    import com.liferay.portlet.shopping.ShippingPhoneException;
048    import com.liferay.portlet.shopping.ShippingStateException;
049    import com.liferay.portlet.shopping.ShippingStreetException;
050    import com.liferay.portlet.shopping.ShippingZipException;
051    import com.liferay.portlet.shopping.ShoppingSettings;
052    import com.liferay.portlet.shopping.model.ShoppingCart;
053    import com.liferay.portlet.shopping.model.ShoppingCartItem;
054    import com.liferay.portlet.shopping.model.ShoppingItem;
055    import com.liferay.portlet.shopping.model.ShoppingItemField;
056    import com.liferay.portlet.shopping.model.ShoppingOrder;
057    import com.liferay.portlet.shopping.model.ShoppingOrderConstants;
058    import com.liferay.portlet.shopping.model.ShoppingOrderItem;
059    import com.liferay.portlet.shopping.model.impl.ShoppingCartItemImpl;
060    import com.liferay.portlet.shopping.service.base.ShoppingOrderLocalServiceBaseImpl;
061    import com.liferay.portlet.shopping.util.ShoppingUtil;
062    import com.liferay.portlet.shopping.util.comparator.OrderDateComparator;
063    import com.liferay.util.CreditCard;
064    
065    import java.util.Currency;
066    import java.util.Date;
067    import java.util.List;
068    import java.util.Map;
069    
070    /**
071     * @author Brian Wing Shun Chan
072     */
073    public class ShoppingOrderLocalServiceImpl
074            extends ShoppingOrderLocalServiceBaseImpl {
075    
076            @Override
077            public ShoppingOrder addLatestOrder(long userId, long groupId)
078                    throws PortalException {
079    
080                    // Order
081    
082                    User user = userPersistence.findByPrimaryKey(userId);
083                    Date now = new Date();
084    
085                    String number = getNumber();
086    
087                    ShoppingOrder order = null;
088    
089                    long orderId = counterLocalService.increment();
090    
091                    List<ShoppingOrder> pastOrders =
092                            shoppingOrderPersistence.findByG_U_PPPS(
093                                    groupId, userId, ShoppingOrderConstants.STATUS_CHECKOUT, 0, 1);
094    
095                    if (!pastOrders.isEmpty()) {
096                            ShoppingOrder pastOrder = pastOrders.get(0);
097    
098                            order = shoppingOrderPersistence.create(orderId);
099    
100                            order.setBillingCompany(pastOrder.getBillingCompany());
101                            order.setBillingStreet(pastOrder.getBillingStreet());
102                            order.setBillingCity(pastOrder.getBillingCity());
103                            order.setBillingState(pastOrder.getBillingState());
104                            order.setBillingZip(pastOrder.getBillingZip());
105                            order.setBillingCountry(pastOrder.getBillingCountry());
106                            order.setBillingPhone(pastOrder.getBillingPhone());
107                            order.setShipToBilling(pastOrder.isShipToBilling());
108                            order.setShippingCompany(pastOrder.getShippingCompany());
109                            order.setShippingStreet(pastOrder.getShippingStreet());
110                            order.setShippingCity(pastOrder.getShippingCity());
111                            order.setShippingState(pastOrder.getShippingState());
112                            order.setShippingZip(pastOrder.getShippingZip());
113                            order.setShippingCountry(pastOrder.getShippingCountry());
114                            order.setShippingPhone(pastOrder.getShippingPhone());
115                    }
116                    else {
117                            order = shoppingOrderPersistence.create(orderId);
118                    }
119    
120                    order.setGroupId(groupId);
121                    order.setCompanyId(user.getCompanyId());
122                    order.setUserId(user.getUserId());
123                    order.setUserName(user.getFullName());
124                    order.setCreateDate(now);
125                    order.setModifiedDate(now);
126                    order.setNumber(number);
127                    order.setBillingFirstName(user.getFirstName());
128                    order.setBillingLastName(user.getLastName());
129                    order.setBillingEmailAddress(user.getEmailAddress());
130                    order.setShippingFirstName(user.getFirstName());
131                    order.setShippingLastName(user.getLastName());
132                    order.setShippingEmailAddress(user.getEmailAddress());
133                    order.setCcName(user.getFullName());
134                    order.setPpPaymentStatus(ShoppingOrderConstants.STATUS_LATEST);
135                    order.setSendOrderEmail(true);
136                    order.setSendShippingEmail(true);
137    
138                    shoppingOrderPersistence.update(order);
139    
140                    // Message boards
141    
142                    if (PropsValues.SHOPPING_ORDER_COMMENTS_ENABLED) {
143                            mbMessageLocalService.addDiscussionMessage(
144                                    userId, order.getUserName(), groupId,
145                                    ShoppingOrder.class.getName(), orderId,
146                                    WorkflowConstants.ACTION_PUBLISH);
147                    }
148    
149                    return order;
150            }
151    
152            @Override
153            public void completeOrder(
154                            String number, String ppTxnId, String ppPaymentStatus,
155                            double ppPaymentGross, String ppReceiverEmail, String ppPayerEmail,
156                            boolean updateInventory, ServiceContext serviceContext)
157                    throws PortalException {
158    
159                    // Order
160    
161                    ShoppingOrder order = shoppingOrderPersistence.findByNumber(number);
162    
163                    order.setModifiedDate(new Date());
164                    order.setPpTxnId(ppTxnId);
165                    order.setPpPaymentStatus(ppPaymentStatus);
166                    order.setPpPaymentGross(ppPaymentGross);
167                    order.setPpReceiverEmail(ppReceiverEmail);
168                    order.setPpPayerEmail(ppPayerEmail);
169    
170                    shoppingOrderPersistence.update(order);
171    
172                    // Inventory
173    
174                    if (updateInventory &&
175                            ppPaymentStatus.equals(ShoppingOrderConstants.STATUS_COMPLETED)) {
176    
177                            List<ShoppingOrderItem> orderItems =
178                                    shoppingOrderItemLocalService.getOrderItems(order.getOrderId());
179    
180                            for (ShoppingOrderItem orderItem : orderItems) {
181                                    ShoppingItem item = shoppingItemLocalService.getItem(
182                                            ShoppingUtil.getItemId(orderItem.getItemId()));
183    
184                                    if (item.isInfiniteStock()) {
185                                            continue;
186                                    }
187    
188                                    if (!item.isFields()) {
189                                            int quantity =
190                                                    item.getStockQuantity() - orderItem.getQuantity();
191    
192                                            item.setStockQuantity(quantity);
193                                    }
194                                    else {
195                                            List<ShoppingItemField> itemFields =
196                                                    shoppingItemFieldLocalService.getItemFields(
197                                                            item.getItemId());
198    
199                                            ShoppingItemField[] itemFieldsArray = itemFields.toArray(
200                                                    new ShoppingItemField[itemFields.size()]);
201    
202                                            String[] fieldsArray = ShoppingCartItemImpl.getFieldsArray(
203                                                    ShoppingUtil.getItemFields(orderItem.getItemId()));
204    
205                                            int rowPos = ShoppingUtil.getFieldsQuantitiesPos(
206                                                    item, itemFieldsArray, fieldsArray);
207    
208                                            String[] fieldsQuantities = item.getFieldsQuantitiesArray();
209    
210                                            try {
211                                                    int quantity =
212                                                            GetterUtil.getInteger(fieldsQuantities[rowPos]) -
213                                                            orderItem.getQuantity();
214    
215                                                    fieldsQuantities[rowPos] = String.valueOf(quantity);
216    
217                                                    item.setFieldsQuantitiesArray(fieldsQuantities);
218                                            }
219                                            catch (Exception e) {
220                                            }
221                                    }
222    
223                                    shoppingItemPersistence.update(item);
224                            }
225                    }
226    
227                    // Email
228    
229                    sendEmail(order, "confirmation", serviceContext);
230            }
231    
232            @Override
233            public void deleteOrder(long orderId) throws PortalException {
234                    ShoppingOrder order = shoppingOrderPersistence.findByPrimaryKey(
235                            orderId);
236    
237                    deleteOrder(order);
238            }
239    
240            @Override
241            public void deleteOrder(ShoppingOrder order) throws PortalException {
242    
243                    // Order
244    
245                    shoppingOrderPersistence.remove(order);
246    
247                    // Subscriptions
248    
249                    subscriptionLocalService.deleteSubscriptions(
250                            order.getCompanyId(), ShoppingOrder.class.getName(),
251                            order.getOrderId());
252    
253                    // Items
254    
255                    shoppingOrderItemPersistence.removeByOrderId(order.getOrderId());
256    
257                    // Message boards
258    
259                    mbMessageLocalService.deleteDiscussionMessages(
260                            ShoppingOrder.class.getName(), order.getOrderId());
261            }
262    
263            @Override
264            public void deleteOrders(long groupId) throws PortalException {
265                    List<ShoppingOrder> orders = shoppingOrderPersistence.findByGroupId(
266                            groupId);
267    
268                    for (ShoppingOrder order : orders) {
269                            deleteOrder(order);
270                    }
271            }
272    
273            @Override
274            public ShoppingOrder getLatestOrder(long userId, long groupId)
275                    throws PortalException {
276    
277                    return shoppingOrderPersistence.findByG_U_PPPS_First(
278                            groupId, userId, ShoppingOrderConstants.STATUS_LATEST, null);
279            }
280    
281            @Override
282            public ShoppingOrder getOrder(long orderId) throws PortalException {
283                    return shoppingOrderPersistence.findByPrimaryKey(orderId);
284            }
285    
286            @Override
287            public ShoppingOrder getOrder(String number) throws PortalException {
288                    return shoppingOrderPersistence.findByNumber(number);
289            }
290    
291            @Override
292            public ShoppingOrder getPayPalTxnIdOrder(String ppTxnId)
293                    throws PortalException {
294    
295                    return shoppingOrderPersistence.findByPPTxnId(ppTxnId);
296            }
297    
298            @Override
299            public ShoppingOrder saveLatestOrder(ShoppingCart cart)
300                    throws PortalException {
301    
302                    Map<ShoppingCartItem, Integer> items = cart.getItems();
303                    Date now = new Date();
304    
305                    ShoppingSettings shoppingSettings = ShoppingSettings.getInstance(
306                            cart.getGroupId());
307    
308                    if (!ShoppingUtil.meetsMinOrder(shoppingSettings, items)) {
309                            throw new CartMinOrderException();
310                    }
311    
312                    ShoppingOrder order = getLatestOrder(
313                            cart.getUserId(), cart.getGroupId());
314    
315                    order.setCreateDate(now);
316                    order.setModifiedDate(now);
317                    order.setPpPaymentStatus(ShoppingOrderConstants.STATUS_CHECKOUT);
318    
319                    shoppingOrderPersistence.update(order);
320    
321                    boolean requiresShipping = false;
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 (item.isRequiresShipping()) {
330                                    requiresShipping = true;
331                            }
332    
333                            long orderItemId = counterLocalService.increment();
334    
335                            ShoppingOrderItem orderItem = shoppingOrderItemPersistence.create(
336                                    orderItemId);
337    
338                            orderItem.setOrderId(order.getOrderId());
339                            orderItem.setItemId(cartItem.getCartItemId());
340                            orderItem.setSku(item.getSku());
341                            orderItem.setName(item.getName());
342                            orderItem.setDescription(item.getDescription());
343                            orderItem.setProperties(item.getProperties());
344                            orderItem.setPrice(
345                                    ShoppingUtil.calculateActualPrice(item, count.intValue()) /
346                                            count.intValue());
347                            orderItem.setQuantity(count.intValue());
348    
349                            shoppingOrderItemPersistence.update(orderItem);
350                    }
351    
352                    order.setModifiedDate(new Date());
353                    order.setTax(ShoppingUtil.calculateTax(items, order.getBillingState()));
354                    order.setShipping(
355                            ShoppingUtil.calculateAlternativeShipping(
356                                    items, cart.getAltShipping()));
357                    order.setAltShipping(
358                            shoppingSettings.getAlternativeShippingName(cart.getAltShipping()));
359                    order.setRequiresShipping(requiresShipping);
360                    order.setInsure(cart.isInsure());
361                    order.setInsurance(ShoppingUtil.calculateInsurance(items));
362                    order.setCouponCodes(cart.getCouponCodes());
363                    order.setCouponDiscount(
364                            ShoppingUtil.calculateCouponDiscount(
365                                    items, order.getBillingState(), cart.getCoupon()));
366                    order.setSendOrderEmail(true);
367                    order.setSendShippingEmail(true);
368    
369                    shoppingOrderPersistence.update(order);
370    
371                    return order;
372            }
373    
374            @Override
375            public List<ShoppingOrder> search(
376                    long groupId, long companyId, long userId, String number,
377                    String billingFirstName, String billingLastName,
378                    String billingEmailAddress, String shippingFirstName,
379                    String shippingLastName, String shippingEmailAddress,
380                    String ppPaymentStatus, boolean andOperator, int start, int end) {
381    
382                    OrderDateComparator obc = new OrderDateComparator(false);
383    
384                    return shoppingOrderFinder.findByG_C_U_N_PPPS(
385                            groupId, companyId, userId, number, billingFirstName,
386                            billingLastName, billingEmailAddress, shippingFirstName,
387                            shippingLastName, shippingEmailAddress, ppPaymentStatus,
388                            andOperator, start, end, obc);
389            }
390    
391            @Override
392            public int searchCount(
393                    long groupId, long companyId, long userId, String number,
394                    String billingFirstName, String billingLastName,
395                    String billingEmailAddress, String shippingFirstName,
396                    String shippingLastName, String shippingEmailAddress,
397                    String ppPaymentStatus, boolean andOperator) {
398    
399                    return shoppingOrderFinder.countByG_C_U_N_PPPS(
400                            groupId, companyId, userId, number, billingFirstName,
401                            billingLastName, billingEmailAddress, shippingFirstName,
402                            shippingLastName, shippingEmailAddress, ppPaymentStatus,
403                            andOperator);
404            }
405    
406            @Override
407            public void sendEmail(
408                            long orderId, String emailType, ServiceContext serviceContext)
409                    throws PortalException {
410    
411                    ShoppingOrder order = shoppingOrderPersistence.findByPrimaryKey(
412                            orderId);
413    
414                    sendEmail(order, emailType, serviceContext);
415            }
416    
417            @Override
418            public void sendEmail(
419                            ShoppingOrder order, String emailType,
420                            ServiceContext serviceContext)
421                    throws PortalException {
422    
423                    ShoppingSettings shoppingSettings = ShoppingSettings.getInstance(
424                            order.getGroupId());
425    
426                    if (emailType.equals("confirmation") &&
427                            shoppingSettings.isEmailOrderConfirmationEnabled()) {
428                    }
429                    else if (emailType.equals("shipping") &&
430                                     shoppingSettings.isEmailOrderShippingEnabled()) {
431                    }
432                    else {
433                            return;
434                    }
435    
436                    notifyUser(order, emailType, shoppingSettings, serviceContext);
437    
438                    if (emailType.equals("confirmation") && order.isSendOrderEmail()) {
439                            order.setSendOrderEmail(false);
440    
441                            shoppingOrderPersistence.update(order);
442                    }
443                    else if (emailType.equals("shipping") && order.isSendShippingEmail()) {
444                            order.setSendShippingEmail(false);
445    
446                            shoppingOrderPersistence.update(order);
447                    }
448            }
449    
450            @Override
451            public ShoppingOrder updateLatestOrder(
452                            long userId, long groupId, String billingFirstName,
453                            String billingLastName, String billingEmailAddress,
454                            String billingCompany, String billingStreet, String billingCity,
455                            String billingState, String billingZip, String billingCountry,
456                            String billingPhone, boolean shipToBilling,
457                            String shippingFirstName, String shippingLastName,
458                            String shippingEmailAddress, String shippingCompany,
459                            String shippingStreet, String shippingCity, String shippingState,
460                            String shippingZip, String shippingCountry, String shippingPhone,
461                            String ccName, String ccType, String ccNumber, int ccExpMonth,
462                            int ccExpYear, String ccVerNumber, String comments)
463                    throws PortalException {
464    
465                    ShoppingOrder order = getLatestOrder(userId, groupId);
466    
467                    return updateOrder(
468                            order.getOrderId(), billingFirstName, billingLastName,
469                            billingEmailAddress, billingCompany, billingStreet, billingCity,
470                            billingState, billingZip, billingCountry, billingPhone,
471                            shipToBilling, shippingFirstName, shippingLastName,
472                            shippingEmailAddress, shippingCompany, shippingStreet, shippingCity,
473                            shippingState, shippingZip, shippingCountry, shippingPhone, ccName,
474                            ccType, ccNumber, ccExpMonth, ccExpYear, ccVerNumber, comments);
475            }
476    
477            @Override
478            public ShoppingOrder updateOrder(
479                            long orderId, String ppTxnId, String ppPaymentStatus,
480                            double ppPaymentGross, String ppReceiverEmail, String ppPayerEmail)
481                    throws PortalException {
482    
483                    ShoppingOrder order = shoppingOrderPersistence.findByPrimaryKey(
484                            orderId);
485    
486                    order.setModifiedDate(new Date());
487                    order.setPpTxnId(ppTxnId);
488                    order.setPpPaymentStatus(ppPaymentStatus);
489                    order.setPpPaymentGross(ppPaymentGross);
490                    order.setPpReceiverEmail(ppReceiverEmail);
491                    order.setPpPayerEmail(ppPayerEmail);
492    
493                    shoppingOrderPersistence.update(order);
494    
495                    return order;
496            }
497    
498            @Override
499            public ShoppingOrder updateOrder(
500                            long orderId, String billingFirstName, String billingLastName,
501                            String billingEmailAddress, String billingCompany,
502                            String billingStreet, String billingCity, String billingState,
503                            String billingZip, String billingCountry, String billingPhone,
504                            boolean shipToBilling, String shippingFirstName,
505                            String shippingLastName, String shippingEmailAddress,
506                            String shippingCompany, String shippingStreet, String shippingCity,
507                            String shippingState, String shippingZip, String shippingCountry,
508                            String shippingPhone, String ccName, String ccType, String ccNumber,
509                            int ccExpMonth, int ccExpYear, String ccVerNumber, String comments)
510                    throws PortalException {
511    
512                    ShoppingOrder order = shoppingOrderPersistence.findByPrimaryKey(
513                            orderId);
514    
515                    ShoppingSettings shoppingSettings = ShoppingSettings.getInstance(
516                            order.getGroupId());
517    
518                    validate(
519                            shoppingSettings, billingFirstName, billingLastName,
520                            billingEmailAddress, billingStreet, billingCity, billingState,
521                            billingZip, billingCountry, billingPhone, shipToBilling,
522                            shippingFirstName, shippingLastName, shippingEmailAddress,
523                            shippingStreet, shippingCity, shippingState, shippingZip,
524                            shippingCountry, shippingPhone, ccName, ccType, ccNumber,
525                            ccExpMonth, ccExpYear, ccVerNumber);
526    
527                    order.setModifiedDate(new Date());
528                    order.setBillingFirstName(billingFirstName);
529                    order.setBillingLastName(billingLastName);
530                    order.setBillingEmailAddress(billingEmailAddress);
531                    order.setBillingCompany(billingCompany);
532                    order.setBillingStreet(billingStreet);
533                    order.setBillingCity(billingCity);
534                    order.setBillingState(billingState);
535                    order.setBillingZip(billingZip);
536                    order.setBillingCountry(billingCountry);
537                    order.setBillingPhone(billingPhone);
538                    order.setShipToBilling(shipToBilling);
539    
540                    if (shipToBilling) {
541                            order.setShippingFirstName(billingFirstName);
542                            order.setShippingLastName(billingLastName);
543                            order.setShippingEmailAddress(billingEmailAddress);
544                            order.setShippingCompany(billingCompany);
545                            order.setShippingStreet(billingStreet);
546                            order.setShippingCity(billingCity);
547                            order.setShippingState(billingState);
548                            order.setShippingZip(billingZip);
549                            order.setShippingCountry(billingCountry);
550                            order.setShippingPhone(billingPhone);
551                    }
552                    else {
553                            order.setShippingFirstName(shippingFirstName);
554                            order.setShippingLastName(shippingLastName);
555                            order.setShippingEmailAddress(shippingEmailAddress);
556                            order.setShippingCompany(shippingCompany);
557                            order.setShippingStreet(shippingStreet);
558                            order.setShippingCity(shippingCity);
559                            order.setShippingState(shippingState);
560                            order.setShippingZip(shippingZip);
561                            order.setShippingCountry(shippingCountry);
562                            order.setShippingPhone(shippingPhone);
563                    }
564    
565                    order.setCcName(ccName);
566                    order.setCcType(ccType);
567                    order.setCcNumber(ccNumber);
568                    order.setCcExpMonth(ccExpMonth);
569                    order.setCcExpYear(ccExpYear);
570                    order.setCcVerNumber(ccVerNumber);
571                    order.setComments(comments);
572    
573                    shoppingOrderPersistence.update(order);
574    
575                    return order;
576            }
577    
578            protected String getNumber() {
579                    String number = PwdGenerator.getPassword(
580                            12, PwdGenerator.KEY1, PwdGenerator.KEY2);
581    
582                    ShoppingOrder order = shoppingOrderPersistence.fetchByNumber(number);
583    
584                    if (order != null) {
585                            return order.getNumber();
586                    }
587    
588                    return number;
589            }
590    
591            protected void notifyUser(
592                            ShoppingOrder order, String emailType,
593                            ShoppingSettings shoppingSettings, ServiceContext serviceContext)
594                    throws PortalException {
595    
596                    User user = userPersistence.findByPrimaryKey(order.getUserId());
597    
598                    Currency currency = Currency.getInstance(
599                            shoppingSettings.getCurrencyId());
600    
601                    String billingAddress =
602                            order.getBillingFirstName() + " " + order.getBillingLastName() +
603                                    "<br>" +
604                            order.getBillingEmailAddress() + "<br>" +
605                            order.getBillingStreet() + "<br>" +
606                            order.getBillingCity() + "<br>" +
607                            order.getBillingState() + "<br>" +
608                            order.getBillingZip() + "<br>" +
609                            order.getBillingCountry() + "<br>" +
610                            order.getBillingPhone() + "<br>";
611    
612                    String shippingAddress =
613                            order.getShippingFirstName() + " " + order.getShippingLastName() +
614                                    "<br>" +
615                            order.getShippingEmailAddress() + "<br>" +
616                            order.getShippingStreet() + "<br>" +
617                            order.getShippingCity() + "<br>" +
618                            order.getShippingState() + "<br>" +
619                            order.getShippingZip() + "<br>" +
620                            order.getShippingCountry() + "<br>" +
621                            order.getShippingPhone() + "<br>";
622    
623                    double total = ShoppingUtil.calculateTotal(order);
624    
625                    String fromName = shoppingSettings.getEmailFromName();
626                    String fromAddress = shoppingSettings.getEmailFromAddress();
627    
628                    String toName = user.getFullName();
629                    String toAddress = user.getEmailAddress();
630    
631                    LocalizedValuesMap subjectLocalizedValuesMap = null;
632                    LocalizedValuesMap bodyLocalizedValuesMap = null;
633    
634                    if (emailType.equals("confirmation")) {
635                            subjectLocalizedValuesMap =
636                                    shoppingSettings.getEmailOrderConfirmationSubject();
637                            bodyLocalizedValuesMap =
638                                    shoppingSettings.getEmailOrderConfirmationBody();
639                    }
640                    else if (emailType.equals("shipping")) {
641                            subjectLocalizedValuesMap =
642                                    shoppingSettings.getEmailOrderShippingSubject();
643                            bodyLocalizedValuesMap =
644                                    shoppingSettings.getEmailOrderShippingBody();
645                    }
646    
647                    SubscriptionSender subscriptionSender = new SubscriptionSender();
648    
649                    subscriptionSender.setCompanyId(order.getCompanyId());
650                    subscriptionSender.setContextAttributes(
651                            "[$ORDER_BILLING_ADDRESS$]", billingAddress, "[$ORDER_CURRENCY$]",
652                            currency.getSymbol(), "[$ORDER_NUMBER$]", order.getNumber(),
653                            "[$ORDER_SHIPPING_ADDRESS$]", shippingAddress, "[$ORDER_TOTAL$]",
654                            total);
655                    subscriptionSender.setFrom(fromAddress, fromName);
656                    subscriptionSender.setHtmlFormat(true);
657                    subscriptionSender.setLocalizedBodyMap(bodyLocalizedValuesMap);
658                    subscriptionSender.setLocalizedSubjectMap(subjectLocalizedValuesMap);
659                    subscriptionSender.setMailId("shopping_order", order.getOrderId());
660                    subscriptionSender.setPortletId(PortletKeys.SHOPPING);
661                    subscriptionSender.setScopeGroupId(order.getGroupId());
662                    subscriptionSender.setServiceContext(serviceContext);
663                    subscriptionSender.setUserId(order.getUserId());
664    
665                    subscriptionSender.addRuntimeSubscribers(toAddress, toName);
666    
667                    subscriptionSender.flushNotificationsAsync();
668            }
669    
670            protected void validate(
671                            ShoppingSettings shoppingSettings, String billingFirstName,
672                            String billingLastName, String billingEmailAddress,
673                            String billingStreet, String billingCity, String billingState,
674                            String billingZip, String billingCountry, String billingPhone,
675                            boolean shipToBilling, String shippingFirstName,
676                            String shippingLastName, String shippingEmailAddress,
677                            String shippingStreet, String shippingCity, String shippingState,
678                            String shippingZip, String shippingCountry, String shippingPhone,
679                            String ccName, String ccType, String ccNumber, int ccExpMonth,
680                            int ccExpYear, String ccVerNumber)
681                    throws PortalException {
682    
683                    if (Validator.isNull(billingFirstName)) {
684                            throw new BillingFirstNameException();
685                    }
686                    else if (Validator.isNull(billingLastName)) {
687                            throw new BillingLastNameException();
688                    }
689                    else if (!Validator.isEmailAddress(billingEmailAddress)) {
690                            throw new BillingEmailAddressException();
691                    }
692                    else if (Validator.isNull(billingStreet)) {
693                            throw new BillingStreetException();
694                    }
695                    else if (Validator.isNull(billingCity)) {
696                            throw new BillingCityException();
697                    }
698                    else if (Validator.isNull(billingState)) {
699                            throw new BillingStateException();
700                    }
701                    else if (Validator.isNull(billingZip)) {
702                            throw new BillingZipException();
703                    }
704                    else if (Validator.isNull(billingCountry)) {
705                            throw new BillingCountryException();
706                    }
707                    else if (Validator.isNull(billingPhone)) {
708                            throw new BillingPhoneException();
709                    }
710    
711                    if (!shipToBilling) {
712                            if (Validator.isNull(shippingFirstName)) {
713                                    throw new ShippingFirstNameException();
714                            }
715                            else if (Validator.isNull(shippingLastName)) {
716                                    throw new ShippingLastNameException();
717                            }
718                            else if (!Validator.isEmailAddress(shippingEmailAddress)) {
719                                    throw new ShippingEmailAddressException();
720                            }
721                            else if (Validator.isNull(shippingStreet)) {
722                                    throw new ShippingStreetException();
723                            }
724                            else if (Validator.isNull(shippingCity)) {
725                                    throw new ShippingCityException();
726                            }
727                            else if (Validator.isNull(shippingState)) {
728                                    throw new ShippingStateException();
729                            }
730                            else if (Validator.isNull(shippingZip)) {
731                                    throw new ShippingZipException();
732                            }
733                            else if (Validator.isNull(shippingCountry)) {
734                                    throw new ShippingCountryException();
735                            }
736                            else if (Validator.isNull(shippingPhone)) {
737                                    throw new ShippingPhoneException();
738                            }
739                    }
740    
741                    if (!shoppingSettings.usePayPal() &&
742                            (shoppingSettings.getCcTypes().length > 0)) {
743    
744                            if (Validator.isNull(ccName)) {
745                                    throw new CCNameException();
746                            }
747                            else if (Validator.isNull(ccType)) {
748                                    throw new CCTypeException();
749                            }
750                            else if (!CreditCard.isValidNumber(ccNumber, ccType)) {
751                                    throw new CCNumberException();
752                            }
753                            else if (!CreditCard.isValidExpirationDate(ccExpMonth, ccExpYear)) {
754                                    throw new CCExpirationException();
755                            }
756                    }
757            }
758    
759    }