1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet.shopping.service.impl;
16  
17  import com.liferay.portal.kernel.exception.PortalException;
18  import com.liferay.portal.kernel.exception.SystemException;
19  import com.liferay.portal.kernel.mail.MailMessage;
20  import com.liferay.portal.kernel.util.CalendarUtil;
21  import com.liferay.portal.kernel.util.GetterUtil;
22  import com.liferay.portal.kernel.util.StringUtil;
23  import com.liferay.portal.kernel.util.Validator;
24  import com.liferay.portal.kernel.workflow.StatusConstants;
25  import com.liferay.portal.model.Company;
26  import com.liferay.portal.model.User;
27  import com.liferay.portal.util.PortalUtil;
28  import com.liferay.portal.util.PortletKeys;
29  import com.liferay.portal.util.PropsValues;
30  import com.liferay.portlet.shopping.BillingCityException;
31  import com.liferay.portlet.shopping.BillingCountryException;
32  import com.liferay.portlet.shopping.BillingEmailAddressException;
33  import com.liferay.portlet.shopping.BillingFirstNameException;
34  import com.liferay.portlet.shopping.BillingLastNameException;
35  import com.liferay.portlet.shopping.BillingPhoneException;
36  import com.liferay.portlet.shopping.BillingStateException;
37  import com.liferay.portlet.shopping.BillingStreetException;
38  import com.liferay.portlet.shopping.BillingZipException;
39  import com.liferay.portlet.shopping.CCExpirationException;
40  import com.liferay.portlet.shopping.CCNameException;
41  import com.liferay.portlet.shopping.CCNumberException;
42  import com.liferay.portlet.shopping.CCTypeException;
43  import com.liferay.portlet.shopping.CartMinOrderException;
44  import com.liferay.portlet.shopping.NoSuchOrderException;
45  import com.liferay.portlet.shopping.ShippingCityException;
46  import com.liferay.portlet.shopping.ShippingCountryException;
47  import com.liferay.portlet.shopping.ShippingEmailAddressException;
48  import com.liferay.portlet.shopping.ShippingFirstNameException;
49  import com.liferay.portlet.shopping.ShippingLastNameException;
50  import com.liferay.portlet.shopping.ShippingPhoneException;
51  import com.liferay.portlet.shopping.ShippingStateException;
52  import com.liferay.portlet.shopping.ShippingStreetException;
53  import com.liferay.portlet.shopping.ShippingZipException;
54  import com.liferay.portlet.shopping.model.ShoppingCart;
55  import com.liferay.portlet.shopping.model.ShoppingCartItem;
56  import com.liferay.portlet.shopping.model.ShoppingItem;
57  import com.liferay.portlet.shopping.model.ShoppingItemField;
58  import com.liferay.portlet.shopping.model.ShoppingOrder;
59  import com.liferay.portlet.shopping.model.ShoppingOrderConstants;
60  import com.liferay.portlet.shopping.model.ShoppingOrderItem;
61  import com.liferay.portlet.shopping.model.impl.ShoppingCartItemImpl;
62  import com.liferay.portlet.shopping.service.base.ShoppingOrderLocalServiceBaseImpl;
63  import com.liferay.portlet.shopping.util.ShoppingPreferences;
64  import com.liferay.portlet.shopping.util.ShoppingUtil;
65  import com.liferay.portlet.shopping.util.comparator.OrderDateComparator;
66  import com.liferay.util.CreditCard;
67  import com.liferay.util.PwdGenerator;
68  
69  import java.io.IOException;
70  
71  import java.util.Currency;
72  import java.util.Date;
73  import java.util.Iterator;
74  import java.util.List;
75  import java.util.Map;
76  
77  import javax.mail.internet.InternetAddress;
78  
79  /**
80   * <a href="ShoppingOrderLocalServiceImpl.java.html"><b><i>View Source</i></b>
81   * </a>
82   *
83   * @author Brian Wing Shun Chan
84   */
85  public class ShoppingOrderLocalServiceImpl
86      extends ShoppingOrderLocalServiceBaseImpl {
87  
88      public ShoppingOrder addLatestOrder(long userId, long groupId)
89          throws PortalException, SystemException {
90  
91          // Order
92  
93          User user = userPersistence.findByPrimaryKey(userId);
94          Date now = new Date();
95  
96          String number = getNumber();
97  
98          ShoppingOrder order = null;
99  
100         long orderId = counterLocalService.increment();
101 
102         List<ShoppingOrder> pastOrders =
103             shoppingOrderPersistence.findByG_U_PPPS(
104                 groupId, userId, ShoppingOrderConstants.STATUS_CHECKOUT, 0, 1);
105 
106         if (pastOrders.size() > 0) {
107             ShoppingOrder pastOrder = pastOrders.get(0);
108 
109             order = shoppingOrderPersistence.create(orderId);
110 
111             order.setBillingCompany(pastOrder.getBillingCompany());
112             order.setBillingStreet(pastOrder.getBillingStreet());
113             order.setBillingCity(pastOrder.getBillingCity());
114             order.setBillingState(pastOrder.getBillingState());
115             order.setBillingZip(pastOrder.getBillingZip());
116             order.setBillingCountry(pastOrder.getBillingCountry());
117             order.setBillingPhone(pastOrder.getBillingPhone());
118             order.setShipToBilling(pastOrder.isShipToBilling());
119             order.setShippingCompany(pastOrder.getShippingCompany());
120             order.setShippingStreet(pastOrder.getShippingStreet());
121             order.setShippingCity(pastOrder.getShippingCity());
122             order.setShippingState(pastOrder.getShippingState());
123             order.setShippingZip(pastOrder.getShippingZip());
124             order.setShippingCountry(pastOrder.getShippingCountry());
125             order.setShippingPhone(pastOrder.getShippingPhone());
126         }
127         else {
128             order = shoppingOrderPersistence.create(orderId);
129         }
130 
131         order.setGroupId(groupId);
132         order.setCompanyId(user.getCompanyId());
133         order.setUserId(user.getUserId());
134         order.setUserName(user.getFullName());
135         order.setCreateDate(now);
136         order.setModifiedDate(now);
137         order.setNumber(number);
138         order.setBillingFirstName(user.getFirstName());
139         order.setBillingLastName(user.getLastName());
140         order.setBillingEmailAddress(user.getEmailAddress());
141         order.setShippingFirstName(user.getFirstName());
142         order.setShippingLastName(user.getLastName());
143         order.setShippingEmailAddress(user.getEmailAddress());
144         order.setCcName(user.getFullName());
145         order.setPpPaymentStatus(ShoppingOrderConstants.STATUS_LATEST);
146         order.setSendOrderEmail(true);
147         order.setSendShippingEmail(true);
148 
149         shoppingOrderPersistence.update(order, false);
150 
151         // Message boards
152 
153         if (PropsValues.SHOPPING_ORDER_COMMENTS_ENABLED) {
154             mbMessageLocalService.addDiscussionMessage(
155                 userId, order.getUserName(), ShoppingOrder.class.getName(),
156                 orderId, StatusConstants.APPROVED);
157         }
158 
159         return order;
160     }
161 
162     public void completeOrder(
163             String number, String ppTxnId, String ppPaymentStatus,
164             double ppPaymentGross, String ppReceiverEmail, String ppPayerEmail,
165             boolean updateInventory)
166         throws PortalException, SystemException {
167 
168         // Order
169 
170         ShoppingOrder order = shoppingOrderPersistence.findByNumber(number);
171 
172         order.setModifiedDate(new Date());
173         order.setPpTxnId(ppTxnId);
174         order.setPpPaymentStatus(ppPaymentStatus);
175         order.setPpPaymentGross(ppPaymentGross);
176         order.setPpReceiverEmail(ppReceiverEmail);
177         order.setPpPayerEmail(ppPayerEmail);
178 
179         shoppingOrderPersistence.update(order, false);
180 
181         // Inventory
182 
183         if (updateInventory &&
184             ppPaymentStatus.equals(ShoppingOrderConstants.STATUS_COMPLETED)) {
185 
186             List<ShoppingOrderItem> orderItems =
187                 shoppingOrderItemLocalService.getOrderItems(order.getOrderId());
188 
189             for (ShoppingOrderItem orderItem : orderItems) {
190                 ShoppingItem item = shoppingItemLocalService.getItem(
191                     ShoppingUtil.getItemId(orderItem.getItemId()));
192 
193                 if (!item.isFields()) {
194                     int quantity =
195                         item.getStockQuantity() - orderItem.getQuantity();
196 
197                     item.setStockQuantity(quantity);
198                 }
199                 else {
200                     List<ShoppingItemField> itemFields =
201                         shoppingItemFieldLocalService.getItemFields(
202                             item.getItemId());
203 
204                     ShoppingItemField[] itemFieldsArray = itemFields.toArray(
205                         new ShoppingItemField[itemFields.size()]);
206 
207                     String[] fieldsArray = ShoppingCartItemImpl.getFieldsArray(
208                         ShoppingUtil.getItemFields(orderItem.getItemId()));
209 
210                     int rowPos = ShoppingUtil.getFieldsQuantitiesPos(
211                         item, itemFieldsArray, fieldsArray);
212 
213                     String[] fieldsQuantities = item.getFieldsQuantitiesArray();
214 
215                     try {
216                         int quantity =
217                             GetterUtil.getInteger(fieldsQuantities[rowPos]) -
218                             orderItem.getQuantity();
219 
220                         fieldsQuantities[rowPos] = String.valueOf(quantity);
221 
222                         item.setFieldsQuantitiesArray(fieldsQuantities);
223                     }
224                     catch (Exception e) {
225                     }
226                 }
227 
228                 shoppingItemPersistence.update(item, false);
229             }
230         }
231 
232         // Email
233 
234         try {
235             doSendEmail(order, "confirmation");
236         }
237         catch (IOException ioe) {
238             throw new SystemException(ioe);
239         }
240     }
241 
242     public void deleteOrder(long orderId)
243         throws PortalException, SystemException {
244 
245         ShoppingOrder order = shoppingOrderPersistence.findByPrimaryKey(
246             orderId);
247 
248         deleteOrder(order);
249     }
250 
251     public void deleteOrder(ShoppingOrder order)
252         throws PortalException, SystemException {
253 
254         // Order
255 
256         shoppingOrderPersistence.remove(order);
257 
258         // Items
259 
260         shoppingOrderItemPersistence.removeByOrderId(order.getOrderId());
261 
262         // Message boards
263 
264         mbMessageLocalService.deleteDiscussionMessages(
265             ShoppingOrder.class.getName(), order.getOrderId());
266     }
267 
268     public void deleteOrders(long groupId)
269         throws PortalException, SystemException {
270 
271         List<ShoppingOrder> orders = shoppingOrderPersistence.findByGroupId(
272             groupId);
273 
274         for (ShoppingOrder order : orders) {
275             deleteOrder(order);
276         }
277     }
278 
279     public ShoppingOrder getLatestOrder(long userId, long groupId)
280         throws PortalException, SystemException {
281 
282         List<ShoppingOrder> orders = shoppingOrderPersistence.findByG_U_PPPS(
283             groupId, userId, ShoppingOrderConstants.STATUS_LATEST, 0, 1);
284 
285         ShoppingOrder order = null;
286 
287         if (orders.size() == 1) {
288             order = orders.get(0);
289         }
290         else {
291             order = shoppingOrderLocalService.addLatestOrder(userId, groupId);
292         }
293 
294         return order;
295     }
296 
297     public ShoppingOrder getOrder(long orderId)
298         throws PortalException, SystemException {
299 
300         return shoppingOrderPersistence.findByPrimaryKey(orderId);
301     }
302 
303     public ShoppingOrder getOrder(String number)
304         throws PortalException, SystemException {
305 
306         return shoppingOrderPersistence.findByNumber(number);
307     }
308 
309     public ShoppingOrder getPayPalTxnIdOrder(String ppTxnId)
310         throws PortalException, SystemException {
311 
312         return shoppingOrderPersistence.findByPPTxnId(ppTxnId);
313     }
314 
315     public ShoppingOrder saveLatestOrder(ShoppingCart cart)
316         throws PortalException, SystemException {
317 
318         Map<ShoppingCartItem, Integer> items = cart.getItems();
319         Date now = new Date();
320 
321         ShoppingPreferences shoppingPrefs = ShoppingPreferences.getInstance(
322             cart.getCompanyId(), cart.getGroupId());
323 
324         if (!ShoppingUtil.meetsMinOrder(shoppingPrefs, items)) {
325             throw new CartMinOrderException();
326         }
327 
328         ShoppingOrder order = getLatestOrder(
329             cart.getUserId(), cart.getGroupId());
330 
331         order.setCreateDate(now);
332         order.setModifiedDate(now);
333         order.setPpPaymentStatus(ShoppingOrderConstants.STATUS_CHECKOUT);
334 
335         shoppingOrderPersistence.update(order, false);
336 
337         boolean requiresShipping = false;
338 
339         Iterator<Map.Entry<ShoppingCartItem, Integer>> itr =
340             items.entrySet().iterator();
341 
342         while (itr.hasNext()) {
343             Map.Entry<ShoppingCartItem, Integer> entry = itr.next();
344 
345             ShoppingCartItem cartItem = entry.getKey();
346             Integer count = entry.getValue();
347 
348             ShoppingItem item = cartItem.getItem();
349 
350             if (item.isRequiresShipping()) {
351                 requiresShipping = true;
352             }
353 
354             long orderItemId = counterLocalService.increment();
355 
356             ShoppingOrderItem orderItem = shoppingOrderItemPersistence.create(
357                 orderItemId);
358 
359             orderItem.setOrderId(order.getOrderId());
360             orderItem.setItemId(cartItem.getCartItemId());
361             orderItem.setSku(item.getSku());
362             orderItem.setName(item.getName());
363             orderItem.setDescription(item.getDescription());
364             orderItem.setProperties(item.getProperties());
365             orderItem.setPrice(
366                 ShoppingUtil.calculateActualPrice(item, count.intValue()) /
367                     count.intValue());
368             orderItem.setQuantity(count.intValue());
369 
370             shoppingOrderItemPersistence.update(orderItem, false);
371         }
372 
373         order.setModifiedDate(new Date());
374         order.setTax(
375             ShoppingUtil.calculateTax(items, order.getBillingState()));
376         order.setShipping(
377             ShoppingUtil.calculateAlternativeShipping(
378                 items, cart.getAltShipping()));
379         order.setAltShipping(
380             shoppingPrefs.getAlternativeShippingName(cart.getAltShipping()));
381         order.setRequiresShipping(requiresShipping);
382         order.setInsure(cart.isInsure());
383         order.setInsurance(ShoppingUtil.calculateInsurance(items));
384         order.setCouponCodes(cart.getCouponCodes());
385         order.setCouponDiscount(
386             ShoppingUtil.calculateCouponDiscount(
387                 items, order.getBillingState(), cart.getCoupon()));
388         order.setSendOrderEmail(true);
389         order.setSendShippingEmail(true);
390 
391         shoppingOrderPersistence.update(order, false);
392 
393         return order;
394     }
395 
396     public List<ShoppingOrder> search(
397             long groupId, long companyId, long userId, String number,
398             String billingFirstName, String billingLastName,
399             String billingEmailAddress, String shippingFirstName,
400             String shippingLastName, String shippingEmailAddress,
401             String ppPaymentStatus, boolean andOperator, int start, int end)
402         throws SystemException {
403 
404         OrderDateComparator obc = new OrderDateComparator(false);
405 
406         return shoppingOrderFinder.findByG_C_U_N_PPPS(
407             groupId, companyId, userId, number, billingFirstName,
408             billingLastName, billingEmailAddress, shippingFirstName,
409             shippingLastName, shippingEmailAddress, ppPaymentStatus,
410             andOperator, start, end, obc);
411     }
412 
413     public int searchCount(
414             long groupId, long companyId, long userId, String number,
415             String billingFirstName, String billingLastName,
416             String billingEmailAddress, String shippingFirstName,
417             String shippingLastName, String shippingEmailAddress,
418             String ppPaymentStatus, boolean andOperator)
419         throws SystemException {
420 
421         return shoppingOrderFinder.countByG_C_U_N_PPPS(
422             groupId, companyId, userId, number, billingFirstName,
423             billingLastName, billingEmailAddress, shippingFirstName,
424             shippingLastName, shippingEmailAddress, ppPaymentStatus,
425             andOperator);
426     }
427 
428     public void sendEmail(long orderId, String emailType)
429         throws PortalException, SystemException {
430 
431         ShoppingOrder order = shoppingOrderPersistence.findByPrimaryKey(
432             orderId);
433 
434         try {
435             doSendEmail(order, emailType);
436         }
437         catch (IOException ioe) {
438             throw new SystemException(ioe);
439         }
440     }
441 
442     public void sendEmail(ShoppingOrder order, String emailType)
443         throws PortalException, SystemException {
444 
445         try {
446             doSendEmail(order, emailType);
447         }
448         catch (IOException ioe) {
449             throw new SystemException(ioe);
450         }
451     }
452 
453     public ShoppingOrder updateLatestOrder(
454             long userId, long groupId, String billingFirstName,
455             String billingLastName, String billingEmailAddress,
456             String billingCompany, String billingStreet, String billingCity,
457             String billingState, String billingZip, String billingCountry,
458             String billingPhone, boolean shipToBilling,
459             String shippingFirstName, String shippingLastName,
460             String shippingEmailAddress, String shippingCompany,
461             String shippingStreet, String shippingCity, String shippingState,
462             String shippingZip, String shippingCountry, String shippingPhone,
463             String ccName, String ccType, String ccNumber, int ccExpMonth,
464             int ccExpYear, String ccVerNumber, String comments)
465         throws PortalException, SystemException {
466 
467         ShoppingOrder order = getLatestOrder(userId, groupId);
468 
469         return updateOrder(
470             order.getOrderId(), billingFirstName, billingLastName,
471             billingEmailAddress, billingCompany, billingStreet, billingCity,
472             billingState, billingZip, billingCountry, billingPhone,
473             shipToBilling, shippingFirstName, shippingLastName,
474             shippingEmailAddress, shippingCompany, shippingStreet, shippingCity,
475             shippingState, shippingZip, shippingCountry, shippingPhone,
476             ccName, ccType, ccNumber, ccExpMonth, ccExpYear, ccVerNumber,
477             comments);
478     }
479 
480     public ShoppingOrder updateOrder(
481             long orderId, String ppTxnId, String ppPaymentStatus,
482             double ppPaymentGross, String ppReceiverEmail, String ppPayerEmail)
483         throws PortalException, SystemException {
484 
485         ShoppingOrder order = shoppingOrderPersistence.findByPrimaryKey(
486             orderId);
487 
488         order.setModifiedDate(new Date());
489         order.setPpTxnId(ppTxnId);
490         order.setPpPaymentStatus(ppPaymentStatus);
491         order.setPpPaymentGross(ppPaymentGross);
492         order.setPpReceiverEmail(ppReceiverEmail);
493         order.setPpPayerEmail(ppPayerEmail);
494 
495         shoppingOrderPersistence.update(order, false);
496 
497         return order;
498     }
499 
500     public ShoppingOrder updateOrder(
501             long orderId, String billingFirstName, String billingLastName,
502             String billingEmailAddress, String billingCompany,
503             String billingStreet, String billingCity, String billingState,
504             String billingZip, String billingCountry, String billingPhone,
505             boolean shipToBilling, String shippingFirstName,
506             String shippingLastName, String shippingEmailAddress,
507             String shippingCompany, String shippingStreet, String shippingCity,
508             String shippingState, String shippingZip, String shippingCountry,
509             String shippingPhone, String ccName, String ccType, String ccNumber,
510             int ccExpMonth, int ccExpYear, String ccVerNumber, String comments)
511         throws PortalException, SystemException {
512 
513         ShoppingOrder order = shoppingOrderPersistence.findByPrimaryKey(
514             orderId);
515 
516         ShoppingPreferences shoppingPrefs = ShoppingPreferences.getInstance(
517             order.getCompanyId(), order.getGroupId());
518 
519         validate(
520             shoppingPrefs, billingFirstName, billingLastName,
521             billingEmailAddress, billingStreet, billingCity, billingState,
522             billingZip, billingCountry, billingPhone, shipToBilling,
523             shippingFirstName, shippingLastName, shippingEmailAddress,
524             shippingStreet, shippingCity, shippingState, shippingZip,
525             shippingCountry, shippingPhone, ccName, ccType, ccNumber,
526             ccExpMonth, ccExpYear, ccVerNumber);
527 
528         order.setModifiedDate(new Date());
529         order.setBillingFirstName(billingFirstName);
530         order.setBillingLastName(billingLastName);
531         order.setBillingEmailAddress(billingEmailAddress);
532         order.setBillingCompany(billingCompany);
533         order.setBillingStreet(billingStreet);
534         order.setBillingCity(billingCity);
535         order.setBillingState(billingState);
536         order.setBillingZip(billingZip);
537         order.setBillingCountry(billingCountry);
538         order.setBillingPhone(billingPhone);
539         order.setShipToBilling(shipToBilling);
540 
541         if (shipToBilling) {
542             order.setShippingFirstName(billingFirstName);
543             order.setShippingLastName(billingLastName);
544             order.setShippingEmailAddress(billingEmailAddress);
545             order.setShippingCompany(billingCompany);
546             order.setShippingStreet(billingStreet);
547             order.setShippingCity(billingCity);
548             order.setShippingState(billingState);
549             order.setShippingZip(billingZip);
550             order.setShippingCountry(billingCountry);
551             order.setShippingPhone(billingPhone);
552         }
553         else {
554             order.setShippingFirstName(shippingFirstName);
555             order.setShippingLastName(shippingLastName);
556             order.setShippingEmailAddress(shippingEmailAddress);
557             order.setShippingCompany(shippingCompany);
558             order.setShippingStreet(shippingStreet);
559             order.setShippingCity(shippingCity);
560             order.setShippingState(shippingState);
561             order.setShippingZip(shippingZip);
562             order.setShippingCountry(shippingCountry);
563             order.setShippingPhone(shippingPhone);
564         }
565 
566         order.setCcName(ccName);
567         order.setCcType(ccType);
568         order.setCcNumber(ccNumber);
569         order.setCcExpMonth(ccExpMonth);
570         order.setCcExpYear(ccExpYear);
571         order.setCcVerNumber(ccVerNumber);
572         order.setComments(comments);
573 
574         shoppingOrderPersistence.update(order, false);
575 
576         return order;
577     }
578 
579     protected void doSendEmail(ShoppingOrder order, String emailType)
580         throws IOException, PortalException, SystemException {
581 
582         ShoppingPreferences shoppingPrefs = ShoppingPreferences.getInstance(
583             order.getCompanyId(), order.getGroupId());
584 
585         if (emailType.equals("confirmation") &&
586             shoppingPrefs.getEmailOrderConfirmationEnabled()) {
587         }
588         else if (emailType.equals("shipping") &&
589                  shoppingPrefs.getEmailOrderShippingEnabled()) {
590         }
591         else {
592             return;
593         }
594 
595         Company company = companyPersistence.findByPrimaryKey(
596             order.getCompanyId());
597 
598         User user = userPersistence.findByPrimaryKey(order.getUserId());
599 
600         Currency currency = Currency.getInstance(shoppingPrefs.getCurrencyId());
601 
602         String billingAddress =
603             order.getBillingFirstName() + " " + order.getBillingLastName() +
604                 "<br>" +
605             order.getBillingEmailAddress() + "<br>" +
606             order.getBillingStreet() + "<br>" +
607             order.getBillingCity() + "<br>" +
608             order.getBillingState() + "<br>" +
609             order.getBillingZip() + "<br>" +
610             order.getBillingCountry() + "<br>" +
611             order.getBillingPhone() + "<br>";
612 
613         String shippingAddress =
614             order.getShippingFirstName() + " " + order.getShippingLastName() +
615                 "<br>" +
616             order.getShippingEmailAddress() + "<br>" +
617             order.getShippingStreet() + "<br>" +
618             order.getShippingCity() + "<br>" +
619             order.getShippingState() + "<br>" +
620             order.getShippingZip() + "<br>" +
621             order.getShippingCountry() + "<br>" +
622             order.getShippingPhone() + "<br>";
623 
624         double total = ShoppingUtil.calculateTotal(order);
625 
626         String portletName = PortalUtil.getPortletTitle(
627             PortletKeys.SHOPPING, user);
628 
629         String fromName = shoppingPrefs.getEmailFromName();
630         String fromAddress = shoppingPrefs.getEmailFromAddress();
631 
632         String toName = user.getFullName();
633         String toAddress = user.getEmailAddress();
634 
635         String subject = null;
636         String body = null;
637 
638         if (emailType.equals("confirmation")) {
639             subject = shoppingPrefs.getEmailOrderConfirmationSubject();
640             body = shoppingPrefs.getEmailOrderConfirmationBody();
641         }
642         else if (emailType.equals("shipping")) {
643             subject = shoppingPrefs.getEmailOrderShippingSubject();
644             body = shoppingPrefs.getEmailOrderShippingBody();
645         }
646 
647         subject = StringUtil.replace(
648             subject,
649             new String[] {
650                 "[$FROM_ADDRESS$]",
651                 "[$FROM_NAME$]",
652                 "[$ORDER_BILLING_ADDRESS$]",
653                 "[$ORDER_CURRENCY$]",
654                 "[$ORDER_NUMBER$]",
655                 "[$ORDER_SHIPPING_ADDRESS$]",
656                 "[$ORDER_TOTAL$]",
657                 "[$PORTAL_URL$]",
658                 "[$PORTLET_NAME$]",
659                 "[$TO_ADDRESS$]",
660                 "[$TO_NAME$]"
661             },
662             new String[] {
663                 fromAddress,
664                 fromName,
665                 billingAddress,
666                 currency.getSymbol(),
667                 order.getNumber(),
668                 shippingAddress,
669                 String.valueOf(total),
670                 company.getVirtualHost(),
671                 portletName,
672                 toAddress,
673                 toName
674             });
675 
676         body = StringUtil.replace(
677             body,
678             new String[] {
679                 "[$FROM_ADDRESS$]",
680                 "[$FROM_NAME$]",
681                 "[$ORDER_BILLING_ADDRESS$]",
682                 "[$ORDER_CURRENCY$]",
683                 "[$ORDER_NUMBER$]",
684                 "[$ORDER_SHIPPING_ADDRESS$]",
685                 "[$ORDER_TOTAL$]",
686                 "[$PORTAL_URL$]",
687                 "[$PORTLET_NAME$]",
688                 "[$TO_ADDRESS$]",
689                 "[$TO_NAME$]"
690             },
691             new String[] {
692                 fromAddress,
693                 fromName,
694                 billingAddress,
695                 currency.getSymbol(),
696                 order.getNumber(),
697                 shippingAddress,
698                 String.valueOf(total),
699                 company.getVirtualHost(),
700                 portletName,
701                 toAddress,
702                 toName
703             });
704 
705         InternetAddress from = new InternetAddress(fromAddress, fromName);
706 
707         InternetAddress to = new InternetAddress(toAddress, toName);
708 
709         MailMessage message = new MailMessage(from, to, subject, body, true);
710 
711         mailService.sendEmail(message);
712 
713         if (emailType.equals("confirmation") && order.isSendOrderEmail()) {
714             order.setSendOrderEmail(false);
715 
716             shoppingOrderPersistence.update(order, false);
717         }
718         else if (emailType.equals("shipping") &&
719                  order.isSendShippingEmail()) {
720 
721             order.setSendShippingEmail(false);
722 
723             shoppingOrderPersistence.update(order, false);
724         }
725     }
726 
727     protected String getNumber() throws SystemException {
728         String number =
729             PwdGenerator.getPassword(PwdGenerator.KEY1 + PwdGenerator.KEY2, 12);
730 
731         try {
732             shoppingOrderPersistence.findByNumber(number);
733 
734             return getNumber();
735         }
736         catch (NoSuchOrderException nsoe) {
737             return number;
738         }
739     }
740 
741     protected void validate(
742             ShoppingPreferences shoppingPrefs, String billingFirstName,
743             String billingLastName, String billingEmailAddress,
744             String billingStreet, String billingCity, String billingState,
745             String billingZip, String billingCountry, String billingPhone,
746             boolean shipToBilling, String shippingFirstName,
747             String shippingLastName, String shippingEmailAddress,
748             String shippingStreet, String shippingCity, String shippingState,
749             String shippingZip, String shippingCountry, String shippingPhone,
750             String ccName, String ccType, String ccNumber, int ccExpMonth,
751             int ccExpYear, String ccVerNumber)
752         throws PortalException {
753 
754         if (Validator.isNull(billingFirstName)) {
755             throw new BillingFirstNameException();
756         }
757         else if (Validator.isNull(billingLastName)) {
758             throw new BillingLastNameException();
759         }
760         else if (!Validator.isEmailAddress(billingEmailAddress)) {
761             throw new BillingEmailAddressException();
762         }
763         else if (Validator.isNull(billingStreet)) {
764             throw new BillingStreetException();
765         }
766         else if (Validator.isNull(billingCity)) {
767             throw new BillingCityException();
768         }
769         else if (Validator.isNull(billingState)) {
770             throw new BillingStateException();
771         }
772         else if (Validator.isNull(billingZip)) {
773             throw new BillingZipException();
774         }
775         else if (Validator.isNull(billingCountry)) {
776             throw new BillingCountryException();
777         }
778         else if (Validator.isNull(billingPhone)) {
779             throw new BillingPhoneException();
780         }
781 
782         if (!shipToBilling) {
783             if (Validator.isNull(shippingFirstName)) {
784                 throw new ShippingFirstNameException();
785             }
786             else if (Validator.isNull(shippingLastName)) {
787                 throw new ShippingLastNameException();
788             }
789             else if (!Validator.isEmailAddress(shippingEmailAddress)) {
790                 throw new ShippingEmailAddressException();
791             }
792             else if (Validator.isNull(shippingStreet)) {
793                 throw new ShippingStreetException();
794             }
795             else if (Validator.isNull(shippingCity)) {
796                 throw new ShippingCityException();
797             }
798             else if (Validator.isNull(shippingState)) {
799                 throw new ShippingStateException();
800             }
801             else if (Validator.isNull(shippingZip)) {
802                 throw new ShippingZipException();
803             }
804             else if (Validator.isNull(shippingCountry)) {
805                 throw new ShippingCountryException();
806             }
807             else if (Validator.isNull(shippingPhone)) {
808                 throw new ShippingPhoneException();
809             }
810         }
811 
812         if ((!shoppingPrefs.usePayPal()) &&
813             (shoppingPrefs.getCcTypes().length > 0)) {
814 
815             if (Validator.isNull(ccName)) {
816                 throw new CCNameException();
817             }
818             else if (Validator.isNull(ccType)) {
819                 throw new CCTypeException();
820             }
821             else if (!CreditCard.isValid(ccNumber, ccType)) {
822                 throw new CCNumberException();
823             }
824             else if (!CalendarUtil.isFuture(ccExpMonth, ccExpYear)) {
825                 throw new CCExpirationException();
826             }
827         }
828     }
829 
830 }