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