KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > order > shoppingcart > CheckOutHelper


1 /*
2  * $Id: CheckOutHelper.java 7287 2006-04-13 18:37:16Z sichen $
3  *
4  * Copyright (c) 2001-2005 The Open For Business Project - www.ofbiz.org
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
21  * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
22  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */

24 package org.ofbiz.order.shoppingcart;
25
26 import java.math.BigDecimal JavaDoc;
27 import java.sql.Timestamp JavaDoc;
28 import java.text.DecimalFormat JavaDoc;
29 import java.text.ParseException JavaDoc;
30 import java.util.ArrayList JavaDoc;
31 import java.util.HashMap JavaDoc;
32 import java.util.Iterator JavaDoc;
33 import java.util.LinkedList JavaDoc;
34 import java.util.List JavaDoc;
35 import java.util.Locale JavaDoc;
36 import java.util.Map JavaDoc;
37 import java.util.Set JavaDoc;
38
39 import org.ofbiz.base.util.*;
40 import org.ofbiz.entity.GenericDelegator;
41 import org.ofbiz.entity.GenericEntityException;
42 import org.ofbiz.entity.GenericValue;
43 import org.ofbiz.entity.condition.EntityExpr;
44 import org.ofbiz.entity.condition.EntityFieldValue;
45 import org.ofbiz.entity.condition.EntityFunction;
46 import org.ofbiz.entity.condition.EntityOperator;
47 import org.ofbiz.entity.util.EntityUtil;
48 import org.ofbiz.order.finaccount.FinAccountHelper;
49 import org.ofbiz.order.order.OrderChangeHelper;
50 import org.ofbiz.party.contact.ContactHelper;
51 import org.ofbiz.product.store.ProductStoreWorker;
52 import org.ofbiz.service.GenericServiceException;
53 import org.ofbiz.service.LocalDispatcher;
54 import org.ofbiz.service.ModelService;
55 import org.ofbiz.service.ServiceUtil;
56
57 /**
58  * A facade over the ShoppingCart to simplify the relatively complex
59  * processing required to create an order in the system.
60  *
61  * @author <a HREF="mailto:jaz@ofbiz.org">Andy Zeneski</a>
62  * @author <a HREF="mailto:cnelson@einnovation.com">Chris Nelson</a>
63  * @author <a HREF="mailto:jonesde@ofbiz.org">David E. Jones</a>
64  * @author <a HREF="mailto:tristana@twibble.org">Tristan Austin</a>
65  * @version $Rev: 7287 $
66  * @since 2.0
67  */

