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