You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by jl...@apache.org on 2011/02/13 09:54:27 UTC

svn commit: r1070193 - /ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java

Author: jleroux
Date: Sun Feb 13 08:54:27 2011
New Revision: 1070193

URL: http://svn.apache.org/viewvc?rev=1070193&view=rev
Log:
A patch from Martin Kreidenweis "savePaymentGatewayResponse throws exceptions due to foreign key constraints" (https://issues.apache.org/jira/browse/OFBIZ-4176) - OFBIZ-4176

If you use a CC payment service provider that actually wants to save not only PaymentGatewayResponses, but also PaymentGatewayResponseMessages, saving these to the database actually might fail because they are created in the wrong order. The response and the messages are scheduled as separate async rollback services in processCreditResult. So it's not guaranteed the Response is there before OFBiz tries to add the ResponseMessages. 

Fix for the issue: we created a new savePaymentGatewayResponseAndMessages service, that takes both the Response and the ResponseMessages and writes them to the database in the right order.

Modified:
    ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java

Modified: ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java?rev=1070193&r1=1070192&r2=1070193&view=diff
==============================================================================
--- ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java (original)
+++ ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java Sun Feb 13 08:54:27 2011
@@ -818,9 +818,8 @@ public class PaymentGatewayServices {
         pgCredit.set("gatewayMessage", context.get("creditMessage"));
         pgCredit.set("transactionDate", UtilDateTime.nowTimestamp());
         pgCredit.set("currencyUomId", currencyUomId);
-        // store the gateway response
-        savePgr(dctx, pgCredit);
         // create the internal messages
+        List<GenericValue> messageEntities = FastList.newInstance();
         List<String> messages = UtilGenerics.cast(context.get("internalRespMsgs"));
         if (UtilValidate.isNotEmpty(messages)) {
             Iterator<String> i = messages.iterator();
@@ -832,9 +831,12 @@ public class PaymentGatewayServices {
                 respMsg.set("paymentGatewayResponseId", responseId);
                 respMsg.set("pgrMessage", message);
                 // store the messages
-                savePgr(dctx, respMsg);
+                messageEntities.add(respMsg);
             }
         }
+        // save the response and respective messages
+        savePgrAndMsgs(dctx, pgCredit, messageEntities);
+
         if (creditResponse != null && creditResponse.booleanValue()) {
             paymentPref.set("statusId", "PAYMENT_CANCELLED");
             try {
@@ -1946,10 +1948,8 @@ public class PaymentGatewayServices {
             if (Boolean.TRUE.equals(context.get("resultBadExpire"))) response.set("resultBadExpire", "Y");
             if (Boolean.TRUE.equals(context.get("resultBadCardNumber"))) response.set("resultBadCardNumber", "Y");
 
-            // save the response
-            savePgr(dctx, response);
-
             // create the internal messages
+            List<GenericValue> messageEntities = FastList.newInstance();
             List<String> messages = UtilGenerics.cast(context.get("internalRespMsgs"));
             if (UtilValidate.isNotEmpty(messages)) {
                 Iterator<String> i = messages.iterator();
@@ -1960,10 +1960,13 @@ public class PaymentGatewayServices {
                     respMsg.set("paymentGatewayRespMsgId", respMsgId);
                     respMsg.set("paymentGatewayResponseId", responseId);
                     respMsg.set("pgrMessage", message);
-                    savePgr(dctx, respMsg);
+                    messageEntities.add(respMsg);
                 }
             }
 
+            // save the response and respective messages
+            savePgrAndMsgs(dctx, response, messageEntities);
+
             if (response.getBigDecimal("amount").compareTo((BigDecimal)context.get("processAmount")) != 0) {
                 Debug.logWarning("The authorized amount does not match the max amount : Response - " + response + " : result - " + context, module);
             }
@@ -2927,6 +2930,22 @@ public class PaymentGatewayServices {
         }
     }
 
+    private static void savePgrAndMsgs(DispatchContext dctx, GenericValue pgr, List<GenericValue> messages) {
+        Map<String, GenericValue> context = UtilMisc.<String, GenericValue>toMap("paymentGatewayResponse", pgr, "messages", messages);
+        LocalDispatcher dispatcher = dctx.getDispatcher();
+        Delegator delegator = dctx.getDelegator();
+
+        try {
+            dispatcher.addRollbackService("savePaymentGatewayResponseAndMessages", context, true);
+            delegator.create(pgr);
+            for (GenericValue message : messages) {
+                delegator.create(message);
+            }
+        } catch (Exception e) {
+            Debug.logError(e, module);
+        }
+    }
+
     public static Map<String, Object> savePaymentGatewayResponse(DispatchContext dctx, Map<String, ? extends Object> context) {
         Delegator delegator = dctx.getDelegator();
         GenericValue pgr = (GenericValue) context.get("paymentGatewayResponse");
@@ -2946,6 +2965,28 @@ public class PaymentGatewayServices {
         return ServiceUtil.returnSuccess();
     }
 
+    public static Map<String, Object> savePaymentGatewayResponseAndMessages(DispatchContext dctx, Map<String, ? extends Object> context) {
+        Delegator delegator = dctx.getDelegator();
+        GenericValue pgr = (GenericValue) context.get("paymentGatewayResponse");
+        String gatewayMessage = pgr.getString("gatewayMessage");
+        if (UtilValidate.isNotEmpty(gatewayMessage) && gatewayMessage.length() > 255) {
+            pgr.set("gatewayMessage", gatewayMessage.substring(0, 255));
+        }
+        @SuppressWarnings("unchecked")
+        List<GenericValue> messages = (List<GenericValue>) context.get("messages");
+
+        try {
+            delegator.create(pgr);
+            for (GenericValue message : messages) {
+                delegator.create(message);
+            }
+        } catch (GenericEntityException e) {
+            Debug.logError(e, module);
+        }
+
+        return ServiceUtil.returnSuccess();
+    }
+
     // manual auth service
     public static Map<String, Object> processManualCcAuth(DispatchContext dctx, Map<String, ? extends Object> context) {
         GenericValue userLogin = (GenericValue) context.get("userLogin");