68 public class CheckOutHelper {
69
70     public static final String JavaDoc module = CheckOutHelper.class.getName();
71     public static final String JavaDoc resource = "OrderUiLabels";
72     public static final String JavaDoc resource_error = "OrderErrorUiLabels";
73
74     protected LocalDispatcher dispatcher = null;
75     protected GenericDelegator delegator = null;
76     protected ShoppingCart cart = null;
77
78     public CheckOutHelper(LocalDispatcher dispatcher, GenericDelegator delegator, ShoppingCart cart) {
79         this.delegator = delegator;
80         this.dispatcher = dispatcher;
81         this.cart = cart;
82     }
83
84     public Map JavaDoc setCheckOutShippingAddress(String JavaDoc shippingContactMechId) {
85         List JavaDoc errorMessages = new ArrayList JavaDoc();
86         Map JavaDoc result;
87         String JavaDoc errMsg = null;
88
89         if (this.cart != null && this.cart.size() > 0) {
90             errorMessages.addAll(setCheckOutShippingAddressInternal(shippingContactMechId));
91         } else {
92             errMsg = UtilProperties.getMessage(resource,"checkhelper.no_items_in_cart", (cart != null ? cart.getLocale() : Locale.getDefault()));
93             errorMessages.add(errMsg);
94         }
95         if (errorMessages.size() == 1) {
96             result = ServiceUtil.returnError(errorMessages.get(0).toString());
97         } else if (errorMessages.size() > 0) {
98             result = ServiceUtil.returnError(errorMessages);
99         } else {
100             result = ServiceUtil.returnSuccess();
101         }
102
103         return result;
104     }
105
106     private List JavaDoc setCheckOutShippingAddressInternal(String JavaDoc shippingContactMechId) {
107         List JavaDoc errorMessages = new ArrayList JavaDoc();
108         String JavaDoc errMsg = null;
109
110         // set the shipping address
111
if (UtilValidate.isNotEmpty(shippingContactMechId)) {
112             this.cart.setShippingContactMechId(shippingContactMechId);
113         } else if (cart.shippingApplies()) {
114             // only return an error if shipping is required for this purchase
115
errMsg = UtilProperties.getMessage(resource,"checkhelper.select_shipping_destination", (cart != null ? cart.getLocale() : Locale.getDefault()));
116             errorMessages.add(errMsg);
117         }
118
119         return errorMessages;
120     }
121
122     public Map JavaDoc setCheckOutShippingOptions(String JavaDoc shippingMethod, String JavaDoc correspondingPoId, String JavaDoc shippingInstructions,
123             String JavaDoc orderAdditionalEmails, String JavaDoc maySplit, String JavaDoc giftMessage, String JavaDoc isGift, String JavaDoc internalCode, String JavaDoc shipBeforeDate, String JavaDoc shipAfterDate ) {
124         List JavaDoc errorMessages = new ArrayList JavaDoc();
125         Map JavaDoc result;
126         String JavaDoc errMsg = null;
127
128         if (this.cart != null && this.cart.size() > 0) {
129             errorMessages.addAll(setCheckOutShippingOptionsInternal(shippingMethod, correspondingPoId,
130                     shippingInstructions, orderAdditionalEmails, maySplit, giftMessage, isGift, internalCode, shipBeforeDate, shipAfterDate));
131         } else {
132             errMsg = UtilProperties.getMessage(resource,"checkhelper.no_items_in_cart", (cart != null ? cart.getLocale() : Locale.getDefault()));
133             errorMessages.add(errMsg);
134         }
135
136         if (errorMessages.size() == 1) {
137             result = ServiceUtil.returnError(errorMessages.get(0).toString());
138         } else if (errorMessages.size() > 0) {
139             result = ServiceUtil.returnError(errorMessages);
140         } else {
141             result = ServiceUtil.returnSuccess();
142         }
143
144         return result;
145     }
146
147     private List JavaDoc setCheckOutShippingOptionsInternal(String JavaDoc shippingMethod, String JavaDoc correspondingPoId, String JavaDoc shippingInstructions,
148             String JavaDoc orderAdditionalEmails, String JavaDoc maySplit, String JavaDoc giftMessage, String JavaDoc isGift, String JavaDoc internalCode, String JavaDoc shipBeforeDate, String JavaDoc shipAfterDate ) {
149         List JavaDoc errorMessages = new ArrayList JavaDoc();
150         String JavaDoc errMsg = null;
151
152         // set the general shipping options
153
if (UtilValidate.isNotEmpty(shippingMethod)) {
154             int delimiterPos = shippingMethod.indexOf('@');
155             String JavaDoc shipmentMethodTypeId = null;
156             String JavaDoc carrierPartyId = null;
157
158             if (delimiterPos > 0) {
159                 shipmentMethodTypeId = shippingMethod.substring(0, delimiterPos);
160                 carrierPartyId = shippingMethod.substring(delimiterPos + 1);
161             }
162
163             this.cart.setShipmentMethodTypeId(shipmentMethodTypeId);
164             this.cart.setCarrierPartyId(carrierPartyId);
165         } else if (cart.shippingApplies()) {
166             // only return an error if shipping is required for this purchase
167
errMsg = UtilProperties.getMessage(resource,"checkhelper.select_shipping_method", (cart != null ? cart.getLocale() : Locale.getDefault()));
168             errorMessages.add(errMsg);
169         }
170
171         // set the shipping instructions
172
this.cart.setShippingInstructions(shippingInstructions);
173
174         if (UtilValidate.isNotEmpty(maySplit)) {
175             cart.setMaySplit(Boolean.valueOf(maySplit));
176         } else {
177             errMsg = UtilProperties.getMessage(resource,"checkhelper.select_splitting_preference", (cart != null ? cart.getLocale() : Locale.getDefault()));
178             errorMessages.add(errMsg);
179         }
180
181         // set the gift message
182
this.cart.setGiftMessage(giftMessage);
183
184         if (UtilValidate.isNotEmpty(isGift)) {
185             cart.setIsGift(Boolean.valueOf(isGift));
186         } else {
187             errMsg = UtilProperties.getMessage(resource, "checkhelper.specify_if_order_is_gift", (cart != null ? cart.getLocale() : Locale.getDefault()));
188             errorMessages.add(errMsg);
189         }
190
191         // interal code
192
this.cart.setInternalCode(internalCode);
193
194         if (shipBeforeDate != null && shipBeforeDate.length() > 0) {
195             if (UtilValidate.isDate(shipBeforeDate)) {
196                 cart.setShipBeforeDate(UtilDateTime.toTimestamp(shipBeforeDate));
197             } else {
198                 errMsg = UtilProperties.getMessage(resource, "checkhelper.specify_if_shipBeforeDate_is_date", (cart != null ? cart.getLocale() : Locale.getDefault()));
199                 errorMessages.add(errMsg);
200             }
201         }
202
203         if (shipAfterDate != null && shipAfterDate.length() > 0) {
204             if (UtilValidate.isDate(shipAfterDate)) {
205                 cart.setShipAfterDate(UtilDateTime.toTimestamp(shipAfterDate));
206             } else {
207                 errMsg = UtilProperties.getMessage(resource, "checkhelper.specify_if_shipAfterDate_is_date", (cart != null ? cart.getLocale() : Locale.getDefault()));
208                 errorMessages.add(errMsg);
209             }
210         }
211
212         // set any additional notification emails
213
this.cart.setOrderAdditionalEmails(orderAdditionalEmails);
214
215         // set the PO number
216
if (UtilValidate.isNotEmpty(correspondingPoId)) {
217             this.cart.setPoNumber(correspondingPoId);
218         } else {
219             this.cart.setPoNumber(null);
220         }
221
222         return errorMessages;
223     }
224
225     public Map JavaDoc setCheckOutPayment(Map JavaDoc selectedPaymentMethods, List JavaDoc singleUsePayments, String JavaDoc billingAccountId, Double JavaDoc billingAccountAmt) {
226         List JavaDoc errorMessages = new ArrayList JavaDoc();
227         Map JavaDoc result;
228         String JavaDoc errMsg = null;
229
230         if (this.cart != null && this.cart.size() > 0) {
231             errorMessages.addAll(setCheckOutPaymentInternal(selectedPaymentMethods, singleUsePayments, billingAccountId, billingAccountAmt));
232         } else {
233             errMsg = UtilProperties.getMessage(resource,"checkhelper.no_items_in_cart", (cart != null ? cart.getLocale() : Locale.getDefault()));
234             errorMessages.add(errMsg);
235         }
236
237         if (errorMessages.size() == 1) {
238             result = ServiceUtil.returnError(errorMessages.get(0).toString());
239         } else if (errorMessages.size() > 0) {
240             result = ServiceUtil.returnError(errorMessages);
241         } else {
242             result = ServiceUtil.returnSuccess();
243         }
244
245         return result;
246     }
247
248     private List JavaDoc setCheckOutPaymentInternal(Map JavaDoc selectedPaymentMethods, List JavaDoc singleUsePayments, String JavaDoc billingAccountId, Double JavaDoc billingAccountAmt) {
249         List JavaDoc errorMessages = new ArrayList JavaDoc();
250         String JavaDoc errMsg = null;
251
252         if (singleUsePayments == null) {
253             singleUsePayments = new ArrayList JavaDoc();
254         }
255
256         // set the billing account amount
257
if (billingAccountId != null && billingAccountAmt != null && !billingAccountId.equals("_NA_")) {
258             cart.setBillingAccount(billingAccountId, billingAccountAmt.doubleValue());
259         } else {
260             cart.setBillingAccount(null, 0.00);
261         }
262
263         // set the payment method option
264
if (selectedPaymentMethods != null && selectedPaymentMethods.size() > 0) {
265             // clear out the old payments
266
cart.clearPayments();
267
268             // if we are EXT_BILLACT (billing account only) then we need to make sure we have enough credit
269
if (selectedPaymentMethods.containsKey("EXT_BILLACT")) {
270                 double accountCredit = this.availableAccountBalance(cart.getBillingAccountId());
271                 // make sure we have enough to cover; if this is selected we don't have other payment methods
272
if (cart.getGrandTotal() > accountCredit) {
273                     errMsg = UtilProperties.getMessage(resource,"checkhelper.insufficient_credit_available_on_account",
274                             (cart != null ? cart.getLocale() : Locale.getDefault()));
275                     errorMessages.add(errMsg);
276                 }
277             }
278
279             Set JavaDoc paymentMethods = selectedPaymentMethods.keySet();
280             Iterator JavaDoc i = paymentMethods.iterator();
281             while (i.hasNext()) {
282                 String JavaDoc checkOutPaymentId = (String JavaDoc) i.next();
283
284                 // get the selected amount to use
285
Double JavaDoc paymentAmount = null;
286                 if (selectedPaymentMethods.get(checkOutPaymentId) != null) {
287                     paymentAmount = (Double JavaDoc) selectedPaymentMethods.get(checkOutPaymentId);
288                 }
289
290                 boolean singleUse = singleUsePayments.contains(checkOutPaymentId);
291                 cart.addPaymentAmount(checkOutPaymentId, paymentAmount, singleUse);
292             }
293         } else if (cart.getGrandTotal() != 0.00) {
294             // only return an error if the order total is not 0.00
295
errMsg = UtilProperties.getMessage(resource,"checkhelper.select_method_of_payment",
296                     (cart != null ? cart.getLocale() : Locale.getDefault()));
297             errorMessages.add(errMsg);
298         }
299
300         return errorMessages;
301     }
302
303     public Map JavaDoc setCheckOutDates(Timestamp JavaDoc shipBefore, Timestamp JavaDoc shipAfter) {
304           List JavaDoc errorMessages = new ArrayList JavaDoc();
305           Map JavaDoc result = null;
306           String JavaDoc errMsg = null;
307
308           if (this.cart != null && this.cart.size() > 0) {
309             this.cart.setShipBeforeDate(shipBefore);
310             this.cart.setShipAfterDate(shipAfter);
311           } else {
312             errMsg = UtilProperties.getMessage(resource,"checkhelper.no_items_in_cart",
313                                                      (cart != null ? cart.getLocale() : Locale.getDefault()));
314             errorMessages.add(errMsg);
315           }
316
317           if (errorMessages.size() == 1) {
318             result = ServiceUtil.returnError(errorMessages.get(0).toString());
319           } else if (errorMessages.size() > 0) {
320             result = ServiceUtil.returnError(errorMessages);
321           } else {
322             result = ServiceUtil.returnSuccess();
323           }
324           return result;
325       }
326
327
328     public Map JavaDoc setCheckOutOptions(String JavaDoc shippingMethod, String JavaDoc shippingContactMechId, Map JavaDoc selectedPaymentMethods,
329             List JavaDoc singleUsePayments, String JavaDoc billingAccountId, Double JavaDoc billingAccountAmt, String JavaDoc correspondingPoId,
330             String JavaDoc shippingInstructions, String JavaDoc orderAdditionalEmails, String JavaDoc maySplit, String JavaDoc giftMessage, String JavaDoc isGift, String JavaDoc internalCode, String JavaDoc shipBeforeDate, String JavaDoc shipAfterDate) {
331         List JavaDoc errorMessages = new ArrayList JavaDoc();
332         Map JavaDoc result = null;
333         String JavaDoc errMsg = null;
334
335
336         if (this.cart != null && this.cart.size() > 0) {
337             // set the general shipping options and method
338
errorMessages.addAll(setCheckOutShippingOptionsInternal(shippingMethod, correspondingPoId,
339                     shippingInstructions, orderAdditionalEmails, maySplit, giftMessage, isGift, internalCode, shipBeforeDate, shipAfterDate));
340
341             // set the shipping address
342
errorMessages.addAll(setCheckOutShippingAddressInternal(shippingContactMechId));
343
344             // set the payment method(s) option
345
errorMessages.addAll(setCheckOutPaymentInternal(selectedPaymentMethods, singleUsePayments, billingAccountId, billingAccountAmt));
346
347         } else {
348             errMsg = UtilProperties.getMessage(resource,"checkhelper.no_items_in_cart", (cart != null ? cart.getLocale() : Locale.getDefault()));
349             errorMessages.add(errMsg);
350         }
351
352         if (errorMessages.size() == 1) {
353             result = ServiceUtil.returnError(errorMessages.get(0).toString());
354         } else if (errorMessages.size() > 0) {
355             result = ServiceUtil.returnError(errorMessages);
356         } else {
357             result = ServiceUtil.returnSuccess();
358         }
359
360         return result;
361     }
362
363     public Map JavaDoc checkGiftCard(Map JavaDoc params, Map JavaDoc selectedPaymentMethods) {
364         List JavaDoc errorMessages = new ArrayList JavaDoc();
365         Map JavaDoc errorMaps = new HashMap JavaDoc();
366         Map JavaDoc result = new HashMap JavaDoc();
367         String JavaDoc errMsg = null;
368         // handle gift card payment
369
if (params.get("addGiftCard") != null) {
370             String JavaDoc gcNum = (String JavaDoc) params.get("giftCardNumber");
371             String JavaDoc gcPin = (String JavaDoc) params.get("giftCardPin");
372             String JavaDoc gcAmt = (String JavaDoc) params.get("giftCardAmount");
373             double gcAmount = -1;
374
375             boolean gcFieldsOkay = true;
376             if (gcNum == null || gcNum.length() == 0) {
377                 errMsg = UtilProperties.getMessage(resource,"checkhelper.enter_gift_card_number", (cart != null ? cart.getLocale() : Locale.getDefault()));
378                 errorMessages.add(errMsg);
379                 gcFieldsOkay = false;
380             }
381             if (cart.isPinRequiredForGC(delegator)) {
382                 // if a PIN is required, make sure the PIN is valid
383
if ((gcPin == null) || (gcPin.length() == 0)) {
384                     errMsg = UtilProperties.getMessage(resource,"checkhelper.enter_gift_card_pin_number", (cart != null ? cart.getLocale() : Locale.getDefault()));
385                     errorMessages.add(errMsg);
386                     gcFieldsOkay = false;
387                 }
388             }
389             // See if we should validate gift card code against FinAccount's accountCode
390
if (cart.isValidateGCFinAccount(delegator)) {
391                 try {
392                     // No PIN required - validate gift card number against account code
393
if (!cart.isPinRequiredForGC(delegator)) {
394                         GenericValue finAccount = FinAccountHelper.getFinAccountFromCode(gcNum, delegator);
395                         if (finAccount == null) {
396                             errMsg = UtilProperties.getMessage(resource,"checkhelper.gift_card_does_not_exist", (cart != null ? cart.getLocale() : Locale.getDefault()));
397                             errorMessages.add(errMsg);
398                             gcFieldsOkay = false;
399                         } else if ((FinAccountHelper.getAvailableBalance(finAccount.getString("finAccountId"), cart.getCurrency(), delegator) == null) ||
400                                 !(FinAccountHelper.getAvailableBalance(finAccount.getString("finAccountId"), cart.getCurrency(), delegator).compareTo(FinAccountHelper.ZERO) == 1)) {
401                             // if account's available balance (including authorizations) is not greater than zero, then return an error
402
errMsg = UtilProperties.getMessage(resource,"checkhelper.gift_card_has_no_value", (cart != null ? cart.getLocale() : Locale.getDefault()));
403                             errorMessages.add(errMsg);
404                             gcFieldsOkay = false;
405                         }
406                     }
407                     // TODO: else case when pin is required - we should validate gcNum and gcPin
408
} catch (GenericEntityException ex) {
409                     errorMessages.add(ex.getMessage());
410                     gcFieldsOkay = false;
411                 }
412             }
413             
414             if (selectedPaymentMethods != null && selectedPaymentMethods.size() > 0) {
415                 if (gcAmt == null || gcAmt.length() == 0) {
416                     errMsg = UtilProperties.getMessage(resource,"checkhelper.enter_amount_to_place_on_gift_card", (cart != null ? cart.getLocale() : Locale.getDefault()));
417                     errorMessages.add(errMsg);
418                     gcFieldsOkay = false;
419                 }
420             }
421             if (gcAmt != null && gcAmt.length() > 0) {
422                 try {
423                     gcAmount = Double.parseDouble(gcAmt);
424                 } catch (NumberFormatException JavaDoc e) {
425                     Debug.logError(e, module);
426                     errMsg = UtilProperties.getMessage(resource,"checkhelper.invalid_amount_for_gift_card", (cart != null ? cart.getLocale() : Locale.getDefault()));
427                     errorMessages.add(errMsg);
428                     gcFieldsOkay = false;
429                 }
430             }
431
432             if (gcFieldsOkay) {
433                 // store the gift card
434
Map JavaDoc gcCtx = new HashMap JavaDoc();
435                 gcCtx.put("partyId", params.get("partyId"));
436                 gcCtx.put("cardNumber", gcNum);
437                 if (cart.isPinRequiredForGC(delegator)) {
438                     gcCtx.put("pinNumber", gcPin);
439                 }
440                 gcCtx.put("userLogin", cart.getUserLogin());
441                 Map JavaDoc gcResult = null;
442                 try {
443                     gcResult = dispatcher.runSync("createGiftCard", gcCtx);
444                 } catch (GenericServiceException e) {
445                     Debug.logError(e, module);
446                     errorMessages.add(e.getMessage());
447                 }
448                 if (gcResult != null) {
449                     this.addErrors(errorMessages, errorMaps, gcResult);
450
451                     if (errorMessages.size() == 0 && errorMaps.size() == 0) {
452                         // set the GC payment method
453
Double JavaDoc giftCardAmount = null;
454                         if (gcAmount > 0) {
455                             giftCardAmount = new Double JavaDoc(gcAmount);
456                         }
457                         String JavaDoc gcPaymentMethodId = (String JavaDoc) gcResult.get("paymentMethodId");
458                         result = ServiceUtil.returnSuccess();
459                         result.put("paymentMethodId", gcPaymentMethodId);
460                         result.put("amount", giftCardAmount);
461                     }
462                 } else {
463                     errMsg = UtilProperties.getMessage(resource,"checkhelper.problem_with_gift_card_information", (cart != null ? cart.getLocale() : Locale.getDefault()));
464                     errorMessages.add(errMsg);
465                 }
466             }
467         } else {
468             result = ServiceUtil.returnSuccess();
469         }
470
471         // see whether we need to return an error or not
472
if (errorMessages.size() > 0) {
473             result.put(ModelService.ERROR_MESSAGE_LIST, errorMessages);
474             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
475         }
476         if (errorMaps.size() > 0) {
477             result.put(ModelService.ERROR_MESSAGE_MAP, errorMaps);
478             result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
479         }
480
481         return result;
482     }
483
484     public Map JavaDoc createOrder(GenericValue userLogin) {
485         return createOrder(userLogin, null, null, null, false, null, null);
486     }
487
488     // Create order event - uses createOrder service for processing
489
public Map JavaDoc createOrder(GenericValue userLogin, String JavaDoc distributorId, String JavaDoc affiliateId,
490             List JavaDoc trackingCodeOrders, boolean areOrderItemsExploded, String JavaDoc visitId, String JavaDoc webSiteId) {
491         if (this.cart == null) {
492             return null;
493         }
494         String JavaDoc orderId = this.cart.getOrderId();
495         this.cart.clearAllItemStatus();
496
497         // format the grandTotal
498
String JavaDoc currencyFormat = UtilProperties.getPropertyValue("general.properties", "currency.decimal.format", "##0.00");
499         DecimalFormat JavaDoc formatter = new DecimalFormat JavaDoc(currencyFormat);
500         double cartTotal = this.cart.getGrandTotal();
501         String JavaDoc grandTotalString = formatter.format(cartTotal);
502         Double JavaDoc grandTotal = null;
503         try {
504             grandTotal = new Double JavaDoc(formatter.parse(grandTotalString).doubleValue());
505         } catch (ParseException JavaDoc e) {
506             Debug.logError(e, "Problem getting parsed currency amount from DecimalFormat", module);
507             String JavaDoc errMsg = UtilProperties.getMessage(resource,"checkhelper.could_not_create_order_parsing_totals", (cart != null ? cart.getLocale() : Locale.getDefault()));
508             return ServiceUtil.returnError(errMsg);
509         }
510
511         // store the order - build the context
512
Map JavaDoc context = this.cart.makeCartMap(this.dispatcher, areOrderItemsExploded);
513
514         //get the TrackingCodeOrder List
515
context.put("trackingCodeOrders", trackingCodeOrders);
516
517         if (distributorId != null) context.put("distributorId", distributorId);
518         if (affiliateId != null) context.put("affiliateId", affiliateId);
519
520         // need the partyId; don't use userLogin in case of an order via order mgr
521
String JavaDoc partyId = this.cart.getPartyId();
522         String JavaDoc facilityId = this.cart.getFacilityId();
523         String JavaDoc terminalId = this.cart.getTerminalId();
524         String JavaDoc transactionId = cart.getTransactionId();
525         String JavaDoc productStoreId = cart.getProductStoreId();
526
527         context.put("grandTotal", grandTotal);
528         context.put("userLogin", userLogin);
529         context.put("partyId", partyId);
530         context.put("productStoreId", productStoreId);
531         context.put("transactionId", transactionId);
532         context.put("originFacilityId", facilityId);
533         context.put("visitId", visitId);
534         context.put("terminalId", terminalId);
535         context.put("webSiteId", webSiteId);
536
537         // store the order - invoke the service
538
Map JavaDoc storeResult = null;
539
540         try {
541             storeResult = dispatcher.runSync("storeOrder", context);
542             orderId = (String JavaDoc) storeResult.get("orderId");
543             if (orderId != null && orderId.length() > 0) {
544                 this.cart.setOrderId(orderId);
545                 if (this.cart.getFirstAttemptOrderId() == null) {
546                     this.cart.setFirstAttemptOrderId(orderId);
547                 }
548             }
549         } catch (GenericServiceException e) {
550             String JavaDoc service = e.getMessage();
551             Map JavaDoc messageMap = UtilMisc.toMap("service", service);
552             String JavaDoc errMsg = UtilProperties.getMessage(resource, "checkhelper.could_not_create_order_invoking_service", messageMap, (cart != null ? cart.getLocale() : Locale.getDefault()));
553             Debug.logError(e, errMsg, module);
554             return ServiceUtil.returnError(errMsg);
555         }
556
557         // check for error message(s)
558
if (ServiceUtil.isError(storeResult)) {
559             String JavaDoc errMsg = UtilProperties.getMessage(resource, "checkhelper.did_not_complete_order_following_occurred", (cart != null ? cart.getLocale() : Locale.getDefault()));
560             List JavaDoc resErrorMessages = new LinkedList JavaDoc();
561             resErrorMessages.add(errMsg);
562             resErrorMessages.add(ServiceUtil.getErrorMessage(storeResult));
563             return ServiceUtil.returnError(resErrorMessages);
564         }
565
566         // ----------
567
// If needed, the production runs are created and linked to the order lines.
568
//
569
Iterator JavaDoc orderItems = ((List JavaDoc)context.get("orderItems")).iterator();
570         int counter = 0;
571         while (orderItems.hasNext()) {
572             GenericValue orderItem = (GenericValue)orderItems.next();
573             String JavaDoc productId = orderItem.getString("productId");
574             if (productId != null) {
575                 try {
576                     GenericValue productStore = ProductStoreWorker.getProductStore(productStoreId, delegator);
577                     GenericValue product = delegator.findByPrimaryKey("Product", UtilMisc.toMap("productId", productId));
578                     if ("AGGREGATED".equals(product.getString("productTypeId"))) {
579                         org.ofbiz.product.config.ProductConfigWrapper config = this.cart.findCartItem(counter).getConfigWrapper();
580                         Map JavaDoc inputMap = new HashMap JavaDoc();
581                         inputMap.put("config", config);
582                         inputMap.put("facilityId", productStore.getString("inventoryFacilityId"));
583                         inputMap.put("orderId", orderId);
584                         inputMap.put("orderItemSeqId", orderItem.getString("orderItemSeqId"));
585                         inputMap.put("quantity", orderItem.getDouble("quantity"));
586                         inputMap.put("userLogin", userLogin);
587                         
588                         Map JavaDoc prunResult = dispatcher.runSync("createProductionRunFromConfiguration", inputMap);
589                         if (ServiceUtil.isError(prunResult)) {
590                             Debug.logError(ServiceUtil.getErrorMessage(prunResult) + " for input:" + inputMap, module);
591                         }
592                     }
593                 } catch (Exception JavaDoc e) {
594                     String JavaDoc service = e.getMessage();
595                     Map JavaDoc messageMap = UtilMisc.toMap("service", service);
596                     String JavaDoc errMsg = UtilProperties.getMessage(resource, "checkhelper.could_not_create_order_invoking_service", messageMap, (cart != null ? cart.getLocale() : Locale.getDefault()));
597                     Debug.logError(e, errMsg, module);
598                     return ServiceUtil.returnError(errMsg);
599                 }
600             }
601             counter++;
602         }
603         // ----------
604

605         // ----------
606
// The status of the requirement associated to the shopping cart lines is set to "ordered".
607
//
608
Iterator JavaDoc shoppingCartItems = this.cart.items().iterator();
609         while (shoppingCartItems.hasNext()) {
610             ShoppingCartItem shoppingCartItem = (ShoppingCartItem)shoppingCartItems.next();
611             String JavaDoc requirementId = shoppingCartItem.getRequirementId();
612             if (requirementId != null) {
613                 try {
614                     Map JavaDoc inputMap = UtilMisc.toMap("requirementId", requirementId, "statusId", "REQ_ORDERED");
615                     inputMap.put("userLogin", userLogin);
616                     // TODO: check service result for an error return
617
Map JavaDoc outMap = dispatcher.runSync("updateRequirement", inputMap);
618                 } catch (Exception JavaDoc e) {
619                     String JavaDoc service = e.getMessage();
620                     Map JavaDoc messageMap = UtilMisc.toMap("service", service);
621                     String JavaDoc errMsg = UtilProperties.getMessage(resource, "checkhelper.could_not_create_order_invoking_service", messageMap, (cart != null ? cart.getLocale() : Locale.getDefault()));
622                     Debug.logError(e, errMsg, module);
623                     return ServiceUtil.returnError(errMsg);
624                 }
625             }
626         }
627         // ----------
628

629         // set the orderId for use by chained events
630
Map JavaDoc result = ServiceUtil.returnSuccess();
631         result.put("orderId", orderId);
632         result.put("orderAdditionalEmails", this.cart.getOrderAdditionalEmails());
633
634         // save the emails to the order
635
List JavaDoc toBeStored = new LinkedList JavaDoc();
636
637         GenericValue party = null;
638         try {
639             party = this.delegator.findByPrimaryKey("Party", UtilMisc.toMap("partyId", partyId));
640         } catch (GenericEntityException e) {
641             Debug.logWarning(e, UtilProperties.getMessage(resource_error,"OrderProblemsGettingPartyRecord", cart.getLocale()), module);
642             party = null;
643         }
644
645         // create order contact mechs for the email address(s)
646
if (party != null) {
647             Iterator JavaDoc emailIter = UtilMisc.toIterator(ContactHelper.getContactMechByType(party, "EMAIL_ADDRESS", false));
648             while (emailIter != null && emailIter.hasNext()) {
649                 GenericValue email = (GenericValue) emailIter.next();
650                 GenericValue orderContactMech = this.delegator.makeValue("OrderContactMech",
651                         UtilMisc.toMap("orderId", orderId, "contactMechId", email.getString("contactMechId"), "contactMechPurposeTypeId", "ORDER_EMAIL"));
652                 toBeStored.add(orderContactMech);
653             }
654         }
655
656         // create dummy contact mechs and order contact mechs for the additional emails
657
String JavaDoc additionalEmails = this.cart.getOrderAdditionalEmails();
658         List JavaDoc emailList = StringUtil.split(additionalEmails, ",");
659         if (emailList == null) emailList = new ArrayList JavaDoc();
660         Iterator JavaDoc eli = emailList.iterator();
661         while (eli.hasNext()) {
662             String JavaDoc email = (String JavaDoc) eli.next();
663             String JavaDoc contactMechId = this.delegator.getNextSeqId("ContactMech").toString();
664             GenericValue contactMech = this.delegator.makeValue("ContactMech",
665                     UtilMisc.toMap("contactMechId", contactMechId, "contactMechTypeId", "EMAIL_ADDRESS", "infoString", email));
666
667             GenericValue orderContactMech = this.delegator.makeValue("OrderContactMech",
668                     UtilMisc.toMap("orderId", orderId, "contactMechId", contactMechId, "contactMechPurposeTypeId", "ORDER_EMAIL"));
669             toBeStored.add(contactMech);
670             toBeStored.add(orderContactMech);
671         }
672
673         if (toBeStored.size() > 0) {
674             try {
675                 if (Debug.verboseOn()) Debug.logVerbose("To Be Stored: " + toBeStored, module);
676                 this.delegator.storeAll(toBeStored);
677             } catch (GenericEntityException e) {
678                 // not a fatal error; so just print a message
679
Debug.logWarning(e, UtilProperties.getMessage(resource_error,"OrderProblemsStoringOrderEmailContactInformation", cart.getLocale()), module);
680             }
681         }
682
683         return result;
684     }
685
686     public void calcAndAddTax() throws GeneralException {
687         calcAndAddTax(null);
688     }
689
690     public void calcAndAddTax(GenericValue shipAddress) throws GeneralException {
691         if (!"SALES_ORDER".equals(cart.getOrderType())) {
692             return;
693         }
694
695         int shipGroups = this.cart.getShipGroupSize();
696         for (int i = 0; i < shipGroups; i++) {
697             Map JavaDoc serviceContext = this.makeTaxContext(i, shipAddress);
698             // pass in BigDecimal values instead of Double
699
List JavaDoc taxReturn = this.getTaxAdjustments(dispatcher, "calcTax", serviceContext);
700
701             if (Debug.verboseOn()) Debug.logVerbose("ReturnList: " + taxReturn, module);
702             ShoppingCart.CartShipInfo csi = cart.getShipInfo(i);
703             List JavaDoc orderAdj = (List JavaDoc) taxReturn.get(0);
704             List JavaDoc itemAdj = (List JavaDoc) taxReturn.get(1);
705
706             // set the item adjustments
707
if (itemAdj != null) {
708                 for (int x = 0; x < itemAdj.size(); x++) {
709                     List JavaDoc adjs = (List JavaDoc) itemAdj.get(x);
710                     ShoppingCartItem item = (ShoppingCartItem) csi.shipItemInfo.get(x);
711                     csi.setItemInfo(item, adjs);
712                     Debug.log("Added item adjustments to ship group [" + i + " / " + x + "] - " + adjs, module);
713                 }
714             }
715
716             // need to manually clear the order adjustments
717
csi.shipTaxAdj.clear();
718             csi.shipTaxAdj.addAll(orderAdj);
719         }
720     }
721
722     private Map JavaDoc makeTaxContext(int shipGroup, GenericValue shipAddress) throws GeneralException {
723         String JavaDoc productStoreId = cart.getProductStoreId();
724         String JavaDoc billToPartyId = cart.getBillToCustomerPartyId();
725         ShoppingCart.CartShipInfo csi = cart.getShipInfo(shipGroup);
726         int totalItems = csi.shipItemInfo.size();
727
728         List JavaDoc product = new ArrayList JavaDoc(totalItems);
729         List JavaDoc amount = new ArrayList JavaDoc(totalItems);
730         List JavaDoc price = new ArrayList JavaDoc(totalItems);
731         List JavaDoc shipAmt = new ArrayList JavaDoc(totalItems);
732
733         for (int i = 0; i < totalItems; i++) {
734             ShoppingCartItem cartItem = (ShoppingCartItem) csi.shipItemInfo.get(i);
735             ShoppingCart.CartShipInfo.CartShipItemInfo itemInfo = csi.getShipItemInfo(cartItem);
736             
737             //Debug.logInfo("In makeTaxContext for item [" + i + "] in ship group [" + shipGroup + "] got cartItem: " + cartItem, module);
738
//Debug.logInfo("In makeTaxContext for item [" + i + "] in ship group [" + shipGroup + "] got itemInfo: " + itemInfo, module);
739

740             product.add(i, cartItem.getProduct());
741             amount.add(i, new BigDecimal JavaDoc(cartItem.getItemSubTotal(itemInfo.quantity)));
742             price.add(i, new BigDecimal JavaDoc(cartItem.getBasePrice()));
743             shipAmt.add(i, new BigDecimal JavaDoc("0.00")); // no per item shipping yet
744
}
745
746         BigDecimal JavaDoc shipAmount = new BigDecimal JavaDoc(csi.shipEstimate);
747         if (shipAddress == null) {
748             shipAddress = cart.getShippingAddress(shipGroup);
749         }
750
751         // no shipping address; try the billing address
752
if (shipAddress == null) {
753             for (int i = 0; i < cart.selectedPayments(); i++) {
754                 ShoppingCart.CartPaymentInfo cpi = cart.getPaymentInfo(i);
755                 GenericValue billAddr = cpi.getBillingAddress(delegator);
756                 if (billAddr != null) {
757                     shipAddress = billAddr;
758                     Debug.logInfo("Found address from payment method.", module);
759                 }
760                 break;
761             }
762         }
763
764         Map JavaDoc serviceContext = UtilMisc.toMap("productStoreId", productStoreId);
765         serviceContext.put("billToPartyId", billToPartyId);
766         serviceContext.put("itemProductList", product);
767         serviceContext.put("itemAmountList", amount);
768         serviceContext.put("itemPriceList", price);
769         serviceContext.put("itemShippingList", shipAmt);
770         serviceContext.put("orderShippingAmount", shipAmount);
771         serviceContext.put("shippingAddress", shipAddress);
772
773         return serviceContext;
774     }
775
776     // Calc the tax adjustments.
777
private List JavaDoc getTaxAdjustments(LocalDispatcher dispatcher, String JavaDoc taxService, Map JavaDoc serviceContext) throws GeneralException {
778         Map JavaDoc serviceResult = null;
779
780         try {
781             serviceResult = dispatcher.runSync(taxService, serviceContext);
782         } catch (GenericServiceException e) {
783             Debug.logError(e, module);
784             throw new GeneralException("Problem occurred in tax service (" + e.getMessage() + ")", e);
785         }
786
787         if (ServiceUtil.isError(serviceResult)) {
788             throw new GeneralException(ServiceUtil.getErrorMessage(serviceResult));
789         }
790
791         // the adjustments (returned in order) from taxware.
792
List JavaDoc orderAdj = (List JavaDoc) serviceResult.get("orderAdjustments");
793         List JavaDoc itemAdj = (List JavaDoc) serviceResult.get("itemAdjustments");
794
795         return UtilMisc.toList(orderAdj, itemAdj);
796     }
797
798     public Map JavaDoc processPayment(GenericValue productStore, GenericValue userLogin) throws GeneralException {
799         return processPayment(productStore, userLogin, false, false);
800     }
801
802     public Map JavaDoc processPayment(GenericValue productStore, GenericValue userLogin, boolean faceToFace) throws GeneralException {
803         return processPayment(productStore, userLogin, faceToFace, false);
804     }
805
806     public Map JavaDoc processPayment(GenericValue productStore, GenericValue userLogin, boolean faceToFace, boolean manualHold) throws GeneralException {
807         // Get some payment related strings
808
String JavaDoc DECLINE_MESSAGE = productStore.getString("authDeclinedMessage");
809         String JavaDoc ERROR_MESSAGE = productStore.getString("authErrorMessage");
810         String JavaDoc RETRY_ON_ERROR = productStore.getString("retryFailedAuths");
811         if (RETRY_ON_ERROR == null) {
812             RETRY_ON_ERROR = "Y";
813         }
814
815         // Get the orderId/total from the cart.
816
double orderTotal = this.cart.getGrandTotal();
817         String JavaDoc orderId = this.cart.getOrderId();
818
819         // Get the paymentMethodTypeIds - this will need to change when ecom supports multiple payments
820
List JavaDoc paymentMethodTypeIds = this.cart.getPaymentMethodTypeIds();
821
822         // Check the payment preferences; if we have ANY w/ status PAYMENT_NOT_AUTH invoke payment service.
823
boolean requireAuth = false;
824         List JavaDoc allPaymentPreferences = null;
825         try {
826             allPaymentPreferences = this.delegator.findByAnd("OrderPaymentPreference", UtilMisc.toMap("orderId", orderId));
827         } catch (GenericEntityException e) {
828             throw new GeneralException("Problems getting payment preferences", e);
829         }
830
831         // filter out cancelled preferences
832
List JavaDoc canExpr = UtilMisc.toList(new EntityExpr("statusId", EntityOperator.NOT_EQUAL, "PAYMENT_CANCELLED"));
833         allPaymentPreferences = EntityUtil.filterByAnd(allPaymentPreferences, canExpr);
834
835         // check for online payment methods or in-hand payment types with verbal or external refs
836
List JavaDoc exprs = UtilMisc.toList(new EntityExpr("manualRefNum", EntityOperator.NOT_EQUAL, null));
837         List JavaDoc manualRefPaymentPrefs = EntityUtil.filterByAnd(allPaymentPreferences, exprs);
838         if (manualRefPaymentPrefs != null && manualRefPaymentPrefs.size() > 0) {
839             Iterator JavaDoc i = manualRefPaymentPrefs.iterator();
840             while (i.hasNext()) {
841                 GenericValue opp = (GenericValue) i.next();
842                 Map JavaDoc authCtx = new HashMap JavaDoc();
843                 authCtx.put("orderPaymentPreference", opp);
844                 if (opp.get("paymentMethodId") == null) {
845                     authCtx.put("serviceTypeEnum", "PRDS_PAY_EXTERNAL");
846                 }
847                 authCtx.put("processAmount", opp.getDouble("maxAmount"));
848                 authCtx.put("authRefNum", opp.getString("manualRefNum"));
849                 authCtx.put("authResult", Boolean.TRUE);
850                 authCtx.put("userLogin", userLogin);
851                 authCtx.put("currencyUomId", cart.getCurrency());
852
853                 Map JavaDoc authResp = dispatcher.runSync("processAuthResult", authCtx);
854                 if (authResp != null && ServiceUtil.isError(authResp)) {
855                     throw new GeneralException(ServiceUtil.getErrorMessage(authResp));
856                 }
857
858                 // approve the order
859
OrderChangeHelper.approveOrder(dispatcher, userLogin, orderId, manualHold);
860
861                 if ("Y".equalsIgnoreCase(productStore.getString("manualAuthIsCapture"))) {
862                     Map JavaDoc captCtx = new HashMap JavaDoc();
863                     captCtx.put("orderPaymentPreference", opp);
864                     if (opp.get("paymentMethodId") == null) {
865                         captCtx.put("serviceTypeEnum", "PRDS_PAY_EXTERNAL");
866                     }
867                     captCtx.put("payToPartyId", productStore.get("payToPartyId"));
868                     captCtx.put("captureResult", Boolean.TRUE);
869                     captCtx.put("captureAmount", opp.getDouble("maxAmount"));
870                     captCtx.put("captureRefNum", opp.getString("manualRefNum"));
871                     captCtx.put("userLogin", userLogin);
872                     captCtx.put("currencyUomId", cart.getCurrency());
873
874                     Map JavaDoc capResp = dispatcher.runSync("processCaptureResult", captCtx);
875                     if (capResp != null && ServiceUtil.isError(capResp)) {
876                         throw new GeneralException(ServiceUtil.getErrorMessage(capResp));
877                     }
878                 }
879             }
880         }
881
882         // check for online payment methods needing authorization
883
Map JavaDoc paymentFields = UtilMisc.toMap("statusId", "PAYMENT_NOT_AUTH");
884         List JavaDoc onlinePaymentPrefs = EntityUtil.filterByAnd(allPaymentPreferences, paymentFields);
885
886         if (onlinePaymentPrefs != null && onlinePaymentPrefs.size() > 0) {
887             requireAuth = true;
888         }
889
890         // Invoke payment processing.
891
if (requireAuth) {
892             if (orderTotal == 0) {
893                 // if there is nothing to authorize; don't bother
894
boolean ok = OrderChangeHelper.approveOrder(dispatcher, userLogin, orderId, manualHold);
895                 if (!ok) {
896                     throw new GeneralException("Problem with order change; see above error");
897                 }
898             }
899
900             // now there should be something to authorize; go ahead
901
Map JavaDoc paymentResult = null;
902             try {
903                 // invoke the payment gateway service.
904
paymentResult = dispatcher.runSync("authOrderPayments",
905                         UtilMisc.toMap("orderId", orderId, "userLogin", userLogin), 180, true);
906             } catch (GenericServiceException e) {
907                 Debug.logWarning(e, module);
908                 throw new GeneralException("Error in authOrderPayments service: " + e.toString(), e.getNested());
909             }
910             if (Debug.verboseOn()) Debug.logVerbose("Finsished w/ Payment Service", module);
911
912             if (paymentResult != null && ServiceUtil.isError(paymentResult)) {
913                 throw new GeneralException(ServiceUtil.getErrorMessage(paymentResult));
914             }
915
916             // grab the customer messages -- only passed back in the case of an error or failure
917
List JavaDoc messages = (List JavaDoc) paymentResult.get("authResultMsgs");
918
919             if (paymentResult != null && paymentResult.containsKey("processResult")) {
920                 String JavaDoc authResp = (String JavaDoc) paymentResult.get("processResult");
921
922                 if (authResp.equals("FAILED")) {
923                     // order was NOT approved
924
if (Debug.verboseOn()) Debug.logVerbose("Payment auth was NOT a success!", module);
925
926                     boolean ok = OrderChangeHelper.rejectOrder(dispatcher, userLogin, orderId);
927                     if (!ok) {
928                         throw new GeneralException("Problem with order change; see above error");
929                     }
930
931                     // null out the orderId for next pass.
932
cart.setOrderId(null);
933                     if (messages == null || messages.size() == 0) {
934                         return ServiceUtil.returnError(DECLINE_MESSAGE);
935                     } else {
936                         return ServiceUtil.returnError(messages);
937                     }
938                 } else if (authResp.equals("APPROVED")) {
939                     // order WAS approved
940
if (Debug.verboseOn()) Debug.logVerbose("Payment auth was a success!", module);
941
942                     // set the order and item status to approved
943
boolean ok = OrderChangeHelper.approveOrder(dispatcher, userLogin, orderId, manualHold);
944                     if (!ok) {
945                         throw new GeneralException("Problem with order change; see above error");
946                     }
947                 } else if (authResp.equals("ERROR")) {
948                     // service failed
949
if (Debug.verboseOn()) Debug.logVerbose("Payment auth failed due to processor trouble.", module);
950                     if (!faceToFace && "Y".equalsIgnoreCase(RETRY_ON_ERROR)) {
951                         // never do this for a face to face purchase regardless of store setting
952
return ServiceUtil.returnSuccess(ERROR_MESSAGE);
953                     } else {
954                         boolean ok = OrderChangeHelper.cancelOrder(dispatcher, userLogin, orderId);
955                         if (!ok) {
956                             throw new GeneralException("Problem with order change; see above error");
957                         }
958                         // null out orderId for next pass
959
this.cart.setOrderId(null);
960                         if (messages == null || messages.size() == 0) {
961                             return ServiceUtil.returnError(ERROR_MESSAGE);
962                         } else {
963                             return ServiceUtil.returnError(messages);
964                         }
965                     }
966                 } else {
967                     // should never happen
968
return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderPleaseContactCustomerService;PaymentReturnCodeUnknown.", (cart != null ? cart.getLocale() : Locale.getDefault())));
969                 }
970             } else {
971                 // result returned null == service failed
972
if (Debug.verboseOn()) Debug.logVerbose("Payment auth failed due to processor trouble.", module);
973                 if (!faceToFace && "Y".equalsIgnoreCase(RETRY_ON_ERROR)) {
974                     // never do this for a face to face purchase regardless of store setting
975
return ServiceUtil.returnSuccess(ERROR_MESSAGE);
976                 } else {
977                     boolean ok = OrderChangeHelper.cancelOrder(dispatcher, userLogin, orderId);
978                     if (!ok) {
979                         throw new GeneralException("Problem with order change; see above error");
980                     }
981                     // null out orderId for next pass
982
this.cart.setOrderId(null);
983                     return ServiceUtil.returnError(ERROR_MESSAGE);
984                 }
985             }
986         } else if (paymentMethodTypeIds.contains("CASH") || paymentMethodTypeIds.contains("EXT_COD") || paymentMethodTypeIds.contains("EXT_BILLACT")) {
987             boolean hasOther = false;
988             // TODO: this is set but not checked anywhere
989
boolean validAmount = false;
990
991             Iterator JavaDoc pmti = paymentMethodTypeIds.iterator();
992             while (pmti.hasNext()) {
993                 String JavaDoc type = (String JavaDoc) pmti.next();
994                 if (!"CASH".equals(type) && !"EXT_COD".equals(type) && !"EXT_BILLACT".equals(type)) {
995                     hasOther = true;
996                     break;
997                 }
998             }
999
1000            if (!hasOther) {
1001                if (!paymentMethodTypeIds.contains("CASH") && !paymentMethodTypeIds.contains("EXT_COD")) {
1002                    // only billing account, make sure we have enough to cover
1003
String JavaDoc billingAccountId = cart.getBillingAccountId();
1004                    double billAcctCredit = this.availableAccountBalance(billingAccountId);
1005                    double billingAcctAmt = cart.getBillingAccountAmount();
1006                    if (billAcctCredit >= billingAcctAmt) {
1007                        if (cart.getGrandTotal() > billAcctCredit) {
1008                            validAmount = false;
1009                        } else {
1010                            validAmount = true;
1011                        }
1012                    }
1013                }
1014
1015                // approve this as long as there are only COD and Billing Account types
1016
boolean ok = OrderChangeHelper.approveOrder(dispatcher, userLogin, orderId, manualHold);
1017                if (!ok) {
1018                    throw new GeneralException("Problem with order change; see above error");
1019                }
1020            }
1021        } else {
1022            // There is nothing to do, we just treat this as a success
1023
}
1024
1025        // check to see if we should auto-invoice/bill
1026
if (faceToFace) {
1027            Debug.log("Face-To-Face Sale - " + orderId, module);
1028            this.adjustFaceToFacePayment(allPaymentPreferences, userLogin);
1029            boolean ok = OrderChangeHelper.completeOrder(dispatcher, userLogin, orderId);
1030            Debug.log("Complete Order Result - " + ok, module);
1031            if (!ok) {
1032                throw new GeneralException("Problem with order change; see error logs");
1033            }
1034        }
1035        return ServiceUtil.returnSuccess();
1036    }
1037
1038    public void adjustFaceToFacePayment(List JavaDoc allPaymentPrefs, GenericValue userLogin) throws GeneralException {
1039        String JavaDoc currencyFormat = UtilProperties.getPropertyValue("general.properties", "currency.decimal.format", "##0.00");
1040        DecimalFormat JavaDoc formatter = new DecimalFormat JavaDoc(currencyFormat);
1041
1042        double cartTotal = this.cart.getGrandTotal();
1043        String JavaDoc grandTotalString = formatter.format(cartTotal);
1044        Double JavaDoc grandTotal = null;
1045        try {
1046            grandTotal = new Double JavaDoc(formatter.parse(grandTotalString).doubleValue());
1047        } catch (ParseException JavaDoc e) {
1048            throw new GeneralException("Problem getting parsed currency amount from DecimalFormat", e);
1049        }
1050
1051        double prefTotal = 0.00;
1052        if (allPaymentPrefs != null) {
1053            Iterator JavaDoc i = allPaymentPrefs.iterator();
1054            while (i.hasNext()) {
1055                GenericValue pref = (GenericValue) i.next();
1056                Double JavaDoc maxAmount = pref.getDouble("maxAmount");
1057                if (maxAmount == null) maxAmount = new Double JavaDoc(0.00);
1058                prefTotal += maxAmount.doubleValue();
1059            }
1060        }
1061
1062        String JavaDoc payTotalString = formatter.format(prefTotal);
1063        Double JavaDoc payTotal = null;
1064        try {
1065            payTotal = new Double JavaDoc(formatter.parse(payTotalString).doubleValue());
1066        } catch (ParseException JavaDoc e) {
1067            throw new GeneralException("Problem getting parsed currency amount from DecimalFormat", e);
1068        }
1069
1070        if (grandTotal == null) grandTotal = new Double JavaDoc(0.00);
1071        if (payTotal == null) payTotal = new Double JavaDoc(0.00);
1072
1073        if (payTotal.doubleValue() > grandTotal.doubleValue()) {
1074            double diff = (payTotal.doubleValue() - grandTotal.doubleValue()) * -1;
1075            String JavaDoc diffString = formatter.format(diff);
1076            Double JavaDoc change = null;
1077            try {
1078                change = new Double JavaDoc(formatter.parse(diffString).doubleValue());
1079            } catch (ParseException JavaDoc e) {
1080                throw new GeneralException("Problem getting parsed currency amount from DecimalFormat", e);
1081            }
1082            GenericValue newPref = delegator.makeValue("OrderPaymentPreference", null);
1083            newPref.set("orderPaymentPreferenceId", delegator.getNextSeqId("OrderPaymentPreference"));
1084            newPref.set("orderId", cart.getOrderId());
1085            newPref.set("paymentMethodTypeId", "CASH");
1086            newPref.set("statusId", "PAYMENT_RECEIVED");
1087            newPref.set("maxAmount", change);
1088            newPref.set("createdDate", UtilDateTime.nowTimestamp());
1089            if (userLogin != null) {
1090                newPref.set("createdByUserLogin", userLogin.getString("userLoginId"));
1091            }
1092            delegator.create(newPref);
1093        }
1094    }
1095
1096    public Map JavaDoc checkOrderBlacklist(GenericValue userLogin) {
1097        if (cart == null) {
1098            return ServiceUtil.returnSuccess("success");
1099        }
1100        GenericValue shippingAddressObj = this.cart.getShippingAddress();
1101        if (shippingAddressObj == null) {
1102            return ServiceUtil.returnSuccess("success");
1103        }
1104        String JavaDoc shippingAddress = UtilFormatOut.checkNull(shippingAddressObj.getString("address1")).toUpperCase();
1105        List JavaDoc exprs = UtilMisc.toList(new EntityExpr(
1106                new EntityExpr(new EntityFunction.UPPER(new EntityFieldValue("blacklistString")), EntityOperator.EQUALS, new EntityFunction.UPPER(shippingAddress)), EntityOperator.AND,
1107                new EntityExpr("orderBlacklistTypeId", EntityOperator.EQUALS, "BLACKLIST_ADDRESS")));
1108        String JavaDoc errMsg=null;
1109
1110        List JavaDoc paymentMethods = this.cart.getPaymentMethods();
1111        Iterator JavaDoc i = paymentMethods.iterator();
1112        while (i.hasNext()) {
1113            GenericValue paymentMethod = (GenericValue) i.next();
1114            if ((paymentMethod != null) && ("CREDIT_CARD".equals(paymentMethod.getString("paymentMethodTypeId")))) {
1115                GenericValue creditCard = null;
1116                GenericValue billingAddress = null;
1117                try {
1118                    creditCard = paymentMethod.getRelatedOne("CreditCard");
1119                    if (creditCard != null)
1120                        billingAddress = creditCard.getRelatedOne("PostalAddress");
1121                } catch (GenericEntityException e) {
1122                    Debug.logError(e, "Problems getting credit card from payment method", module);
1123                    errMsg = UtilProperties.getMessage(resource,"checkhelper.problems_reading_database", (cart != null ? cart.getLocale() : Locale.getDefault()));
1124                    return ServiceUtil.returnError(errMsg);
1125                }
1126                if (creditCard != null) {
1127                    String JavaDoc creditCardNumber = UtilFormatOut.checkNull(creditCard.getString("cardNumber"));
1128                    exprs.add(new EntityExpr(
1129                            new EntityExpr("blacklistString", EntityOperator.EQUALS, creditCardNumber), EntityOperator.AND,
1130                            new EntityExpr("orderBlacklistTypeId", EntityOperator.EQUALS, "BLACKLIST_CREDITCARD")));
1131                }
1132                if (billingAddress != null) {
1133                    String JavaDoc address = UtilFormatOut.checkNull(billingAddress.getString("address1").toUpperCase());
1134                    exprs.add(new EntityExpr(
1135                            new EntityExpr(new EntityFunction.UPPER(new EntityFieldValue("blacklistString")), EntityOperator.EQUALS, new EntityFunction.UPPER(address)), EntityOperator.AND,
1136                            new EntityExpr("orderBlacklistTypeId", EntityOperator.EQUALS, "BLACKLIST_ADDRESS")));
1137                }
1138            }
1139        }
1140
1141        List JavaDoc blacklistFound = null;
1142        if (exprs.size() > 0) {
1143            try {
1144                blacklistFound = this.delegator.findByOr("OrderBlacklist", exprs);
1145            } catch (GenericEntityException e) {
1146                Debug.logError(e, "Problems with OrderBlacklist lookup.", module);
1147                errMsg = UtilProperties.getMessage(resource,"checkhelper.problems_reading_database", (cart != null ? cart.getLocale() : Locale.getDefault()));
1148                return ServiceUtil.returnError(errMsg);
1149            }
1150        }
1151
1152        if (blacklistFound != null && blacklistFound.size() > 0) {
1153            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderFailed", (cart != null ? cart.getLocale() : Locale.getDefault())));
1154        } else {
1155            return ServiceUtil.returnSuccess("success");
1156        }
1157    }
1158
1159    public Map JavaDoc failedBlacklistCheck(GenericValue userLogin, GenericValue productStore) {
1160        Map JavaDoc result;
1161        String JavaDoc errMsg=null;
1162
1163        String JavaDoc REJECT_MESSAGE = productStore.getString("authFraudMessage");
1164
1165        // Get the orderId from the cart.
1166
String JavaDoc orderId = this.cart.getOrderId();
1167
1168        // set the order/item status - reverse inv
1169
OrderChangeHelper.rejectOrder(dispatcher, userLogin, orderId);
1170
1171        // nuke the userlogin
1172
userLogin.set("enabled", "N");
1173        try {
1174            userLogin.store();
1175        } catch (GenericEntityException e) {
1176            Debug.logError(e, "Problems de-activating userLogin.", module);
1177            errMsg = UtilProperties.getMessage(resource,"checkhelper.database_error", (cart != null ? cart.getLocale() : Locale.getDefault()));
1178            result = ServiceUtil.returnError(errMsg);
1179            return result;
1180        }
1181        result = ServiceUtil.returnSuccess();
1182        result.put(ModelService.ERROR_MESSAGE, REJECT_MESSAGE);
1183
1184        // wipe the cart and session
1185
this.cart.clear();
1186        return result;
1187    }
1188
1189    public Map JavaDoc checkExternalPayment(String JavaDoc orderId) {
1190        Map JavaDoc result;
1191        String JavaDoc errMsg=null;
1192        // warning there can only be ONE payment preference for this to work
1193
// you cannot accept multiple payment type when using an external gateway
1194
GenericValue orderHeader = null;
1195        try {
1196            orderHeader = this.delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId));
1197        } catch (GenericEntityException e) {
1198            Debug.logError(e, "Problems getting order header", module);
1199            errMsg = UtilProperties.getMessage(resource,"checkhelper.problems_getting_order_header", (cart != null ? cart.getLocale() : Locale.getDefault()));
1200            result = ServiceUtil.returnError(errMsg);
1201            return result;
1202        }
1203        if (orderHeader != null) {
1204            List JavaDoc paymentPrefs = null;
1205            try {
1206                paymentPrefs = orderHeader.getRelated("OrderPaymentPreference");
1207            } catch (GenericEntityException e) {
1208                Debug.logError(e, "Problems getting order payments", module);
1209                errMsg = UtilProperties.getMessage(resource,"checkhelper.problems_getting_payment_preference", (cart != null ? cart.getLocale() : Locale.getDefault()));
1210                result = ServiceUtil.returnError(errMsg);
1211                return result;
1212            }
1213            if (paymentPrefs != null && paymentPrefs.size() > 0) {
1214                if (paymentPrefs.size() > 1) {
1215                    Debug.logError("Too many payment preferences, you cannot have more then one when using external gateways", module);
1216                }
1217                GenericValue paymentPreference = EntityUtil.getFirst(paymentPrefs);
1218                String JavaDoc paymentMethodTypeId = paymentPreference.getString("paymentMethodTypeId");
1219                if (paymentMethodTypeId.startsWith("EXT_")) {
1220                    String JavaDoc type = paymentMethodTypeId.substring(4);
1221                    result = ServiceUtil.returnSuccess();
1222                    result.put("type", type.toLowerCase());
1223                    return result;
1224                }
1225            }
1226            result = ServiceUtil.returnSuccess();
1227            result.put("type", "none");
1228            return result;
1229        } else {
1230            errMsg = UtilProperties.getMessage(resource,"checkhelper.problems_getting_order_header", (cart != null ? cart.getLocale() : Locale.getDefault()));
1231            result = ServiceUtil.returnError(errMsg);
1232            result.put("type", "error");
1233            return result;
1234        }
1235    }
1236
1237    /**
1238     * Sets the shipping contact mechanism on the cart
1239     *
1240     * @param shippingContactMechId The identifier of the contact
1241     * @return A Map conforming to the OFBiz Service conventions containing
1242     * any error messages
1243     */

