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.WorkflowConstants;
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(), groupId,
156                 ShoppingOrder.class.getName(), orderId,
157                 WorkflowConstants.ACTION_PUBLISH);
158         }
159 
160         return order;
161     }
162 
163     public void completeOrder(
164             String number, String ppTxnId, String ppPaymentStatus,
165             double ppPaymentGross, String ppReceiverEmail, String ppPayerEmail,
166             boolean updateInventory)
167         throws PortalException, SystemException {
168 
169         // Order
170 
171         ShoppingOrder order = shoppingOrderPersistence.findByNumber(number);
172 
173         order.setModifiedDate(new Date());
174         order.setPpTxnId(ppTxnId);
175         order.setPpPaymentStatus(ppPaymentStatus);
176         order.setPpPaymentGross(ppPaymentGross);
177         order.setPpReceiverEmail(ppReceiverEmail);
178         order.setPpPayerEmail(ppPayerEmail);
179 
180         shoppingOrderPersistence.update(order, false);
181 
182         // Inventory
183 
184         if (updateInventory &&
185             ppPaymentStatus.equals(ShoppingOrderConstants.STATUS_COMPLETED)) {
186 
187             List<ShoppingOrderItem> orderItems =
188                 shoppingOrderItemLocalService.getOrderItems(order.getOrderId());
189 
190             for (ShoppingOrderItem orderItem : orderItems) {
191                 ShoppingItem item = shoppingItemLocalService.getItem(
192                     ShoppingUtil.getItemId(orderItem.getItemId()));
193 
194                 if (!item.isFields()) {
195                     int quantity =
196                         item.getStockQuantity() - orderItem.getQuantity();
197 
198                     item.setStockQuantity(quantity);
199                 }
200                 else {
201                     List<ShoppingItemField> itemFields =
202                         shoppingItemFieldLocalService.getItemFields(
203                             item.getItemId());
204 
205                     ShoppingItemField[] itemFieldsArray = itemFields.toArray(
206                         new ShoppingItemField[itemFields.size()]);
207 
208                     String[] fieldsArray = ShoppingCartItemImpl.getFieldsArray(
209                         ShoppingUtil.getItemFields(orderItem.getItemId()));
210 
211                     int rowPos = ShoppingUtil.getFieldsQuantitiesPos(
212                         item, itemFieldsArray, fieldsArray);
213 
214                     String[] fieldsQuantities = item.getFieldsQuantitiesArray();
215 
216                     try {
217                         int quantity =
218                             GetterUtil.getInteger(fieldsQuantities[rowPos]) -
219                             orderItem.getQuantity();
220 
221                         fieldsQuantities[rowPos] = String.valueOf(quantity);
222 
223                         item.setFieldsQuantitiesArray(fieldsQuantities);
224                     }
225                     catch (Exception e) {
226                     }
227                 }
228 
229                 shoppingItemPersistence.update(item, false);
230             }
231         }
232 
233         // Email
234 
235         try {
236             doSendEmail(order, "confirmation");
237         }
238         catch (IOException ioe) {
239             throw new SystemException(ioe);
240         }
241     }
242 
243     public void deleteOrder(long orderId)
244         throws PortalException, SystemException {
245 
246         ShoppingOrder order = shoppingOrderPersistence.findByPrimaryKey(
247             orderId);
248 
249         deleteOrder(order);
250     }
251 
252     public void deleteOrder(ShoppingOrder order)
253         throws PortalException, SystemException {
254 
255         // Order
256 
257         shoppingOrderPersistence.remove(order);
258 
259         // Items
260 
261         shoppingOrderItemPersistence.removeByOrderId(order.getOrderId());
262 
263         // Message boards
264 
265         mbMessageLocalService.deleteDiscussionMessages(
266             ShoppingOrder.class.getName(), order.getOrderId());
267     }
268 
269     public void deleteOrders(long groupId)
270         throws PortalException, SystemException {
271 
272         List<ShoppingOrder> orders = shoppingOrderPersistence.findByGroupId(
273             groupId);
274 
275         for (ShoppingOrder order : orders) {
276             deleteOrder(order);
277         }
278     }
279 
280     public ShoppingOrder getLatestOrder(long userId, long groupId)
281         throws PortalException, SystemException {
282 
283         List<ShoppingOrder> orders = shoppingOrderPersistence.findByG_U_PPPS(
284             groupId, userId, ShoppingOrderConstants.STATUS_LATEST, 0, 1);
285 
286         ShoppingOrder order = null;
287 
288         if (orders.size() == 1) {
289             order = orders.get(0);
290         }
291         else {
292             order = shoppingOrderLocalService.addLatestOrder(userId, groupId);
293         }
294 
295         return order;
296     }
297 
298     public ShoppingOrder getOrder(long orderId)
299         throws PortalException, SystemException {
300 
301         return shoppingOrderPersistence.findByPrimaryKey(orderId);
302     }
303 
304     public ShoppingOrder getOrder(String number)
305         throws PortalException, SystemException {
306 
307         return shoppingOrderPersistence.findByNumber(number);
308     }
309 
310     public ShoppingOrder getPayPalTxnIdOrder(String ppTxnId)
311         throws PortalException, SystemException {
312 
313         return shoppingOrderPersistence.findByPPTxnId(ppTxnId);
314     }
315 
316     public ShoppingOrder saveLatestOrder(ShoppingCart cart)
317         throws PortalException, SystemException {
318 
319         Map<ShoppingCartItem, Integer> items = cart.getItems();
320         Date now = new Date();
321 
322         ShoppingPreferences shoppingPrefs = ShoppingPreferences.getInstance(
323             cart.getCompanyId(), cart.getGroupId());
324 
325         if (!ShoppingUtil.meetsMinOrder(shoppingPrefs, items)) {
326             throw new CartMinOrderException();
327         }
328 
329         ShoppingOrder order = getLatestOrder(
330             cart.getUserId(), cart.getGroupId());
331 
332         order.setCreateDate(now);
333         order.setModifiedDate(now);
334         order.setPpPaymentStatus(ShoppingOrderConstants.STATUS_CHECKOUT);
335 
336         shoppingOrderPersistence.update(order, false);
337 
338         boolean requiresShipping = false;
339 
340         Iterator<Map.Entry<ShoppingCartItem, Integer>> itr =
341             items.entrySet().iterator();
342 
343         while (itr.hasNext()) {
344             Map.Entry<ShoppingCartItem, Integer> entry = itr.next();
345 
346             ShoppingCartItem cartItem = entry.getKey();
347             Integer count = entry.getValue();
348 
349             ShoppingItem item = cartItem.getItem();
350 
351             if (item.isRequiresShipping()) {
352                 requiresShipping = true;
353             }
354 
355             long orderItemId = counterLocalService.increment();
356 
357             ShoppingOrderItem orderItem = shoppingOrderItemPersistence.create(
358                 orderItemId);
359 
360             orderItem.setOrderId(order.getOrderId());
361             orderItem.setItemId(cartItem.getCartItemId());
362             orderItem.setSku(item.getSku());
363             orderItem.setName(item.getName());
364             orderItem.setDescription(item.getDescription());
365             orderItem.setProperties(item.getProperties());
366             orderItem.setPrice(
367                 ShoppingUtil.calculateActualPrice(item, count.intValue()) /
368                     count.intValue());
369             orderItem.setQuantity(count.intValue());
370 
371             shoppingOrderItemPersistence.update(orderItem, false);
372         }
373 
374         order.setModifiedDate(new Date());
375         order.setTax(
376             ShoppingUtil.calculateTax(items, order.getBillingState()));
377         order.setShipping(
378             ShoppingUtil.calculateAlternativeShipping(
379                 items, cart.getAltShipping()));
380         order.setAltShipping(
381             shoppingPrefs.getAlternativeShippingName(cart.getAltShipping()));
382         order.setRequiresShipping(requiresShipping);
383         order.setInsure(cart.isInsure());
384         order.setInsurance(ShoppingUtil.calculateInsurance(items));
385         order.setCouponCodes(cart.getCouponCodes());
386         order.setCouponDiscount(
387             ShoppingUtil.calculateCouponDiscount(
388                 items, order.getBillingState(), cart.getCoupon()));
389         order.setSendOrderEmail(true);
390         order.setSendShippingEmail(true);
391 
392         shoppingOrderPersistence.update(order, false);
393 
394         return order;
395     }
396 
397     public List<ShoppingOrder> search(
398             long groupId, long companyId, long userId, String number,
399             String billingFirstName, String billingLastName,
400             String billingEmailAddress, String shippingFirstName,
401             String shippingLastName, String shippingEmailAddress,
402             String ppPaymentStatus, boolean andOperator, int start, int end)
403         throws SystemException {
404 
405         OrderDateComparator obc = new OrderDateComparator(false);
406 
407         return shoppingOrderFinder.findByG_C_U_N_PPPS(
408             groupId, companyId, userId, number, billingFirstName,
409             billingLastName, billingEmailAddress, shippingFirstName,
410             shippingLastName, shippingEmailAddress, ppPaymentStatus,
411             andOperator, start, end, obc);
412     }
413 
414     public int searchCount(
415             long groupId, long companyId, long userId, String number,
416             String billingFirstName, String billingLastName,
417             String billingEmailAddress, String shippingFirstName,
418             String shippingLastName, String shippingEmailAddress,
419             String ppPaymentStatus, boolean andOperator)
420         throws SystemException {
421 
422         return shoppingOrderFinder.countByG_C_U_N_PPPS(
423             groupId, companyId, userId, number, billingFirstName,
424             billingLastName, billingEmailAddress, shippingFirstName,
425             shippingLastName, shippingEmailAddress, ppPaymentStatus,
426             andOperator);
427     }
428 
429     public void sendEmail(long orderId, String emailType)
430         throws PortalException, SystemException {
431 
432         ShoppingOrder order = shoppingOrderPersistence.findByPrimaryKey(
433             orderId);
434 
435         try {
436             doSendEmail(order, emailType);
437         }
438         catch (IOException ioe) {
439             throw new SystemException(ioe);
440         }
441     }
442 
443     public void sendEmail(ShoppingOrder order, String emailType)
444         throws PortalException, SystemException {
445 
446         try {
447             doSendEmail(order, emailType);
448         }
449         catch (IOException ioe) {
450             throw new SystemException(ioe);
451         }
452     }
453 
454     public ShoppingOrder updateLatestOrder(
455             long userId, long groupId, String billingFirstName,
456             String billingLastName, String billingEmailAddress,
457             String billingCompany, String billingStreet, String billingCity,
458             String billingState, String billingZip, String billingCountry,
459             String billingPhone, boolean shipToBilling,
460             String shippingFirstName, String shippingLastName,
461             String shippingEmailAddress, String shippingCompany,
462             String shippingStreet, String shippingCity, String shippingState,
463             String shippingZip, String shippingCountry, String shippingPhone,
464             String ccName, String ccType, String ccNumber, int ccExpMonth,
465             int ccExpYear, String ccVerNumber, String comments)
466         throws PortalException, SystemException {
467 
468         ShoppingOrder order = getLatestOrder(userId, groupId);
469 
470         return updateOrder(
471             order.getOrderId(), billingFirstName, billingLastName,
472             billingEmailAddress, billingCompany, billingStreet, billingCity,
473             billingState, billingZip, billingCountry, billingPhone,
474             shipToBilling, shippingFirstName, shippingLastName,
475             shippingEmailAddress, shippingCompany, shippingStreet, shippingCity,
476             shippingState, shippingZip, shippingCountry, shippingPhone,
477             ccName, ccType, ccNumber, ccExpMonth, ccExpYear, ccVerNumber,
478             comments);
479     }
480 
481     public ShoppingOrder updateOrder(
482             long orderId, String ppTxnId, String ppPaymentStatus,
483             double ppPaymentGross, String ppReceiverEmail, String ppPayerEmail)
484         throws PortalException, SystemException {
485 
486         ShoppingOrder order = shoppingOrderPersistence.findByPrimaryKey(
487             orderId);
488 
489         order.setModifiedDate(new Date());
490         order.setPpTxnId(ppTxnId);
491         order.setPpPaymentStatus(ppPaymentStatus);
492         order.setPpPaymentGross(ppPaymentGross);
493         order.setPpReceiverEmail(ppReceiverEmail);
494         order.setPpPayerEmail(ppPayerEmail);
495 
496         shoppingOrderPersistence.update(order, false);
497 
498         return order;
499     }
500 
501     public ShoppingOrder updateOrder(
502             long orderId, String billingFirstName, String billingLastName,
503             String billingEmailAddress, String billingCompany,
504             String billingStreet, String billingCity, String billingState,
505             String billingZip, String billingCountry, String billingPhone,
506             boolean shipToBilling, String shippingFirstName,
507             String shippingLastName, String shippingEmailAddress,
508             String shippingCompany, String shippingStreet, String shippingCity,
509             String shippingState, String shippingZip, String shippingCountry,
510             String shippingPhone, String ccName, String ccType, String ccNumber,
511             int ccExpMonth, int ccExpYear, String ccVerNumber, String comments)
512         throws PortalException, SystemException {
513 
514         ShoppingOrder order = shoppingOrderPersistence.findByPrimaryKey(
515             orderId);
516 
517         ShoppingPreferences shoppingPrefs = ShoppingPreferences.getInstance(
518             order.getCompanyId(), order.getGroupId());
519 
520         validate(
521             shoppingPrefs, billingFirstName, billingLastName,
522             billingEmailAddress, billingStreet, billingCity, billingState,
523             billingZip, billingCountry, billingPhone, shipToBilling,
524             shippingFirstName, shippingLastName, shippingEmailAddress,
525             shippingStreet, shippingCity, shippingState, shippingZip,
526             shippingCountry, shippingPhone, ccName, ccType, ccNumber,
527             ccExpMonth, ccExpYear, ccVerNumber);
528 
529         order.setModifiedDate(new Date());
530         order.setBillingFirstName(billingFirstName);
531         order.setBillingLastName(billingLastName);
532         order.setBillingEmailAddress(billingEmailAddress);
533         order.setBillingCompany(billingCompany);
534         order.setBillingStreet(billingStreet);
535         order.setBillingCity(billingCity);
536         order.setBillingState(billingState);
537         order.setBillingZip(billingZip);
538         order.setBillingCountry(billingCountry);
539         order.setBillingPhone(billingPhone);
540         order.setShipToBilling(shipToBilling);
541 
542         if (shipToBilling) {
543             order.setShippingFirstName(billingFirstName);
544             order.setShippingLastName(billingLastName);
545             order.setShippingEmailAddress(billingEmailAddress);
546             order.setShippingCompany(billingCompany);
547             order.setShippingStreet(billingStreet);
548             order.setShippingCity(billingCity);
549             order.setShippingState(billingState);
550             order.setShippingZip(billingZip);
551             order.setShippingCountry(billingCountry);
552             order.setShippingPhone(billingPhone);
553         }
554         else {
555             order.setShippingFirstName(shippingFirstName);
556             order.setShippingLastName(shippingLastName);
557             order.setShippingEmailAddress(shippingEmailAddress);
558             order.setShippingCompany(shippingCompany);
559             order.setShippingStreet(shippingStreet);
560             order.setShippingCity(shippingCity);
561             order.setShippingState(shippingState);
562             order.setShippingZip(shippingZip);
563             order.setShippingCountry(shippingCountry);
564             order.setShippingPhone(shippingPhone);
565         }
566 
567         order.setCcName(ccName);
568         order.setCcType(ccType);
569         order.setCcNumber(ccNumber);
570         order.setCcExpMonth(ccExpMonth);
571         order.setCcExpYear(ccExpYear);
572         order.setCcVerNumber(ccVerNumber);
573         order.setComments(comments);
574 
575         shoppingOrderPersistence.update(order, false);
576 
577         return order;
578     }
579 
580     protected void doSendEmail(ShoppingOrder order, String emailType)
581         throws IOException, PortalException, SystemException {
582 
583         ShoppingPreferences shoppingPrefs = ShoppingPreferences.getInstance(
584             order.getCompanyId(), order.getGroupId());
585 
586         if (emailType.equals("confirmation") &&
587             shoppingPrefs.getEmailOrderConfirmationEnabled()) {
588         }
589         else if (emailType.equals("shipping") &&
590                  shoppingPrefs.getEmailOrderShippingEnabled()) {
591         }
592         else {
593             return;
594         }
595 
596         Company company = companyPersistence.findByPrimaryKey(
597             order.getCompanyId());
598 
599         User user = userPersistence.findByPrimaryKey(order.getUserId());
600 
601         Currency currency = Currency.getInstance(shoppingPrefs.getCurrencyId());
602 
603         String billingAddress =
604             order.getBillingFirstName() + " " + order.getBillingLastName() +
605                 "<br>" +
606             order.getBillingEmailAddress() + "<br>" +
607             order.getBillingStreet() + "<br>" +
608             order.getBillingCity() + "<br>" +
609             order.getBillingState() + "<br>" +
610             order.getBillingZip() + "<br>" +
611             order.getBillingCountry() + "<br>" +
612             order.getBillingPhone() + "<br>";
613 
614         String shippingAddress =
615             order.getShippingFirstName() + " " + order.getShippingLastName() +
616                 "<br>" +
617             order.getShippingEmailAddress() + "<br>" +
618             order.getShippingStreet() + "<br>" +
619             order.getShippingCity() + "<br>" +
620             order.getShippingState() + "<br>" +
621             order.getShippingZip() + "<br>" +
622             order.getShippingCountry() + "<br>" +
623             order.getShippingPhone() + "<br>";
624 
625         double total = ShoppingUtil.calculateTotal(order);
626 
627         String portletName = PortalUtil.getPortletTitle(
628             PortletKeys.SHOPPING, user);
629 
630         String fromName = shoppingPrefs.getEmailFromName();
631         String fromAddress = shoppingPrefs.getEmailFromAddress();
632 
633         String toName = user.getFullName();
634         String toAddress = user.getEmailAddress();
635 
636         String subject = null;
637         String body = null;
638 
639         if (emailType.equals("confirmation")) {
640             subject = shoppingPrefs.getEmailOrderConfirmationSubject();
641             body = shoppingPrefs.getEmailOrderConfirmationBody();
642         }
643         else if (emailType.equals("shipping")) {
644             subject = shoppingPrefs.getEmailOrderShippingSubject();
645             body = shoppingPrefs.getEmailOrderShippingBody();
646         }
647 
648         subject = StringUtil.replace(
649             subject,
650             new String[] {
651                 "[$FROM_ADDRESS$]",
652                 "[$FROM_NAME$]",
653                 "[$ORDER_BILLING_ADDRESS$]",
654                 "[$ORDER_CURRENCY$]",
655                 "[$ORDER_NUMBER$]",
656                 "[$ORDER_SHIPPING_ADDRESS$]",
657                 "[$ORDER_TOTAL$]",
658                 "[$PORTAL_URL$]",
659                 "[$PORTLET_NAME$]",
660                 "[$TO_ADDRESS$]",
661                 "[$TO_NAME$]"
662             },
663             new String[] {
664                 fromAddress,
665                 fromName,
666                 billingAddress,
667                 currency.getSymbol(),
668                 order.getNumber(),
669                 shippingAddress,
670                 String.valueOf(total),
671                 company.getVirtualHost(),
672                 portletName,
673                 toAddress,
674                 toName
675             });
676 
677         body = StringUtil.replace(
678             body,
679             new String[] {
680                 "[$FROM_ADDRESS$]",
681                 "[$FROM_NAME$]",
682                 "[$ORDER_BILLING_ADDRESS$]",
683                 "[$ORDER_CURRENCY$]",
684                 "[$ORDER_NUMBER$]",
685                 "[$ORDER_SHIPPING_ADDRESS$]",
686                 "[$ORDER_TOTAL$]",
687                 "[$PORTAL_URL$]",
688                 "[$PORTLET_NAME$]",
689                 "[$TO_ADDRESS$]",
690                 "[$TO_NAME$]"
691             },
692             new String[] {
693                 fromAddress,
694                 fromName,
695                 billingAddress,
696                 currency.getSymbol(),
697                 order.getNumber(),
698                 shippingAddress,
699                 String.valueOf(total),
700                 company.getVirtualHost(),
701                 portletName,
702                 toAddress,
703                 toName
704             });
705 
706         InternetAddress from = new InternetAddress(fromAddress, fromName);
707 
708         InternetAddress to = new InternetAddress(toAddress, toName);
709 
710         MailMessage message = new MailMessage(from, to, subject, body, true);
711 
712         mailService.sendEmail(message);
713 
714         if (emailType.equals("confirmation") && order.isSendOrderEmail()) {
715             order.setSendOrderEmail(false);
716 
717             shoppingOrderPersistence.update(order, false);
718         }
719         else if (emailType.equals("shipping") &&
720                  order.isSendShippingEmail()) {
721 
722             order.setSendShippingEmail(false);
723 
724             shoppingOrderPersistence.update(order, false);
725         }
726     }
727 
728     protected String getNumber() throws SystemException {
729         String number = PwdGenerator.getPassword(
730             PwdGenerator.KEY1 + PwdGenerator.KEY2, 12);
731 
732         try {
733             shoppingOrderPersistence.findByNumber(number);
734 
735             return getNumber();
736         }
737         catch (NoSuchOrderException nsoe) {
738             return number;
739         }
740     }
741 
742     protected void validate(
743             ShoppingPreferences shoppingPrefs, String billingFirstName,
744             String billingLastName, String billingEmailAddress,
745             String billingStreet, String billingCity, String billingState,
746             String billingZip, String billingCountry, String billingPhone,
747             boolean shipToBilling, String shippingFirstName,
748             String shippingLastName, String shippingEmailAddress,
749             String shippingStreet, String shippingCity, String shippingState,
750             String shippingZip, String shippingCountry, String shippingPhone,
751             String ccName, String ccType, String ccNumber, int ccExpMonth,
752             int ccExpYear, String ccVerNumber)
753         throws PortalException {
754 
755         if (Validator.isNull(billingFirstName)) {
756             throw new BillingFirstNameException();
757         }
758         else if (Validator.isNull(billingLastName)) {
759             throw new BillingLastNameException();
760         }
761         else if (!Validator.isEmailAddress(billingEmailAddress)) {
762             throw new BillingEmailAddressException();
763         }
764         else if (Validator.isNull(billingStreet)) {
765             throw new BillingStreetException();
766         }
767         else if (Validator.isNull(billingCity)) {
768             throw new BillingCityException();
769         }
770         else if (Validator.isNull(billingState)) {
771             throw new BillingStateException();
772         }
773         else if (Validator.isNull(billingZip)) {
774             throw new BillingZipException();
775         }
776         else if (Validator.isNull(billingCountry)) {
777             throw new BillingCountryException();
778         }
779         else if (Validator.isNull(billingPhone)) {
780             throw new BillingPhoneException();
781         }
782 
783         if (!shipToBilling) {
784             if (Validator.isNull(shippingFirstName)) {
785                 throw new ShippingFirstNameException();
786             }
787             else if (Validator.isNull(shippingLastName)) {
788                 throw new ShippingLastNameException();
789             }
790             else if (!Validator.isEmailAddress(shippingEmailAddress)) {
791                 throw new ShippingEmailAddressException();
792             }
793             else if (Validator.isNull(shippingStreet)) {
794                 throw new ShippingStreetException();
795             }
796             else if (Validator.isNull(shippingCity)) {
797                 throw new ShippingCityException();
798             }
799             else if (Validator.isNull(shippingState)) {
800                 throw new ShippingStateException();
801             }
802             else if (Validator.isNull(shippingZip)) {
803                 throw new ShippingZipException();
804             }
805             else if (Validator.isNull(shippingCountry)) {
806                 throw new ShippingCountryException();
807             }
808             else if (Validator.isNull(shippingPhone)) {
809                 throw new ShippingPhoneException();
810             }
811         }
812 
813         if ((!shoppingPrefs.usePayPal()) &&
814             (shoppingPrefs.getCcTypes().length > 0)) {
815 
816             if (Validator.isNull(ccName)) {
817                 throw new CCNameException();
818             }
819             else if (Validator.isNull(ccType)) {
820                 throw new CCTypeException();
821             }
822             else if (!CreditCard.isValid(ccNumber, ccType)) {
823                 throw new CCNumberException();
824             }
825             else if (!CalendarUtil.isFuture(ccExpMonth, ccExpYear)) {
826                 throw new CCExpirationException();
827             }
828         }
829     }
830 
831 }