1244    public Map JavaDoc finalizeOrderEntryShip(String JavaDoc shippingContactMechId) {
1245        Map JavaDoc result;
1246        String JavaDoc errMsg=null;
1247        //Verify the field is valid
1248
if (UtilValidate.isNotEmpty(shippingContactMechId)) {
1249            this.cart.setShippingContactMechId(shippingContactMechId);
1250            result = ServiceUtil.returnSuccess();
1251        } else {
1252            errMsg = UtilProperties.getMessage(resource,"checkhelper.enter_shipping_address", (cart != null ? cart.getLocale() : Locale.getDefault()));
1253            result = ServiceUtil.returnError(errMsg);
1254        }
1255
1256        return result;
1257    }
1258
1259    /**
1260     * Sets the options associated with the order
1261     *
1262     * @param shippingMethod The shipping method indicating the carrier and
1263     * shipment type to use
1264     * @param shippingInstructions Any additional handling instructions
1265     * @param maySplit "true" or anything else for <code>false</code>
1266     * @param giftMessage A message to have included for the recipient
1267     * @param isGift "true" or anything else for <code>false</code>
1268     * @param internalCode an internal code associated with the order
1269     * @return A Map conforming to the OFBiz Service conventions containing
1270     * any error messages
1271     */

1272    public Map JavaDoc finalizeOrderEntryOptions(String JavaDoc shippingMethod, String JavaDoc shippingInstructions, String JavaDoc maySplit,
1273            String JavaDoc giftMessage, String JavaDoc isGift, String JavaDoc internalCode, String JavaDoc shipBeforeDate, String JavaDoc shipAfterDate) {
1274
1275        Map JavaDoc result;
1276        String JavaDoc errMsg=null;
1277        //Verify the shipping method is valid
1278
if (UtilValidate.isNotEmpty(shippingMethod)) {
1279            int delimiterPos = shippingMethod.indexOf('@');
1280            String JavaDoc shipmentMethodTypeId = null;
1281            String JavaDoc carrierPartyId = null;
1282
1283            if (delimiterPos > 0) {
1284                shipmentMethodTypeId = shippingMethod.substring(0, delimiterPos);
1285                carrierPartyId = shippingMethod.substring(delimiterPos + 1);
1286            }
1287
1288            this.cart.setShipmentMethodTypeId(shipmentMethodTypeId);
1289            this.cart.setCarrierPartyId(carrierPartyId);
1290        } else {
1291            errMsg = UtilProperties.getMessage(resource,"checkhelper.select_shipping_method", (cart != null ? cart.getLocale() : Locale.getDefault()));
1292            result = ServiceUtil.returnError(errMsg);
1293        }
1294
1295        //Set the remaining order options
1296
this.cart.setShippingInstructions(shippingInstructions);
1297        this.cart.setGiftMessage(giftMessage);
1298        this.cart.setMaySplit(Boolean.valueOf(maySplit));
1299        this.cart.setIsGift(Boolean.valueOf(isGift));
1300        this.cart.setInternalCode(internalCode);
1301
1302        // set ship before date
1303
if ((shipBeforeDate != null) && (shipBeforeDate.length() > 8)) {
1304           shipBeforeDate = shipBeforeDate.trim();
1305           if (shipBeforeDate.length() < 14) {
1306               shipBeforeDate = shipBeforeDate + " " + "00:00:00.000";
1307           }
1308
1309           try {
1310               this.cart.setShipBeforeDate((Timestamp JavaDoc) ObjectType.simpleTypeConvert(shipBeforeDate, "Timestamp", null, null));
1311           } catch (Exception JavaDoc e) {
1312               errMsg = "Ship Before Date must be a valid date formed ";
1313               result = ServiceUtil.returnError(errMsg);
1314           }
1315        }
1316
1317        // set ship after date
1318
if ((shipAfterDate != null) && (shipAfterDate.length() > 8)) {
1319           shipAfterDate = shipAfterDate.trim();
1320           if (shipAfterDate.length() < 14) {
1321               shipAfterDate = shipAfterDate + " " + "00:00:00.000";
1322           }
1323
1324           try {
1325               this.cart.setShipAfterDate((Timestamp JavaDoc) ObjectType.simpleTypeConvert(shipAfterDate,"Timestamp", null, null));
1326            } catch (Exception JavaDoc e) {
1327              errMsg = "Ship After Date must be a valid date formed ";
1328              result = ServiceUtil.returnError(errMsg);
1329            }
1330        }
1331
1332        result = ServiceUtil.returnSuccess();
1333        return result;
1334    }
1335
1336    /**
1337     * Sets the payment ID to use during the checkout process
1338     *
1339     * @param checkOutPaymentId The payment ID to be associated with the cart
1340     * @return A Map conforming to the OFBiz Service conventions containing
1341     * any error messages.
1342     */

1343    public Map JavaDoc finalizeOrderEntryPayment(String JavaDoc checkOutPaymentId, Double JavaDoc amount, boolean singleUse, boolean append) {
1344        Map JavaDoc result = ServiceUtil.returnSuccess();
1345
1346        if (UtilValidate.isNotEmpty(checkOutPaymentId)) {
1347            if (!append) {
1348                cart.clearPayments();
1349            }
1350            cart.addPaymentAmount(checkOutPaymentId, amount, singleUse);
1351        }
1352
1353        return result;
1354    }
1355    
1356    /**
1357     * Performs all the finalization settings and combines all the results.
1358     * This is a convenience method, primarily to match the original
1359     * code structure of the adapter class <code>CheckOutEvents</code>.
1360     * <p>
1361     * I would prefer to remove this altogether and move the method
1362     * {@link #addErrors(List, Map, Map) addErrors} to the utility
1363     * class {@link ServiceUtil ServiceUtil}
1364     *
1365     * @see CheckOutHelper#finalizeOrderEntryOptions(String, String, String, String, String, String, String, String)
1366     * @see CheckOutHelper#finalizeOrderEntryPayment(String, Double, boolean, boolean)
1367     * @see CheckOutHelper#finalizeOrderEntryShip(String)
1368     */

1369    public Map JavaDoc finalizeOrderEntry(String JavaDoc finalizeMode, String JavaDoc shippingContactMechId, String JavaDoc shippingMethod,
1370            String JavaDoc shippingInstructions, String JavaDoc maySplit, String JavaDoc giftMessage, String JavaDoc isGift, String JavaDoc methodType,
1371            String JavaDoc checkOutPaymentId, boolean isSingleUsePayment, boolean appendPayment, Map JavaDoc params,
1372            String JavaDoc internalCode, String JavaDoc shipBeforeDate, String JavaDoc shipAfterDate) {
1373
1374        Map JavaDoc result = ServiceUtil.returnSuccess();
1375        Map JavaDoc errorMaps = new HashMap JavaDoc();
1376        Map JavaDoc callResult;
1377        List JavaDoc errorMessages = new ArrayList JavaDoc();
1378
1379        // set the shipping method
1380
if (finalizeMode != null && finalizeMode.equals("ship")) {
1381            callResult = this.finalizeOrderEntryShip(shippingContactMechId);
1382            this.addErrors(errorMessages, errorMaps, callResult);
1383        }
1384
1385        // set the options
1386
if (finalizeMode != null && finalizeMode.equals("options")) {
1387            callResult = this.finalizeOrderEntryOptions(shippingMethod, shippingInstructions, maySplit, giftMessage, isGift, internalCode, shipBeforeDate, shipAfterDate);
1388            this.addErrors(errorMessages, errorMaps, callResult);
1389        }
1390
1391        // set the payment
1392
if (finalizeMode != null && finalizeMode.equals("payment")) {
1393            Map JavaDoc selectedPaymentMethods = null;
1394            if (checkOutPaymentId != null) {
1395                callResult = this.finalizeOrderEntryPayment(checkOutPaymentId, null, isSingleUsePayment, appendPayment);
1396                this.addErrors(errorMessages, errorMaps, callResult);
1397                selectedPaymentMethods = UtilMisc.toMap(checkOutPaymentId, null);
1398            }
1399            callResult = checkGiftCard(params, selectedPaymentMethods);
1400            this.addErrors(errorMessages, errorMaps, callResult);
1401            if (errorMessages.size() == 0 && errorMaps.size() == 0) {
1402                String JavaDoc gcPaymentMethodId = (String JavaDoc) callResult.get("paymentMethodId");
1403                Double JavaDoc giftCardAmount = (Double JavaDoc) callResult.get("amount");
1404                Map JavaDoc gcCallRes = this.finalizeOrderEntryPayment(gcPaymentMethodId, giftCardAmount, true, true);
1405                this.addErrors(errorMessages, errorMaps, gcCallRes);
1406            }
1407        }
1408
1409        //See whether we need to return an error or not
1410
if (errorMessages.size() > 0) {
1411            result.put(ModelService.ERROR_MESSAGE_LIST, errorMessages);
1412            result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
1413        }
1414        if (errorMaps.size() > 0) {
1415            result.put(ModelService.ERROR_MESSAGE_MAP, errorMaps);
1416            result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
1417        }
1418
1419        return result;
1420    }
1421
1422    /**
1423     * Takes the result of an invocation and extracts any error messages
1424     * and adds them to the targetList. This will handle both List and String
1425     * error messags.
1426     *
1427     * @param targetList The List to add the error messages to
1428     * @param targetMap The Map to add any Map error messages to
1429     * @param callResult The result from an invocation
1430     */

1431    private void addErrors(List JavaDoc targetList, Map JavaDoc targetMap, Map JavaDoc callResult) {
1432        List JavaDoc newList;
1433        //Map.Entry entry;
1434
//Iterator mapIter;
1435
Map JavaDoc errorMsgMap;
1436        //StringBuffer outMsg;
1437

1438        //See if there is a single message
1439
if (callResult.containsKey(ModelService.ERROR_MESSAGE)) {
1440            targetList.add(callResult.get(ModelService.ERROR_MESSAGE));
1441        }
1442
1443        //See if there is a message list
1444
if (callResult.containsKey(ModelService.ERROR_MESSAGE_LIST)) {
1445            newList = (List JavaDoc) callResult.get(ModelService.ERROR_MESSAGE_LIST);
1446            targetList.addAll(newList);
1447        }
1448
1449        //See if there are an error message map
1450
if (callResult.containsKey(ModelService.ERROR_MESSAGE_MAP)) {
1451            errorMsgMap = (Map JavaDoc) callResult.get(ModelService.ERROR_MESSAGE_MAP);
1452            targetMap.putAll(errorMsgMap);
1453        }
1454    }
1455
1456    public double availableAccountBalance(String JavaDoc billingAccountId) {
1457        GenericValue billingAccount = null;
1458        Double JavaDoc availableBalance = new Double JavaDoc(0.00);
1459
1460        if (billingAccountId != null) {
1461            try {
1462                Map JavaDoc res = dispatcher.runSync("calcBillingAccountBalance", UtilMisc.toMap("billingAccountId", billingAccountId));
1463                availableBalance = (Double JavaDoc) res.get("availableBalance");
1464            } catch (GenericServiceException e) {
1465                Debug.logError(e, module);
1466            }
1467        }
1468
1469        return availableBalance.doubleValue();
1470    }
1471
1472    public Map JavaDoc makeBillingAccountMap(List JavaDoc paymentPrefs) {
1473        Map JavaDoc accountMap = new HashMap JavaDoc();
1474        if (paymentPrefs != null) {
1475            Iterator JavaDoc i = accountMap.keySet().iterator();
1476            while (i.hasNext()) {
1477                GenericValue pp = (GenericValue) i.next();
1478                if (pp.get("billingAccountId") != null) {
1479                    accountMap.put(pp.getString("billingAccountId"), pp.getDouble("maxAmount"));
1480                }
1481            }
1482        }
1483        return accountMap;
1484    }
1485
1486    public Map JavaDoc validatePaymentMethods() {
1487        String JavaDoc errMsg = null;
1488        String JavaDoc billingAccountId = cart.getBillingAccountId();
1489        double billingAccountAmt = cart.getBillingAccountAmount();
1490        double availableAmount = this.availableAccountBalance(billingAccountId);
1491        if (billingAccountAmt > availableAmount) {
1492            Map JavaDoc messageMap = UtilMisc.toMap("billingAccountId", billingAccountId);
1493            errMsg = UtilProperties.getMessage(resource, "checkevents.not_enough_available_on_account", messageMap, (cart != null ? cart.getLocale() : Locale.getDefault()));
1494            return ServiceUtil.returnError(errMsg);
1495        }
1496
1497        // payment by billing account only requires more checking
1498
List JavaDoc paymentMethods = cart.getPaymentMethodIds();
1499        List JavaDoc paymentTypes = cart.getPaymentMethodTypeIds();
1500        if (paymentTypes.contains("EXT_BILLACT") && paymentTypes.size() == 1 && paymentMethods.size() == 0) {
1501            if (cart.getGrandTotal() > availableAmount) {
1502                errMsg = UtilProperties.getMessage(resource, "checkevents.insufficient_credit_available_on_account", (cart != null ? cart.getLocale() : Locale.getDefault()));
1503                return ServiceUtil.returnError(errMsg);
1504            }
1505        }
1506
1507        // validate any gift card balances
1508
this.validateGiftCardAmounts();
1509
1510        String JavaDoc currencyFormat = UtilProperties.getPropertyValue("general.properties", "currency.decimal.format", "##0.00");
1511        DecimalFormat JavaDoc formatter = new DecimalFormat JavaDoc(currencyFormat);
1512
1513        // update the selected payment methods amount with valid numbers
1514
if (paymentMethods != null) {
1515            List JavaDoc nullPaymentIds = new ArrayList JavaDoc();
1516            Iterator JavaDoc i = paymentMethods.iterator();
1517            while (i.hasNext()) {
1518                String JavaDoc paymentMethodId = (String JavaDoc) i.next();
1519                Double JavaDoc paymentAmount = cart.getPaymentAmount(paymentMethodId);
1520                if (paymentAmount == null || paymentAmount.doubleValue() == 0) {
1521                    Debug.log("Found null paymentMethodId - " + paymentMethodId, module);
1522                    nullPaymentIds.add(paymentMethodId);
1523                }
1524            }
1525            Iterator JavaDoc npi = nullPaymentIds.iterator();
1526            while (npi.hasNext()) {
1527                String JavaDoc paymentMethodId = (String JavaDoc) npi.next();
1528                double selectedPaymentTotal = cart.getPaymentTotal();
1529                double requiredAmount = cart.getGrandTotal() - cart.getBillingAccountAmount();
1530                double nullAmount = requiredAmount - selectedPaymentTotal;
1531                boolean setOverflow = false;
1532
1533                ShoppingCart.CartPaymentInfo info = cart.getPaymentInfo(paymentMethodId);
1534                String JavaDoc amountString = formatter.format(nullAmount);
1535                double newAmount = 0;
1536                try {
1537                    newAmount = formatter.parse(amountString).doubleValue();
1538                } catch (ParseException JavaDoc e) {
1539                    Debug.logError(e, "Problem getting parsed new amount; unable to update payment info!", module);
1540                }
1541
1542                Debug.log("Remaining total is - " + newAmount, module);
1543                if (newAmount > 0) {
1544                    info.amount = new Double JavaDoc(newAmount);
1545                    Debug.log("Set null paymentMethodId - " + info.paymentMethodId + " / " + info.amount, module);
1546                } else {
1547                    info.amount = new Double JavaDoc(0);
1548                    Debug.log("Set null paymentMethodId - " + info.paymentMethodId + " / " + info.amount, module);
1549                }
1550                if (!setOverflow) {
1551                    info.overflow = setOverflow = true;
1552                    Debug.log("Set overflow flag on payment - " + info.paymentMethodId, module);
1553                }
1554            }
1555        }
1556
1557        // verify the selected payment method amounts will cover the total
1558
double reqAmtPreParse = cart.getGrandTotal() - cart.getBillingAccountAmount();
1559        double selectedPaymentTotal = cart.getPaymentTotal();
1560
1561        String JavaDoc preParseString = formatter.format(reqAmtPreParse);
1562        double requiredAmount = 0;
1563        try {
1564            requiredAmount = formatter.parse(preParseString).doubleValue();
1565        } catch (ParseException JavaDoc e) {
1566            requiredAmount = reqAmtPreParse;
1567            Debug.logError(e, "Problem getting parsed required amount; unable to update payment info!", module);
1568        }
1569        if (paymentMethods != null && paymentMethods.size() > 0 && requiredAmount > selectedPaymentTotal) {
1570            Debug.logError("Required Amount : " + requiredAmount + " / Selected Amount : " + selectedPaymentTotal, module);
1571            errMsg = UtilProperties.getMessage(resource, "checkevents.payment_not_cover_this_order", (cart != null ? cart.getLocale() : Locale.getDefault()));
1572            return ServiceUtil.returnError(errMsg);
1573        }
1574
1575        return ServiceUtil.returnSuccess();
1576    }
1577
1578    public void validateGiftCardAmounts() {
1579        // get the product store
1580
GenericValue productStore = ProductStoreWorker.getProductStore(cart.getProductStoreId(), delegator);
1581        if (productStore != null && !"Y".equalsIgnoreCase(productStore.getString("checkGcBalance"))) {
1582            return;
1583        }
1584
1585        // get the payment config
1586
String JavaDoc paymentConfig = ProductStoreWorker.getProductStorePaymentProperties(delegator, cart.getProductStoreId(), "GIFT_CARD", null, true);
1587        String JavaDoc giftCardType = UtilProperties.getPropertyValue(paymentConfig, "", "ofbiz");
1588        String JavaDoc balanceField = null;
1589
1590        // get the gift card objects to check
1591
Iterator JavaDoc i = cart.getGiftCards().iterator();
1592        while (i.hasNext()) {
1593            GenericValue gc = (GenericValue) i.next();
1594            Map JavaDoc gcBalanceMap = null;
1595            double gcBalance = 0.00;
1596            try {
1597                Map JavaDoc ctx = UtilMisc.toMap("userLogin", cart.getUserLogin());
1598                ctx.put("currency", cart.getCurrency());
1599                if ("ofbiz".equalsIgnoreCase(giftCardType)) {
1600                    balanceField = "balance";
1601                    ctx.put("cardNumber", gc.getString("cardNumber"));
1602                    ctx.put("pinNumber", gc.getString("pinNumber"));
1603                    gcBalanceMap = dispatcher.runSync("checkGiftCertificateBalance", ctx);
1604                }
1605                if ("valuelink".equalsIgnoreCase(giftCardType)) {
1606                    balanceField = "balance";
1607                    ctx.put("paymentConfig", paymentConfig);
1608                    ctx.put("cardNumber", gc.getString("cardNumber"));
1609                    ctx.put("pin", gc.getString("pinNumber"));
1610                    gcBalanceMap = dispatcher.runSync("balanceInquireGiftCard", ctx);
1611                }
1612            } catch (GenericServiceException e) {
1613                Debug.logError(e, module);
1614            }
1615            if (gcBalanceMap != null) {
1616                Double JavaDoc bal = (Double JavaDoc) gcBalanceMap.get(balanceField);
1617                if (bal != null) {
1618                    gcBalance = bal.doubleValue();
1619                }
1620            }
1621
1622            // get the bill-up to amount
1623
Double JavaDoc billUpTo = cart.getPaymentAmount(gc.getString("paymentMethodId"));
1624
1625            // null bill-up to means use the full balance || update the bill-up to with the balance
1626
if (billUpTo == null || billUpTo.doubleValue() == 0 || gcBalance < billUpTo.doubleValue()) {
1627                cart.addPaymentAmount(gc.getString("paymentMethodId"), new Double JavaDoc(gcBalance));
1628            }
1629        }
1630    }
1631}
1632
Popular Tags