0001: /*
0002: * $Id: ValueLinkServices.java,v 1.5 2004/03/12 21:53:57 ajzeneski Exp $
0003: *
0004: * Copyright (c) 2003 The Open For Business Project - www.ofbiz.org
0005: *
0006: * Permission is hereby granted, free of charge, to any person obtaining a
0007: * copy of this software and associated documentation files (the "Software"),
0008: * to deal in the Software without restriction, including without limitation
0009: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0010: * and/or sell copies of the Software, and to permit persons to whom the
0011: * Software is furnished to do so, subject to the following conditions:
0012: *
0013: * The above copyright notice and this permission notice shall be included
0014: * in all copies or substantial portions of the Software.
0015: *
0016: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
0017: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0018: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
0019: * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
0020: * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
0021: * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
0022: * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
0023: *
0024: */
0025: package org.ofbiz.accounting.thirdparty.valuelink;
0026:
0027: import java.util.*;
0028:
0029: import org.ofbiz.service.*;
0030: import org.ofbiz.base.util.*;
0031: import org.ofbiz.entity.GenericDelegator;
0032: import org.ofbiz.entity.GenericValue;
0033: import org.ofbiz.entity.GenericEntityException;
0034: import org.ofbiz.entity.util.EntityUtil;
0035: import org.ofbiz.product.store.ProductStoreWorker;
0036: import org.ofbiz.order.order.OrderReadHelper;
0037:
0038: import javax.transaction.xa.XAException;
0039:
0040: /**
0041: * ValueLinkServices - Integration with ValueLink Gift Cards
0042: *
0043: * @author <a href="mailto:jaz@ofbiz.org">Andy Zeneski</a>
0044: * @version $Revision: 1.5 $
0045: * @since 3.0
0046: */
0047: public class ValueLinkServices {
0048:
0049: public static final String module = ValueLinkServices.class
0050: .getName();
0051:
0052: // generate/display new public/private/kek keys
0053: public static Map createKeys(DispatchContext dctx, Map context) {
0054: GenericDelegator delegator = dctx.getDelegator();
0055: Properties props = getProperties(context);
0056: ValueLinkApi vl = ValueLinkApi.getInstance(delegator, props);
0057: vl.reload();
0058:
0059: Boolean kekOnly = context.get("kekOnly") != null ? (Boolean) context
0060: .get("kekOnly")
0061: : new Boolean(false);
0062: String kekTest = (String) context.get("kekTest");
0063: Debug.log("KEK Only : " + kekOnly.booleanValue(), module);
0064:
0065: StringBuffer buf = vl.outputKeyCreation(kekOnly.booleanValue(),
0066: kekTest);
0067: String output = buf.toString();
0068: Debug.log(":: Key Generation Output ::\n\n" + output, module);
0069:
0070: Map result = ServiceUtil.returnSuccess();
0071: result.put("output", output);
0072: return result;
0073: }
0074:
0075: // test the KEK encryption
0076: public static Map testKekEncryption(DispatchContext dctx,
0077: Map context) {
0078: GenericDelegator delegator = dctx.getDelegator();
0079: GenericValue userLogin = (GenericValue) context
0080: .get("userLogin");
0081: Properties props = getProperties(context);
0082:
0083: // get an api instance
0084: ValueLinkApi vl = ValueLinkApi.getInstance(delegator, props);
0085: vl.reload();
0086:
0087: String testString = (String) context.get("kekTest");
0088: Integer mode = (Integer) context.get("mode");
0089: byte[] testBytes = StringUtil.fromHexString(testString);
0090:
0091: // place holder
0092: byte[] testEncryption = new byte[0];
0093: String desc = "";
0094:
0095: if (mode.intValue() == 1) {
0096: // encrypt the test bytes
0097: testEncryption = vl.encryptViaKek(testBytes);
0098: desc = "Encrypted";
0099: } else {
0100: // decrypt the test bytes
0101: testEncryption = vl.decryptViaKek(testBytes);
0102: desc = "Decrypted";
0103: }
0104:
0105: // setup the output
0106: StringBuffer buf = new StringBuffer();
0107: buf.append("======== Begin Test String (" + testString.length()
0108: + ") ========\n");
0109: buf.append(testString + "\n");
0110: buf.append("======== End Test String ========\n\n");
0111:
0112: buf.append("======== Begin Test Bytes (" + testBytes.length
0113: + ") ========\n");
0114: buf.append(StringUtil.toHexString(testBytes) + "\n");
0115: buf.append("======== End Test Bytes ========\n\n");
0116:
0117: buf.append("======== Begin Test Bytes " + desc + " ("
0118: + testEncryption.length + ") ========\n");
0119: buf.append(StringUtil.toHexString(testEncryption) + "\n");
0120: buf.append("======== End Test Bytes " + desc + " ========\n\n");
0121:
0122: String output = buf.toString();
0123: Debug.log(":: KEK Test Output ::\n\n" + output, module);
0124:
0125: Map result = ServiceUtil.returnSuccess();
0126: result.put("output", output);
0127: return result;
0128: }
0129:
0130: // change working key service
0131: public static Map assignWorkingKey(DispatchContext dctx, Map context) {
0132: GenericDelegator delegator = dctx.getDelegator();
0133: GenericValue userLogin = (GenericValue) context
0134: .get("userLogin");
0135: Properties props = getProperties(context);
0136:
0137: // get an api instance
0138: ValueLinkApi vl = ValueLinkApi.getInstance(delegator, props);
0139: vl.reload();
0140:
0141: // place holder
0142: byte[] mwk = null;
0143:
0144: // see if we passed in the DES hex string
0145: String desHexString = (String) context.get("desHexString");
0146: if (desHexString == null || desHexString.length() == 0) {
0147: mwk = vl.generateMwk();
0148: } else {
0149: mwk = vl
0150: .generateMwk(StringUtil.fromHexString(desHexString));
0151: }
0152:
0153: // encrypt the mwk
0154: String mwkHex = StringUtil.toHexString(vl.encryptViaKek(mwk));
0155:
0156: // build the request
0157: Map request = vl.getInitialRequestMap(context);
0158: request.put("Interface", "Encrypt");
0159: request.put("EncryptKey", mwkHex);
0160: request.put("EncryptID", new Long(vl.getWorkingKeyIndex()
0161: .longValue() + 1));
0162:
0163: // send the request
0164: Map response = null;
0165: try {
0166: response = vl.send(request);
0167: } catch (HttpClientException e) {
0168: Debug.logError(e, "Problem communicating with VL");
0169: return ServiceUtil.returnError("Unable to update MWK");
0170: }
0171: Debug.log("Response : " + response, module);
0172:
0173: // on success update the database / reload the cached api
0174: if (response != null) {
0175: String responseCode = (String) response.get("responsecode");
0176: if (responseCode.equals("00")) {
0177: GenericValue vlKeys = new GenericValue(vl
0178: .getGenericValue());
0179: vlKeys.set("lastWorkingKey", vlKeys.get("workingKey"));
0180: vlKeys.set("workingKey", StringUtil.toHexString(mwk));
0181: vlKeys.set("workingKeyIndex", request.get("EncryptID"));
0182: vlKeys.set("lastModifiedDate", UtilDateTime
0183: .nowTimestamp());
0184: vlKeys.set("lastModifiedByUserLogin",
0185: userLogin != null ? userLogin
0186: .get("userLoginId") : null);
0187: try {
0188: vlKeys.store();
0189: } catch (GenericEntityException e) {
0190: Debug.logError(e,
0191: "Unable to store updated keys; the keys were changed with ValueLink : "
0192: + vlKeys, module);
0193: return ServiceUtil
0194: .returnError("Unable to store updated keys");
0195: }
0196: vl.reload();
0197: return ServiceUtil.returnSuccess();
0198: } else {
0199: return ServiceUtil
0200: .returnError("Transaction failed with response code : "
0201: + responseCode);
0202: }
0203: } else {
0204: return ServiceUtil
0205: .returnError("Recevied back an empty response");
0206: }
0207: }
0208:
0209: public static Map activate(DispatchContext dctx, Map context) {
0210: GenericDelegator delegator = dctx.getDelegator();
0211: Properties props = getProperties(context);
0212: String vlPromoCode = (String) context.get("vlPromoCode");
0213: String cardNumber = (String) context.get("cardNumber");
0214: String pin = (String) context.get("pin");
0215: String currency = (String) context.get("currency");
0216: String orderId = (String) context.get("orderId");
0217: String partyId = (String) context.get("partyId");
0218: Double amount = (Double) context.get("amount");
0219:
0220: // override interface for void/rollback
0221: String iFace = (String) context.get("Interface");
0222:
0223: // get an api instance
0224: ValueLinkApi vl = ValueLinkApi.getInstance(delegator, props);
0225: Map request = vl.getInitialRequestMap(context);
0226: request.put("Interface", iFace != null ? iFace : "Activate");
0227: if (vlPromoCode != null && vlPromoCode.length() > 0) {
0228: request.put("PromoCode", vlPromoCode);
0229: }
0230: request.put("Amount", vl.getAmount(amount));
0231: request.put("LocalCurr", vl.getCurrency(currency));
0232:
0233: if (cardNumber != null && cardNumber.length() > 0) {
0234: request.put("CardNo", cardNumber);
0235: }
0236: if (pin != null && pin.length() > 0) {
0237: request.put("PIN", vl.encryptPin(pin));
0238: }
0239:
0240: // user defined field #1
0241: if (orderId != null && orderId.length() > 0) {
0242: request.put("User1", orderId);
0243: }
0244:
0245: // user defined field #2
0246: if (partyId != null && partyId.length() > 0) {
0247: request.put("User2", partyId);
0248: }
0249:
0250: // set the timeout reversal
0251: setTimeoutReversal(dctx, context, request);
0252:
0253: // send the request
0254: Map response = null;
0255: try {
0256: response = vl.send(request);
0257: } catch (HttpClientException e) {
0258: Debug.logError(e, "Problem communicating with VL");
0259: return ServiceUtil
0260: .returnError("Unable to activate gift card");
0261: }
0262:
0263: if (response != null) {
0264: String responseCode = (String) response.get("responsecode");
0265: Map result = ServiceUtil.returnSuccess();
0266: if (responseCode.equals("00")) {
0267: result.put("processResult", new Boolean(true));
0268: result.put("pin", vl.decryptPin((String) response
0269: .get("pin")));
0270: } else {
0271: result.put("processResult", new Boolean(false));
0272: result.put("pin", response.get("PIN"));
0273: }
0274: result.put("responseCode", responseCode);
0275: result.put("authCode", response.get("authcode"));
0276: result.put("cardNumber", response.get("cardno"));
0277: result.put("amount", vl.getAmount((String) response
0278: .get("currbal")));
0279: result.put("expireDate", response.get("expiredate"));
0280: result.put("cardClass", response.get("cardclass"));
0281: result.put("referenceNum", response.get("traceno"));
0282: Debug.log("Activate Result : " + result, module);
0283: return result;
0284: } else {
0285: return ServiceUtil
0286: .returnError("Empty response returned from ValueLink");
0287: }
0288: }
0289:
0290: public static Map linkPhysicalCard(DispatchContext dctx, Map context) {
0291: GenericDelegator delegator = dctx.getDelegator();
0292: Properties props = getProperties(context);
0293: String virtualCard = (String) context.get("virtualCard");
0294: String virtualPin = (String) context.get("virtualPin");
0295: String physicalCard = (String) context.get("physicalCard");
0296: String physicalPin = (String) context.get("physicalPin");
0297: String partyId = (String) context.get("partyId");
0298:
0299: // get an api instance
0300: ValueLinkApi vl = ValueLinkApi.getInstance(delegator, props);
0301: Map request = vl.getInitialRequestMap(context);
0302: request.put("Interface", "Link");
0303: request.put("VCardNo", virtualCard);
0304: request.put("VPIN", vl.encryptPin(virtualPin));
0305: request.put("PCardNo", physicalCard);
0306: request.put("PPIN", vl.encryptPin(physicalPin));
0307:
0308: // user defined field #2
0309: if (partyId != null && partyId.length() > 0) {
0310: request.put("User2", partyId);
0311: }
0312:
0313: // send the request
0314: Map response = null;
0315: try {
0316: response = vl.send(request);
0317: } catch (HttpClientException e) {
0318: Debug.logError(e, "Problem communicating with VL");
0319: return ServiceUtil
0320: .returnError("Unable to link gift card(s)");
0321: }
0322:
0323: if (response != null) {
0324: String responseCode = (String) response.get("responsecode");
0325: Map result = ServiceUtil
0326: .returnSuccess("Activation of physical card complete.");
0327: if (responseCode.equals("00")) {
0328:
0329: result.put("processResult", new Boolean(true));
0330: } else {
0331: result.put("processResult", new Boolean(false));
0332: }
0333: result.put("responseCode", responseCode);
0334: result.put("authCode", response.get("authcode"));
0335: result.put("amount", vl.getAmount((String) response
0336: .get("newbal")));
0337: result.put("expireDate", response.get("expiredate"));
0338: result.put("cardClass", response.get("cardclass"));
0339: result.put("referenceNum", response.get("traceno"));
0340: Debug.log("Link Result : " + result, module);
0341: return result;
0342: } else {
0343: return ServiceUtil
0344: .returnError("Empty response returned from ValueLink");
0345: }
0346: }
0347:
0348: public static Map disablePin(DispatchContext dctx, Map context) {
0349: GenericDelegator delegator = dctx.getDelegator();
0350: Properties props = getProperties(context);
0351: String cardNumber = (String) context.get("cardNumber");
0352: String pin = (String) context.get("pin");
0353: String orderId = (String) context.get("orderId");
0354: String partyId = (String) context.get("partyId");
0355: Double amount = (Double) context.get("amount");
0356:
0357: // get an api instance
0358: ValueLinkApi vl = ValueLinkApi.getInstance(delegator, props);
0359: Map request = vl.getInitialRequestMap(context);
0360: request.put("Interface", "Disable");
0361: request.put("CardNo", cardNumber);
0362: request.put("PIN", vl.encryptPin(pin));
0363: request.put("Amount", vl.getAmount(amount));
0364:
0365: // user defined field #1
0366: if (orderId != null && orderId.length() > 0) {
0367: request.put("User1", orderId);
0368: }
0369:
0370: // user defined field #2
0371: if (partyId != null && partyId.length() > 0) {
0372: request.put("User2", partyId);
0373: }
0374:
0375: // send the request
0376: Map response = null;
0377: try {
0378: response = vl.send(request);
0379: } catch (HttpClientException e) {
0380: Debug.logError(e, "Problem communicating with VL");
0381: return ServiceUtil.returnError("Unable to call disble pin");
0382: }
0383:
0384: if (response != null) {
0385: String responseCode = (String) response.get("responsecode");
0386: Map result = ServiceUtil.returnSuccess("PIN disabled.");
0387: if (responseCode.equals("00")) {
0388: result.put("processResult", new Boolean(true));
0389: } else {
0390: result.put("processResult", new Boolean(false));
0391: }
0392: result.put("responseCode", responseCode);
0393: result.put("balance", vl.getAmount((String) response
0394: .get("currbal")));
0395: result.put("expireDate", response.get("expiredate"));
0396: result.put("cardClass", response.get("cardclass"));
0397: result.put("referenceNum", response.get("traceno"));
0398: Debug.log("Disable Result : " + result, module);
0399: return result;
0400: } else {
0401: return ServiceUtil
0402: .returnError("Empty response returned from ValueLink");
0403: }
0404: }
0405:
0406: public static Map redeem(DispatchContext dctx, Map context) {
0407: GenericDelegator delegator = dctx.getDelegator();
0408: Properties props = getProperties(context);
0409: String cardNumber = (String) context.get("cardNumber");
0410: String pin = (String) context.get("pin");
0411: String currency = (String) context.get("currency");
0412: String orderId = (String) context.get("orderId");
0413: String partyId = (String) context.get("partyId");
0414: Double amount = (Double) context.get("amount");
0415:
0416: // override interface for void/rollback
0417: String iFace = (String) context.get("Interface");
0418:
0419: // get an api instance
0420: ValueLinkApi vl = ValueLinkApi.getInstance(delegator, props);
0421: Map request = vl.getInitialRequestMap(context);
0422: request.put("Interface", iFace != null ? iFace : "Redeem");
0423: request.put("CardNo", cardNumber);
0424: request.put("PIN", vl.encryptPin(pin));
0425: request.put("Amount", vl.getAmount(amount));
0426: request.put("LocalCurr", vl.getCurrency(currency));
0427:
0428: // user defined field #1
0429: if (orderId != null && orderId.length() > 0) {
0430: request.put("User1", orderId);
0431: }
0432:
0433: // user defined field #2
0434: if (partyId != null && partyId.length() > 0) {
0435: request.put("User2", partyId);
0436: }
0437:
0438: // set the timeout reversal
0439: setTimeoutReversal(dctx, context, request);
0440:
0441: // send the request
0442: Map response = null;
0443: try {
0444: response = vl.send(request);
0445: } catch (HttpClientException e) {
0446: Debug.logError(e, "Problem communicating with VL");
0447: return ServiceUtil
0448: .returnError("Unable to redeem gift card");
0449: }
0450:
0451: if (response != null) {
0452: String responseCode = (String) response.get("responsecode");
0453: Map result = ServiceUtil.returnSuccess();
0454: if (responseCode.equals("00")) {
0455: result.put("processResult", new Boolean(true));
0456: } else {
0457: result.put("processResult", new Boolean(false));
0458: }
0459: result.put("responseCode", responseCode);
0460: result.put("authCode", response.get("authcode"));
0461: result.put("previousAmount", vl.getAmount((String) response
0462: .get("prevbal")));
0463: result.put("amount", vl.getAmount((String) response
0464: .get("newbal")));
0465: result.put("expireDate", response.get("expiredate"));
0466: result.put("cardClass", response.get("cardclass"));
0467: result.put("cashBack", vl.getAmount((String) response
0468: .get("cashback")));
0469: result.put("referenceNum", response.get("traceno"));
0470: Debug.log("Redeem Result : " + result, module);
0471: return result;
0472: } else {
0473: return ServiceUtil
0474: .returnError("Empty response returned from ValueLink");
0475: }
0476: }
0477:
0478: public static Map reload(DispatchContext dctx, Map context) {
0479: GenericDelegator delegator = dctx.getDelegator();
0480: Properties props = getProperties(context);
0481: String cardNumber = (String) context.get("cardNumber");
0482: String pin = (String) context.get("pin");
0483: String currency = (String) context.get("currency");
0484: String orderId = (String) context.get("orderId");
0485: String partyId = (String) context.get("partyId");
0486: Double amount = (Double) context.get("amount");
0487:
0488: // override interface for void/rollback
0489: String iFace = (String) context.get("Interface");
0490:
0491: // get an api instance
0492: ValueLinkApi vl = ValueLinkApi.getInstance(delegator, props);
0493: Map request = vl.getInitialRequestMap(context);
0494: request.put("Interface", iFace != null ? iFace : "Reload");
0495: request.put("CardNo", cardNumber);
0496: request.put("PIN", vl.encryptPin(pin));
0497: request.put("Amount", vl.getAmount(amount));
0498: request.put("LocalCurr", vl.getCurrency(currency));
0499:
0500: // user defined field #1
0501: if (orderId != null && orderId.length() > 0) {
0502: request.put("User1", orderId);
0503: }
0504:
0505: // user defined field #2
0506: if (partyId != null && partyId.length() > 0) {
0507: request.put("User2", partyId);
0508: }
0509:
0510: // set the timeout reversal
0511: setTimeoutReversal(dctx, context, request);
0512:
0513: // send the request
0514: Map response = null;
0515: try {
0516: response = vl.send(request);
0517: } catch (HttpClientException e) {
0518: Debug.logError(e, "Problem communicating with VL");
0519: return ServiceUtil
0520: .returnError("Unable to reload gift card");
0521: }
0522:
0523: if (response != null) {
0524: String responseCode = (String) response.get("responsecode");
0525: Map result = ServiceUtil.returnSuccess();
0526: if (responseCode.equals("00")) {
0527: result.put("processResult", new Boolean(true));
0528: } else {
0529: result.put("processResult", new Boolean(false));
0530: }
0531: result.put("responseCode", responseCode);
0532: result.put("authCode", response.get("authcode"));
0533: result.put("previousAmount", vl.getAmount((String) response
0534: .get("prevbal")));
0535: result.put("amount", vl.getAmount((String) response
0536: .get("newbal")));
0537: result.put("expireDate", response.get("expiredate"));
0538: result.put("cardClass", response.get("cardclass"));
0539: result.put("referenceNum", response.get("traceno"));
0540: Debug.log("Reload Result : " + result, module);
0541: return result;
0542: } else {
0543: return ServiceUtil
0544: .returnError("Empty response returned from ValueLink");
0545: }
0546: }
0547:
0548: public static Map balanceInquire(DispatchContext dctx, Map context) {
0549: GenericDelegator delegator = dctx.getDelegator();
0550: Properties props = getProperties(context);
0551: String cardNumber = (String) context.get("cardNumber");
0552: String pin = (String) context.get("pin");
0553: String currency = (String) context.get("currency");
0554: String orderId = (String) context.get("orderId");
0555: String partyId = (String) context.get("partyId");
0556:
0557: // get an api instance
0558: ValueLinkApi vl = ValueLinkApi.getInstance(delegator, props);
0559: Map request = vl.getInitialRequestMap(context);
0560: request.put("Interface", "Balance");
0561: request.put("CardNo", cardNumber);
0562: request.put("PIN", vl.encryptPin(pin));
0563: request.put("LocalCurr", vl.getCurrency(currency));
0564:
0565: // user defined field #1
0566: if (orderId != null && orderId.length() > 0) {
0567: request.put("User1", orderId);
0568: }
0569:
0570: // user defined field #2
0571: if (partyId != null && partyId.length() > 0) {
0572: request.put("User2", partyId);
0573: }
0574:
0575: // send the request
0576: Map response = null;
0577: try {
0578: response = vl.send(request);
0579: } catch (HttpClientException e) {
0580: Debug.logError(e, "Problem communicating with VL");
0581: return ServiceUtil
0582: .returnError("Unable to call balance inquire");
0583: }
0584:
0585: if (response != null) {
0586: String responseCode = (String) response.get("responsecode");
0587: Map result = ServiceUtil.returnSuccess();
0588: if (responseCode.equals("00")) {
0589: result.put("processResult", new Boolean(true));
0590: } else {
0591: result.put("processResult", new Boolean(false));
0592: }
0593: result.put("responseCode", responseCode);
0594: result.put("balance", vl.getAmount((String) response
0595: .get("currbal")));
0596: result.put("expireDate", response.get("expiredate"));
0597: result.put("cardClass", response.get("cardclass"));
0598: result.put("referenceNum", response.get("traceno"));
0599: Debug.log("Balance Result : " + result, module);
0600: return result;
0601: } else {
0602: return ServiceUtil
0603: .returnError("Empty response returned from ValueLink");
0604: }
0605: }
0606:
0607: public static Map transactionHistory(DispatchContext dctx,
0608: Map context) {
0609: GenericDelegator delegator = dctx.getDelegator();
0610: Properties props = getProperties(context);
0611: String cardNumber = (String) context.get("cardNumber");
0612: String pin = (String) context.get("pin");
0613: String orderId = (String) context.get("orderId");
0614: String partyId = (String) context.get("partyId");
0615:
0616: // get an api instance
0617: ValueLinkApi vl = ValueLinkApi.getInstance(delegator, props);
0618: Map request = vl.getInitialRequestMap(context);
0619: request.put("Interface", "History");
0620: request.put("CardNo", cardNumber);
0621: request.put("PIN", vl.encryptPin(pin));
0622:
0623: // user defined field #1
0624: if (orderId != null && orderId.length() > 0) {
0625: request.put("User1", orderId);
0626: }
0627:
0628: // user defined field #2
0629: if (partyId != null && partyId.length() > 0) {
0630: request.put("User2", partyId);
0631: }
0632:
0633: // send the request
0634: Map response = null;
0635: try {
0636: response = vl.send(request);
0637: } catch (HttpClientException e) {
0638: Debug.logError(e, "Problem communicating with VL");
0639: return ServiceUtil
0640: .returnError("Unable to call history inquire");
0641: }
0642:
0643: if (response != null) {
0644: String responseCode = (String) response.get("responsecode");
0645: Map result = ServiceUtil.returnSuccess();
0646: if (responseCode.equals("00")) {
0647: result.put("processResult", new Boolean(true));
0648: } else {
0649: result.put("processResult", new Boolean(false));
0650: }
0651: result.put("responseCode", responseCode);
0652: result.put("balance", vl.getAmount((String) response
0653: .get("currbal")));
0654: result.put("history", response.get("history"));
0655: result.put("expireDate", response.get("expiredate"));
0656: result.put("cardClass", response.get("cardclass"));
0657: result.put("referenceNum", response.get("traceno"));
0658: Debug.log("History Result : " + result, module);
0659: return result;
0660: } else {
0661: return ServiceUtil
0662: .returnError("Empty response returned from ValueLink");
0663: }
0664: }
0665:
0666: public static Map refund(DispatchContext dctx, Map context) {
0667: GenericDelegator delegator = dctx.getDelegator();
0668: Properties props = getProperties(context);
0669: String cardNumber = (String) context.get("cardNumber");
0670: String pin = (String) context.get("pin");
0671: String currency = (String) context.get("currency");
0672: String orderId = (String) context.get("orderId");
0673: String partyId = (String) context.get("partyId");
0674: Double amount = (Double) context.get("amount");
0675:
0676: // override interface for void/rollback
0677: String iFace = (String) context.get("Interface");
0678:
0679: // get an api instance
0680: ValueLinkApi vl = ValueLinkApi.getInstance(delegator, props);
0681: Map request = vl.getInitialRequestMap(context);
0682: request.put("Interface", iFace != null ? iFace : "Refund");
0683: request.put("CardNo", cardNumber);
0684: request.put("PIN", vl.encryptPin(pin));
0685: request.put("Amount", vl.getAmount(amount));
0686: request.put("LocalCurr", vl.getCurrency(currency));
0687:
0688: // user defined field #1
0689: if (orderId != null && orderId.length() > 0) {
0690: request.put("User1", orderId);
0691: }
0692:
0693: // user defined field #2
0694: if (partyId != null && partyId.length() > 0) {
0695: request.put("User2", partyId);
0696: }
0697:
0698: // set the timeout reversal
0699: setTimeoutReversal(dctx, context, request);
0700:
0701: // send the request
0702: Map response = null;
0703: try {
0704: response = vl.send(request);
0705: } catch (HttpClientException e) {
0706: Debug.logError(e, "Problem communicating with VL");
0707: return ServiceUtil
0708: .returnError("Unable to refund gift card");
0709: }
0710:
0711: if (response != null) {
0712: String responseCode = (String) response.get("responsecode");
0713: Map result = ServiceUtil.returnSuccess();
0714: if (responseCode.equals("00")) {
0715: result.put("processResult", new Boolean(true));
0716: } else {
0717: result.put("processResult", new Boolean(false));
0718: }
0719: result.put("responseCode", responseCode);
0720: result.put("authCode", response.get("authcode"));
0721: result.put("previousAmount", vl.getAmount((String) response
0722: .get("prevbal")));
0723: result.put("amount", vl.getAmount((String) response
0724: .get("newbal")));
0725: result.put("expireDate", response.get("expiredate"));
0726: result.put("cardClass", response.get("cardclass"));
0727: result.put("referenceNum", response.get("traceno"));
0728: Debug.log("Refund Result : " + result, module);
0729: return result;
0730: } else {
0731: return ServiceUtil
0732: .returnError("Empty response returned from ValueLink");
0733: }
0734: }
0735:
0736: public static Map voidRedeem(DispatchContext dctx, Map context) {
0737: context.put("Interface", "Redeem/Void");
0738: return redeem(dctx, context);
0739: }
0740:
0741: public static Map voidRefund(DispatchContext dctx, Map context) {
0742: context.put("Interface", "Refund/Void");
0743: return refund(dctx, context);
0744: }
0745:
0746: public static Map voidReload(DispatchContext dctx, Map context) {
0747: context.put("Interface", "Reload/Void");
0748: return reload(dctx, context);
0749: }
0750:
0751: public static Map voidActivate(DispatchContext dctx, Map context) {
0752: context.put("Interface", "Activate/Void");
0753: return activate(dctx, context);
0754: }
0755:
0756: public static Map timeOutReversal(DispatchContext dctx, Map context) {
0757: String vlInterface = (String) context.get("Interface");
0758: Debug.log("704 Interface : " + vlInterface, module);
0759: if (vlInterface != null) {
0760: if (vlInterface.startsWith("Activate")) {
0761: if (vlInterface.equals("Activate/Rollback")) {
0762: return ServiceUtil
0763: .returnError("This transaction is not supported by ValueLink");
0764: }
0765: return activate(dctx, context);
0766: } else if (vlInterface.startsWith("Redeem")) {
0767: return redeem(dctx, context);
0768: } else if (vlInterface.startsWith("Reload")) {
0769: return reload(dctx, context);
0770: } else if (vlInterface.startsWith("Refund")) {
0771: return refund(dctx, context);
0772: }
0773: }
0774:
0775: return ServiceUtil.returnError("Not a valid 0704 transaction");
0776: }
0777:
0778: // 0704 Timeout Reversal (Supports - Activate/Void, Redeem, Redeem/Void, Reload, Reload/Void, Refund, Refund/Void)
0779: private static void setTimeoutReversal(DispatchContext dctx,
0780: Map ctx, Map request) {
0781: String vlInterface = (String) request.get("Interface");
0782: // clone the context
0783: Map context = new HashMap(ctx);
0784:
0785: // append the rollback interface
0786: if (vlInterface.endsWith("Rollback")) {
0787: context.put("Interface", vlInterface);
0788: } else {
0789: context.put("Interface", vlInterface + "/Rollback");
0790: }
0791:
0792: // set the old tx time and number
0793: context.put("MerchTime", request.get("MerchTime"));
0794: context.put("TermTxnNo", request.get("TermTxnNo"));
0795:
0796: // Activate/Rollback is not supported by valuelink
0797: if (!vlInterface.equals("Activate")) {
0798: // create the listener
0799: ServiceXaWrapper xaw = new ServiceXaWrapper(dctx);
0800: xaw.setRollbackService("vlTimeOutReversal", context);
0801: //xaw.setCommitService("vlTimeOutReversal", context);
0802: Debug.log("Set 704 context : " + context, module);
0803: try {
0804: xaw.enlist();
0805: } catch (XAException e) {
0806: Debug
0807: .logError(
0808: e,
0809: "Unable to setup 0704 Timeout Reversal",
0810: module);
0811: }
0812: }
0813: }
0814:
0815: private static Properties getProperties(Map context) {
0816: String paymentProperties = (String) context
0817: .get("paymentConfig");
0818: if (paymentProperties == null) {
0819: paymentProperties = "payment.properties";
0820: }
0821: return UtilProperties.getProperties(paymentProperties);
0822: }
0823:
0824: // payment processing wrappers (process/release/refund)
0825:
0826: public static Map giftCardProcessor(DispatchContext dctx,
0827: Map context) {
0828: LocalDispatcher dispatcher = dctx.getDispatcher();
0829: GenericValue userLogin = (GenericValue) context
0830: .get("userLogin");
0831:
0832: GenericValue giftCard = (GenericValue) context.get("giftCard");
0833: GenericValue person = (GenericValue) context
0834: .get("contactPerson");
0835: String paymentConfig = (String) context.get("paymentConfig");
0836: String currency = (String) context.get("currency");
0837: String orderId = (String) context.get("orderId");
0838: Double amount = (Double) context.get("processAmount");
0839:
0840: // make sure we have a currency
0841: if (currency == null) {
0842: currency = UtilProperties.getPropertyValue(
0843: "general.properties", "currency.uom.id.default",
0844: "USD");
0845: }
0846:
0847: Map redeemCtx = new HashMap();
0848: redeemCtx.put("userLogin", userLogin);
0849: redeemCtx.put("paymentConfig", paymentConfig);
0850: redeemCtx.put("cardNumber", giftCard.get("cardNumber"));
0851: redeemCtx.put("pin", giftCard.get("pinNumber"));
0852: redeemCtx.put("currency", currency);
0853: redeemCtx.put("orderId", orderId);
0854: redeemCtx.put("partyId", person.get("partyId"));
0855: redeemCtx.put("amount", amount);
0856:
0857: // invoke the redeem service
0858: Map redeemResult = null;
0859: try {
0860: redeemResult = dispatcher.runSync("redeemGiftCard",
0861: redeemCtx);
0862: } catch (GenericServiceException e) {
0863: Debug.logError(e, "Problem calling the redeem service",
0864: module);
0865: return ServiceUtil.returnError("Redeem service failed");
0866: }
0867:
0868: Map result = ServiceUtil.returnSuccess();
0869: if (redeemResult != null) {
0870: Boolean processResult = (Boolean) redeemResult
0871: .get("processResult");
0872: // confirm the amount redeemed; since VL does not error in insufficient funds
0873: if (processResult.booleanValue()) {
0874: Double previous = (Double) redeemResult
0875: .get("previousAmount");
0876: if (previous == null)
0877: previous = new Double(0);
0878: Double current = (Double) redeemResult.get("amount");
0879: if (current == null)
0880: current = new Double(0);
0881: double redeemed = previous.doubleValue()
0882: - current.doubleValue();
0883: if (redeemed < amount.doubleValue()) {
0884: // we didn't redeem enough void the transaction and return false
0885: Map voidResult = null;
0886: try {
0887: voidResult = dispatcher.runSync(
0888: "voidRedeemGiftCard", redeemCtx);
0889: } catch (GenericServiceException e) {
0890: Debug.logError(e, module);
0891: }
0892: if (ServiceUtil.isError(voidResult)) {
0893: return voidResult;
0894: }
0895: processResult = new Boolean(false);
0896: amount = new Double(redeemed);
0897: result.put("authMessage",
0898: "Gift card did not contain enough funds");
0899: }
0900: }
0901: result.put("processAmount", amount);
0902: result.put("authFlag", redeemResult.get("responseCode"));
0903: result.put("authResult", processResult);
0904: result.put("captureResult", processResult);
0905: result.put("authCode", redeemResult.get("authCode"));
0906: result.put("captureCode", redeemResult.get("authCode"));
0907: result.put("authRefNum", redeemResult.get("referenceNum"));
0908: result.put("captureRefNum", redeemResult
0909: .get("referenceNum"));
0910: }
0911:
0912: return result;
0913: }
0914:
0915: public static Map giftCardRelease(DispatchContext dctx, Map context) {
0916: LocalDispatcher dispatcher = dctx.getDispatcher();
0917: GenericValue userLogin = (GenericValue) context
0918: .get("userLogin");
0919:
0920: GenericValue paymentPref = (GenericValue) context
0921: .get("orderPaymentPreference");
0922: String paymentConfig = (String) context.get("paymentConfig");
0923: String currency = (String) context.get("currency");
0924: Double amount = (Double) context.get("releaseAmount");
0925:
0926: // get the orderId for tracking
0927: String orderId = paymentPref.getString("orderId");
0928:
0929: // get the GiftCard VO
0930: GenericValue giftCard = null;
0931: try {
0932: giftCard = paymentPref.getRelatedOne("GiftCard");
0933: } catch (GenericEntityException e) {
0934: Debug
0935: .logError(
0936: "Unable to get GiftCard from OrderPaymentPreference",
0937: module);
0938: return ServiceUtil
0939: .returnError("Unable to locate GiftCard Information");
0940: }
0941:
0942: if (giftCard == null) {
0943: return ServiceUtil
0944: .returnError("Attempt to release GiftCard payment faild; not a valid GiftCard record");
0945: }
0946:
0947: // make sure we have a currency
0948: if (currency == null) {
0949: currency = UtilProperties.getPropertyValue(
0950: "general.properties", "currency.uom.id.default",
0951: "USD");
0952: }
0953:
0954: Map redeemCtx = new HashMap();
0955: redeemCtx.put("userLogin", userLogin);
0956: redeemCtx.put("paymentConfig", paymentConfig);
0957: redeemCtx.put("cardNumber", giftCard.get("cardNumber"));
0958: redeemCtx.put("pin", giftCard.get("pinNumber"));
0959: redeemCtx.put("currency", currency);
0960: redeemCtx.put("orderId", orderId);
0961: redeemCtx.put("amount", amount);
0962:
0963: // invoke the void redeem service
0964: Map redeemResult = null;
0965: try {
0966: redeemResult = dispatcher.runSync("voidRedeemGiftCard",
0967: redeemCtx);
0968: } catch (GenericServiceException e) {
0969: Debug.logError(e, "Problem calling the redeem service",
0970: module);
0971: return ServiceUtil.returnError("Redeem service failed");
0972: }
0973:
0974: Map result = ServiceUtil.returnSuccess();
0975: if (redeemResult != null) {
0976: Boolean processResult = (Boolean) redeemResult
0977: .get("processResult");
0978: result.put("releaseAmount", redeemResult.get("amount"));
0979: result.put("releaseFlag", redeemResult.get("responseCode"));
0980: result.put("releaseResult", processResult);
0981: result.put("releaseCode", redeemResult.get("authCode"));
0982: result.put("releaseRefNum", redeemResult
0983: .get("referenceNum"));
0984: }
0985:
0986: return result;
0987: }
0988:
0989: public static Map giftCardRefund(DispatchContext dctx, Map context) {
0990: LocalDispatcher dispatcher = dctx.getDispatcher();
0991: GenericValue userLogin = (GenericValue) context
0992: .get("userLogin");
0993:
0994: GenericValue paymentPref = (GenericValue) context
0995: .get("orderPaymentPreference");
0996: String paymentConfig = (String) context.get("paymentConfig");
0997: String currency = (String) context.get("currency");
0998: Double amount = (Double) context.get("refundAmount");
0999:
1000: // get the orderId for tracking
1001: String orderId = paymentPref.getString("orderId");
1002:
1003: // get the GiftCard VO
1004: GenericValue giftCard = null;
1005: try {
1006: giftCard = paymentPref.getRelatedOne("GiftCard");
1007: } catch (GenericEntityException e) {
1008: Debug
1009: .logError(
1010: "Unable to get GiftCard from OrderPaymentPreference",
1011: module);
1012: return ServiceUtil
1013: .returnError("Unable to locate GiftCard Information");
1014: }
1015:
1016: if (giftCard == null) {
1017: return ServiceUtil
1018: .returnError("Attempt to release GiftCard payment faild; not a valid GiftCard record");
1019: }
1020:
1021: // make sure we have a currency
1022: if (currency == null) {
1023: currency = UtilProperties.getPropertyValue(
1024: "general.properties", "currency.uom.id.default",
1025: "USD");
1026: }
1027:
1028: Map refundCtx = new HashMap();
1029: refundCtx.put("userLogin", userLogin);
1030: refundCtx.put("paymentConfig", paymentConfig);
1031: refundCtx.put("cardNumber", giftCard.get("cardNumber"));
1032: refundCtx.put("pin", giftCard.get("pinNumber"));
1033: refundCtx.put("currency", currency);
1034: refundCtx.put("orderId", orderId);
1035: refundCtx.put("amount", amount);
1036:
1037: // invoke the refund service
1038: Map redeemResult = null;
1039: try {
1040: redeemResult = dispatcher.runSync("refundGiftCard",
1041: refundCtx);
1042: } catch (GenericServiceException e) {
1043: Debug.logError(e, "Problem calling the refund service",
1044: module);
1045: return ServiceUtil.returnError("Refund service failed");
1046: }
1047:
1048: Map result = ServiceUtil.returnSuccess();
1049: if (redeemResult != null) {
1050: Boolean processResult = (Boolean) redeemResult
1051: .get("processResult");
1052: result.put("refundAmount", redeemResult.get("amount"));
1053: result.put("refundFlag", redeemResult.get("responseCode"));
1054: result.put("refundResult", processResult);
1055: result.put("refundCode", redeemResult.get("authCode"));
1056: result
1057: .put("refundRefNum", redeemResult
1058: .get("referenceNum"));
1059: }
1060:
1061: return result;
1062: }
1063:
1064: // item fulfillment wrappers (purchase/reload)
1065:
1066: public static Map giftCardPurchase(DispatchContext dctx, Map context) {
1067: // this service should always be called via FULFILLMENT_EXTASYNC
1068: LocalDispatcher dispatcher = dctx.getDispatcher();
1069: GenericDelegator delegator = dctx.getDelegator();
1070: GenericValue userLogin = (GenericValue) context
1071: .get("userLogin");
1072: GenericValue orderItem = (GenericValue) context
1073: .get("orderItem");
1074:
1075: // order ID for tracking
1076: String orderId = orderItem.getString("orderId");
1077:
1078: // the order header for store info
1079: GenericValue orderHeader = null;
1080: try {
1081: orderHeader = orderItem.getRelatedOne("OrderHeader");
1082: } catch (GenericEntityException e) {
1083: Debug.logError(e,
1084: "Unable to get OrderHeader from OrderItem", module);
1085: return ServiceUtil
1086: .returnError("Unable to get OrderHeader from OrderItem");
1087: }
1088:
1089: // get the order read helper
1090: OrderReadHelper orh = new OrderReadHelper(orderHeader);
1091:
1092: // get the currency
1093: String currency = orh.getCurrency();
1094:
1095: // make sure we have a currency
1096: if (currency == null) {
1097: currency = UtilProperties.getPropertyValue(
1098: "general.properties", "currency.uom.id.default",
1099: "USD");
1100: }
1101:
1102: // get the product store
1103: String productStoreId = null;
1104: if (orderHeader != null) {
1105: productStoreId = orh.getProductStoreId();
1106: }
1107: if (productStoreId == null) {
1108: return ServiceUtil
1109: .returnError("Unable to process gift card purchase; no productStoreId on OrderHeader : "
1110: + orderId);
1111: }
1112:
1113: // payment config
1114: GenericValue paymentSetting = ProductStoreWorker
1115: .getProductStorePaymentSetting(delegator,
1116: productStoreId, "GIFT_CARD", null, true);
1117: String paymentConfig = null;
1118: if (paymentSetting != null) {
1119: paymentConfig = paymentSetting
1120: .getString("paymentPropertiesPath");
1121: }
1122: if (paymentConfig == null) {
1123: return ServiceUtil
1124: .returnError("Unable to get payment configuration file");
1125: }
1126:
1127: // party ID for tracking
1128: GenericValue placingParty = orh.getPlacingParty();
1129: String partyId = null;
1130: if (placingParty != null) {
1131: partyId = placingParty.getString("partyId");
1132: }
1133:
1134: // amount/quantity of the gift card(s)
1135: Double amount = orderItem.getDouble("unitPrice");
1136: Double quantity = orderItem.getDouble("quantity");
1137:
1138: // the product entity needed for information
1139: GenericValue product = null;
1140: try {
1141: product = orderItem.getRelatedOne("Product");
1142: } catch (GenericEntityException e) {
1143: Debug.logError("Unable to get Product from OrderItem",
1144: module);
1145: }
1146: if (product == null) {
1147: return ServiceUtil
1148: .returnError("No product associated with OrderItem, cannot fulfill gift card");
1149: }
1150:
1151: // get the productFeature type TYPE (VL promo code)
1152: GenericValue typeFeature = null;
1153: try {
1154: Map fields = UtilMisc.toMap("productId", product
1155: .get("productId"), "productFeatureTypeId", "TYPE");
1156: List order = UtilMisc.toList("-fromDate");
1157: List featureAppls = delegator.findByAndCache(
1158: "ProductFeatureAndAppl", fields, order);
1159: featureAppls = EntityUtil.filterByDate(featureAppls);
1160: typeFeature = EntityUtil.getFirst(featureAppls);
1161: } catch (GenericEntityException e) {
1162: Debug.logError(e, module);
1163: return ServiceUtil
1164: .returnError("Unable to get the required feature type TYPE from Product");
1165: }
1166: if (typeFeature == null) {
1167: return ServiceUtil
1168: .returnError("Required feature type TYPE not found for product : "
1169: + product.get("productId"));
1170: }
1171:
1172: // get the VL promo code
1173: String promoCode = typeFeature.getString("idCode");
1174: if (promoCode == null || promoCode.length() == 0) {
1175: return ServiceUtil
1176: .returnError("Invalid promo code set on idCode field of feature type TYPE");
1177: }
1178:
1179: // survey information
1180: String surveyId = UtilProperties.getPropertyValue(
1181: paymentConfig, "payment.valuelink.purchase.surveyId");
1182:
1183: // get the survey response
1184: GenericValue surveyResponse = null;
1185: try {
1186: Map fields = UtilMisc.toMap("orderId", orderId,
1187: "orderItemSeqId", orderItem.get("orderItemSeqId"),
1188: "surveyId", surveyId);
1189: List order = UtilMisc.toList("-responseDate");
1190: List responses = delegator.findByAnd("SurveyResponse",
1191: fields, order);
1192: // there should be only one
1193: surveyResponse = EntityUtil.getFirst(responses);
1194: } catch (GenericEntityException e) {
1195: Debug.logError(e, module);
1196: return ServiceUtil
1197: .returnError("Unable to get survey response information; cannot fulfill gift card");
1198: }
1199:
1200: // get the response answers
1201: List responseAnswers = null;
1202: try {
1203: responseAnswers = surveyResponse
1204: .getRelated("SurveyResponseAnswer");
1205: } catch (GenericEntityException e) {
1206: Debug.logError(e, module);
1207: return ServiceUtil
1208: .returnError("Unable to get survey response answers from survey response; cannot fulfill gift card");
1209: }
1210:
1211: // make a map of answer info
1212: Map answerMap = new HashMap();
1213: if (responseAnswers != null) {
1214: Iterator rai = responseAnswers.iterator();
1215: while (rai.hasNext()) {
1216: GenericValue answer = (GenericValue) rai.next();
1217: GenericValue question = null;
1218: try {
1219: question = answer.getRelatedOne("SurveyQuestion");
1220: } catch (GenericEntityException e) {
1221: Debug.logError(e, module);
1222: return ServiceUtil
1223: .returnError("Unable to get survey question from answer");
1224: }
1225: if (question != null) {
1226: String desc = question.getString("description");
1227: String ans = answer.getString("textResponse"); // only support text response types for now
1228: answerMap.put(desc, ans);
1229: }
1230: }
1231: }
1232:
1233: // get the send to email address - key defined in properties file
1234: String sendToKey = UtilProperties.getPropertyValue(
1235: paymentConfig,
1236: "payment.valuelink.purchase.survey.sendToEmail");
1237: String sendToEmail = (String) answerMap.get(sendToKey);
1238:
1239: // get the copyMe flag and set the order email address
1240: String orderEmails = orh.getOrderEmailString();
1241: String copyMeField = UtilProperties.getPropertyValue(
1242: paymentConfig,
1243: "payment.valuelink.purchase.survey.copyMe");
1244: String copyMeResp = copyMeField != null ? (String) answerMap
1245: .get(copyMeField) : null;
1246: boolean copyMe = (UtilValidate.isNotEmpty(copyMeField)
1247: && UtilValidate.isNotEmpty(copyMeResp) && "true"
1248: .equalsIgnoreCase(copyMeResp)) ? true : false;
1249:
1250: int qtyLoop = quantity.intValue();
1251: for (int i = 0; i < qtyLoop; i++) {
1252: // activate a gift card
1253: Map activateCtx = new HashMap();
1254: activateCtx.put("paymentConfig", paymentConfig);
1255: activateCtx.put("vlPromoCode", promoCode);
1256: activateCtx.put("currency", currency);
1257: activateCtx.put("partyId", partyId);
1258: activateCtx.put("orderId", orderId);
1259: activateCtx.put("amount", amount);
1260: activateCtx.put("userLogin", userLogin);
1261:
1262: boolean failure = false;
1263: Map activateResult = null;
1264: try {
1265: activateResult = dispatcher.runSync("activateGiftCard",
1266: activateCtx);
1267: } catch (GenericServiceException e) {
1268: Debug.logError(e, "Unable to activate gift card(s)",
1269: module);
1270: return ServiceUtil
1271: .returnError("Problem running activation service");
1272: }
1273:
1274: Boolean processResult = (Boolean) activateResult
1275: .get("processResult");
1276: if (activateResult == null
1277: || activateResult
1278: .containsKey(ModelService.ERROR_MESSAGE)
1279: || !processResult.booleanValue()) {
1280: failure = true;
1281: }
1282:
1283: if (!failure) {
1284: // set the void on rollback wrapper
1285: ServiceXaWrapper xaw = new ServiceXaWrapper(dctx);
1286: activateCtx.put("cardNumber", activateResult
1287: .get("cardNumber"));
1288: activateCtx.put("pin", activateResult.get("pin"));
1289: xaw.setRollbackService("voidActivateGiftCard",
1290: activateCtx);
1291: try {
1292: xaw.enlist();
1293: } catch (XAException e) {
1294: Debug.logError(e,
1295: "Unable to setup Activate/Void on error",
1296: module);
1297: }
1298: }
1299:
1300: // create the fulfillment record
1301: Map vlFulFill = new HashMap();
1302: vlFulFill.put("typeEnumId", "VL_ACTIVATE");
1303: vlFulFill.put("merchantId", UtilProperties
1304: .getPropertyValue(paymentConfig,
1305: "payment.valuelink.merchantId"));
1306: vlFulFill.put("partyId", partyId);
1307: vlFulFill.put("orderId", orderId);
1308: vlFulFill.put("orderItemSeqId", orderItem
1309: .get("orderItemSeqId"));
1310: vlFulFill.put("surveyResponseId", surveyResponse
1311: .get("surveyResponseId"));
1312: vlFulFill.put("cardNumber", activateResult
1313: .get("cardNumber"));
1314: vlFulFill.put("pinNumber", activateResult.get("pin"));
1315: vlFulFill.put("amount", activateResult.get("amount"));
1316: vlFulFill.put("responseCode", activateResult
1317: .get("responseCode"));
1318: vlFulFill.put("referenceNum", activateResult
1319: .get("referenceNum"));
1320: vlFulFill.put("authCode", activateResult.get("authCode"));
1321: vlFulFill.put("userLogin", userLogin);
1322: try {
1323: dispatcher.runAsync("createVLFulFillmentRecord",
1324: vlFulFill, true);
1325: } catch (GenericServiceException e) {
1326: Debug.logError(e, module);
1327: return ServiceUtil
1328: .returnError("Unable to store fulfillment info");
1329: }
1330:
1331: if (failure) {
1332: return ServiceUtil.returnError("Activate Failed");
1333: }
1334:
1335: // add some information to the answerMap for the email
1336: answerMap.put("cardNumber", activateResult
1337: .get("cardNumber"));
1338: answerMap.put("pinNumber", activateResult.get("pin"));
1339: answerMap.put("amount", activateResult.get("amount"));
1340:
1341: // get the email setting for this email type
1342: GenericValue productStoreEmail = null;
1343: String emailType = "PRDS_GC_PURCHASE";
1344: try {
1345: productStoreEmail = delegator.findByPrimaryKey(
1346: "ProductStoreEmailSetting", UtilMisc.toMap(
1347: "productStoreId", productStoreId,
1348: "emailType", emailType));
1349: } catch (GenericEntityException e) {
1350: Debug
1351: .logError(
1352: e,
1353: "Unable to get product store email setting for gift card purchase",
1354: module);
1355: }
1356: if (productStoreEmail == null) {
1357: Debug
1358: .logError(
1359: "No gift card purchase email setting found for this store; cannot send gift card information",
1360: module);
1361: } else {
1362: String subjectString = productStoreEmail
1363: .getString("subject");
1364: subjectString = FlexibleStringExpander.expandString(
1365: subjectString, answerMap);
1366:
1367: // set the bcc address(s)
1368: String bcc = productStoreEmail.getString("bccAddress");
1369: if (copyMe) {
1370: if (UtilValidate.isNotEmpty(bcc)) {
1371: bcc = bcc + "," + orderEmails;
1372: } else {
1373: bcc = orderEmails;
1374: }
1375: }
1376:
1377: String ofbizHome = System.getProperty("ofbiz.home");
1378: Map emailCtx = new HashMap();
1379: emailCtx.put("templateName", ofbizHome
1380: + productStoreEmail.get("templatePath"));
1381: emailCtx.put("templateData", answerMap);
1382: emailCtx.put("sendTo", sendToEmail);
1383: emailCtx.put("contentType", productStoreEmail
1384: .get("contentType"));
1385: emailCtx.put("sendFrom", productStoreEmail
1386: .get("fromAddress"));
1387: emailCtx.put("sendCc", productStoreEmail
1388: .get("ccAddress"));
1389: emailCtx.put("sendBcc", bcc);
1390: emailCtx.put("subject", subjectString);
1391: emailCtx.put("userLogin", userLogin);
1392:
1393: // send off the email async so we will retry on failed attempts
1394: try {
1395: dispatcher.runAsync("sendGenericNotificationEmail",
1396: emailCtx);
1397: } catch (GenericServiceException e) {
1398: Debug.logError(e, "Problem sending mail", module);
1399: // this is fatal; we will rollback and try again later
1400: return ServiceUtil
1401: .returnError("Problem sending email");
1402: }
1403: }
1404: }
1405:
1406: return ServiceUtil.returnSuccess();
1407: }
1408:
1409: public static Map giftCardReload(DispatchContext dctx, Map context) {
1410: // this service should always be called via FULFILLMENT_EXTSYNC
1411: LocalDispatcher dispatcher = dctx.getDispatcher();
1412: GenericDelegator delegator = dctx.getDelegator();
1413: GenericValue userLogin = (GenericValue) context
1414: .get("userLogin");
1415: GenericValue orderItem = (GenericValue) context
1416: .get("orderItem");
1417:
1418: // order ID for tracking
1419: String orderId = orderItem.getString("orderId");
1420:
1421: // the order header for store info
1422: GenericValue orderHeader = null;
1423: try {
1424: orderHeader = orderItem.getRelatedOne("OrderHeader");
1425: } catch (GenericEntityException e) {
1426: Debug.logError(e,
1427: "Unable to get OrderHeader from OrderItem", module);
1428: return ServiceUtil
1429: .returnError("Unable to get OrderHeader from OrderItem");
1430: }
1431:
1432: // get the order read helper
1433: OrderReadHelper orh = new OrderReadHelper(orderHeader);
1434:
1435: // get the currency
1436: String currency = orh.getCurrency();
1437:
1438: // make sure we have a currency
1439: if (currency == null) {
1440: currency = UtilProperties.getPropertyValue(
1441: "general.properties", "currency.uom.id.default",
1442: "USD");
1443: }
1444:
1445: // get the product store
1446: String productStoreId = null;
1447: if (orderHeader != null) {
1448: productStoreId = orh.getProductStoreId();
1449: }
1450: if (productStoreId == null) {
1451: return ServiceUtil
1452: .returnError("Unable to process gift card reload; no productStoreId on OrderHeader : "
1453: + orderId);
1454: }
1455:
1456: // payment config
1457: GenericValue paymentSetting = ProductStoreWorker
1458: .getProductStorePaymentSetting(delegator,
1459: productStoreId, "GIFT_CARD", null, true);
1460: String paymentConfig = null;
1461: if (paymentSetting != null) {
1462: paymentConfig = paymentSetting
1463: .getString("paymentPropertiesPath");
1464: }
1465: if (paymentConfig == null) {
1466: return ServiceUtil
1467: .returnError("Unable to get payment configuration file");
1468: }
1469:
1470: // party ID for tracking
1471: GenericValue placingParty = orh.getPlacingParty();
1472: String partyId = null;
1473: if (placingParty != null) {
1474: partyId = placingParty.getString("partyId");
1475: }
1476:
1477: // amount of the gift card reload
1478: Double amount = orderItem.getDouble("unitPrice");
1479:
1480: // survey information
1481: String surveyId = UtilProperties.getPropertyValue(
1482: paymentConfig, "payment.valuelink.reload.surveyId");
1483:
1484: // get the survey response
1485: GenericValue surveyResponse = null;
1486: try {
1487: Map fields = UtilMisc.toMap("orderId", orderId,
1488: "orderItemSeqId", orderItem.get("orderItemSeqId"),
1489: "surveyId", surveyId);
1490: List order = UtilMisc.toList("-responseDate");
1491: List responses = delegator.findByAnd("SurveyResponse",
1492: fields, order);
1493: // there should be only one
1494: surveyResponse = EntityUtil.getFirst(responses);
1495: } catch (GenericEntityException e) {
1496: Debug.logError(e, module);
1497: return ServiceUtil
1498: .returnError("Unable to get survey response information; cannot fulfill gift card reload");
1499: }
1500:
1501: // get the response answers
1502: List responseAnswers = null;
1503: try {
1504: responseAnswers = surveyResponse
1505: .getRelated("SurveyResponseAnswer");
1506: } catch (GenericEntityException e) {
1507: Debug.logError(e, module);
1508: return ServiceUtil
1509: .returnError("Unable to get survey response answers from survey response; cannot fulfill gift card reload");
1510: }
1511:
1512: // make a map of answer info
1513: Map answerMap = new HashMap();
1514: if (responseAnswers != null) {
1515: Iterator rai = responseAnswers.iterator();
1516: while (rai.hasNext()) {
1517: GenericValue answer = (GenericValue) rai.next();
1518: GenericValue question = null;
1519: try {
1520: question = answer.getRelatedOne("SurveyQuestion");
1521: } catch (GenericEntityException e) {
1522: Debug.logError(e, module);
1523: return ServiceUtil
1524: .returnError("Unable to get survey question from answer");
1525: }
1526: if (question != null) {
1527: String desc = question.getString("description");
1528: String ans = answer.getString("textResponse"); // only support text response types for now
1529: answerMap.put(desc, ans);
1530: }
1531: }
1532: }
1533:
1534: String cardNumberKey = UtilProperties.getPropertyValue(
1535: paymentConfig,
1536: "payment.valuelink.reload.survey.cardNumber");
1537: String pinNumberKey = UtilProperties.getPropertyValue(
1538: paymentConfig,
1539: "payment.valuelink.reload.survey.pinNumber");
1540: String cardNumber = (String) answerMap.get(cardNumberKey);
1541: String pinNumber = (String) answerMap.get(pinNumberKey);
1542:
1543: // reload the gift card
1544: Map reloadCtx = new HashMap();
1545: reloadCtx.put("paymentConfig", paymentConfig);
1546: reloadCtx.put("currency", currency);
1547: reloadCtx.put("partyId", partyId);
1548: reloadCtx.put("orderId", orderId);
1549: reloadCtx.put("cardNumber", cardNumber);
1550: reloadCtx.put("pin", pinNumber);
1551: reloadCtx.put("amount", amount);
1552: reloadCtx.put("userLogin", userLogin);
1553:
1554: Map reloadResult = null;
1555: try {
1556: reloadResult = dispatcher.runSync("reloadGiftCard",
1557: reloadCtx);
1558: } catch (GenericServiceException e) {
1559: Debug.logError(e, "Unable to reload gift card", module);
1560: return ServiceUtil
1561: .returnError("Problem running reload service");
1562: }
1563:
1564: // create the fulfillment record
1565: Map vlFulFill = new HashMap();
1566: vlFulFill.put("typeEnumId", "VL_RELOAD");
1567: vlFulFill.put("merchantId", UtilProperties.getPropertyValue(
1568: paymentConfig, "payment.valuelink.merchantId"));
1569: vlFulFill.put("partyId", partyId);
1570: vlFulFill.put("orderId", orderId);
1571: vlFulFill
1572: .put("orderItemSeqId", orderItem.get("orderItemSeqId"));
1573: vlFulFill.put("surveyResponseId", surveyResponse
1574: .get("surveyResponseId"));
1575: vlFulFill.put("cardNumber", cardNumber);
1576: vlFulFill.put("pinNumber", pinNumber);
1577: vlFulFill.put("amount", amount);
1578: vlFulFill.put("responseCode", reloadResult.get("responseCode"));
1579: vlFulFill.put("referenceNum", reloadResult.get("referenceNum"));
1580: vlFulFill.put("authCode", reloadResult.get("authCode"));
1581: vlFulFill.put("userLogin", userLogin);
1582: try {
1583: dispatcher.runAsync("createVLFulFillmentRecord", vlFulFill,
1584: true);
1585: } catch (GenericServiceException e) {
1586: Debug.logError(e, module);
1587: return ServiceUtil
1588: .returnError("Unable to store fulfillment info");
1589: }
1590:
1591: Boolean processResult = (Boolean) reloadResult
1592: .get("processResult");
1593: if (reloadResult == null
1594: || reloadResult.containsKey(ModelService.ERROR_MESSAGE)
1595: || !processResult.booleanValue()) {
1596: Debug.logError("Reload Failed Need to Refund : "
1597: + reloadResult, module);
1598:
1599: // process the return
1600: try {
1601: Map refundCtx = UtilMisc.toMap("orderItem", orderItem,
1602: "partyId", partyId, "userLogin", userLogin);
1603: dispatcher.runAsync("refundVLReload", refundCtx, null,
1604: true, 300, true);
1605: } catch (GenericServiceException e) {
1606: Debug
1607: .logError(
1608: e,
1609: "ERROR! Unable to call create refund service; this failed reload will NOT be refunded",
1610: module);
1611: }
1612:
1613: String responseCode = "-1";
1614: if (processResult != null) {
1615: responseCode = (String) reloadResult
1616: .get("responseCode");
1617: }
1618: if ("17".equals(responseCode)) {
1619: Debug.logError("Error code : " + responseCode
1620: + " : Max Balance Exceeded", module);
1621: return ServiceUtil
1622: .returnError("Gift Card Reload Failed : Max Balance Exceeded; charges will be refunded");
1623: } else {
1624: Debug.logError("Error code : " + responseCode
1625: + " : Processing Error", module);
1626: return ServiceUtil
1627: .returnError("Gift Card Reload Failed : Processing Error; charges will be refunded");
1628: }
1629: }
1630:
1631: // add some information to the answerMap for the email
1632: answerMap.put("processResult", reloadResult
1633: .get("processResult"));
1634: answerMap.put("responseCode", reloadResult.get("responseCode"));
1635: answerMap.put("previousAmount", reloadResult
1636: .get("previousAmount"));
1637: answerMap.put("amount", reloadResult.get("amount"));
1638:
1639: // get the email setting for this email type
1640: GenericValue productStoreEmail = null;
1641: String emailType = "PRDS_GC_RELOAD";
1642: try {
1643: productStoreEmail = delegator.findByPrimaryKey(
1644: "ProductStoreEmailSetting", UtilMisc.toMap(
1645: "productStoreId", productStoreId,
1646: "emailType", emailType));
1647: } catch (GenericEntityException e) {
1648: Debug
1649: .logError(
1650: e,
1651: "Unable to get product store email setting for gift card purchase",
1652: module);
1653: }
1654: if (productStoreEmail == null) {
1655: Debug
1656: .logError(
1657: "No gift card purchase email setting found for this store; cannot send gift card information",
1658: module);
1659: } else {
1660: String subjectString = productStoreEmail
1661: .getString("subject");
1662: subjectString = FlexibleStringExpander.expandString(
1663: subjectString, answerMap);
1664:
1665: String ofbizHome = System.getProperty("ofbiz.home");
1666: Map emailCtx = new HashMap();
1667: emailCtx.put("templateName", ofbizHome
1668: + productStoreEmail.get("templatePath"));
1669: emailCtx.put("templateData", answerMap);
1670: emailCtx.put("sendTo", orh.getOrderEmailString());
1671: emailCtx.put("contentType", productStoreEmail
1672: .get("contentType"));
1673: emailCtx.put("sendFrom", productStoreEmail
1674: .get("fromAddress"));
1675: emailCtx.put("sendCc", productStoreEmail.get("ccAddress"));
1676: emailCtx
1677: .put("sendBcc", productStoreEmail.get("bccAddress"));
1678: emailCtx.put("subject", subjectString);
1679: emailCtx.put("userLogin", userLogin);
1680:
1681: // send off the email async so we will retry on failed attempts
1682: try {
1683: dispatcher.runAsync("sendGenericNotificationEmail",
1684: emailCtx);
1685: } catch (GenericServiceException e) {
1686: Debug.logError(e, "Problem sending mail", module);
1687: // this is fatal; we will rollback and try again later
1688: return ServiceUtil.returnError("Problem sending email");
1689: }
1690: }
1691:
1692: return ServiceUtil.returnSuccess();
1693: }
1694:
1695: public static Map createFulfillmentRecord(DispatchContext dctx,
1696: Map context) {
1697: GenericDelegator delegator = dctx.getDelegator();
1698:
1699: // create the fulfillment record
1700: GenericValue vlFulFill = delegator.makeValue(
1701: "ValueLinkFulfillment", null);
1702: vlFulFill.set("fulfillmentId", delegator.getNextSeqId(
1703: "ValueLinkFulfillment").toString());
1704: vlFulFill.set("typeEnumId", context.get("typeEnumId"));
1705: vlFulFill.set("merchantId", context.get("merchantId"));
1706: vlFulFill.set("partyId", context.get("partyId"));
1707: vlFulFill.set("orderId", context.get("orderId"));
1708: vlFulFill.set("orderItemSeqId", context.get("orderItemSeqId"));
1709: vlFulFill.set("surveyResponseId", context
1710: .get("surveyResponseId"));
1711: vlFulFill.set("cardNumber", context.get("cardNumber"));
1712: vlFulFill.set("pinNumber", context.get("pinNumber"));
1713: vlFulFill.set("amount", context.get("amount"));
1714: vlFulFill.set("responseCode", context.get("responseCode"));
1715: vlFulFill.set("referenceNum", context.get("referenceNum"));
1716: vlFulFill.set("authCode", context.get("authCode"));
1717: vlFulFill.set("fulfillmentDate", UtilDateTime.nowTimestamp());
1718: try {
1719: delegator.create(vlFulFill);
1720: } catch (GenericEntityException e) {
1721: Debug.logError(e, module);
1722: return ServiceUtil
1723: .returnError("Unable to store fulfillment info");
1724: }
1725: return ServiceUtil.returnSuccess();
1726: }
1727:
1728: public static Map refundReload(DispatchContext dctx, Map context) {
1729: LocalDispatcher dispatcher = dctx.getDispatcher();
1730: GenericDelegator delegator = dctx.getDelegator();
1731: GenericValue userLogin = (GenericValue) context
1732: .get("userLogin");
1733: GenericValue orderItem = (GenericValue) context
1734: .get("orderItem");
1735: String partyId = (String) context.get("partyId");
1736:
1737: // refresh the item object for status changes
1738: try {
1739: orderItem.refresh();
1740: } catch (GenericEntityException e) {
1741: Debug.logError(e, module);
1742: }
1743:
1744: Map returnableInfo = null;
1745: try {
1746: returnableInfo = dispatcher.runSync(
1747: "getReturnableQuantity", UtilMisc.toMap(
1748: "orderItem", orderItem, "userLogin",
1749: userLogin));
1750: } catch (GenericServiceException e) {
1751: Debug.logError(e, module);
1752: return ServiceUtil
1753: .returnError("Unable to get returnable infomation for order item : "
1754: + orderItem);
1755: }
1756:
1757: if (returnableInfo != null) {
1758: Double returnableQuantity = (Double) returnableInfo
1759: .get("returnableQuantity");
1760: Double returnablePrice = (Double) returnableInfo
1761: .get("returnablePrice");
1762: Debug.logInfo("Returnable INFO : " + returnableQuantity
1763: + " @ " + returnablePrice + " :: " + orderItem,
1764: module);
1765:
1766: // create the return header
1767: Map returnHeaderInfo = new HashMap();
1768: returnHeaderInfo.put("fromPartyId", partyId);
1769: returnHeaderInfo.put("userLogin", userLogin);
1770: Map returnHeaderResp = null;
1771: try {
1772: returnHeaderResp = dispatcher.runSync(
1773: "createReturnHeader", returnHeaderInfo);
1774: } catch (GenericServiceException e) {
1775: Debug.logError(e, module);
1776: return ServiceUtil
1777: .returnError("Unable to create return header");
1778: }
1779:
1780: if (returnHeaderResp != null) {
1781: String errorMessage = ServiceUtil
1782: .getErrorMessage(returnHeaderResp);
1783: if (errorMessage != null) {
1784: return ServiceUtil.returnError(errorMessage);
1785: }
1786: }
1787:
1788: String returnId = null;
1789: if (returnHeaderResp != null) {
1790: returnId = (String) returnHeaderResp.get("returnId");
1791: }
1792:
1793: if (returnId == null) {
1794: return ServiceUtil
1795: .returnError("Create return did not return a valid return id");
1796: }
1797:
1798: // create the return item
1799: Map returnItemInfo = new HashMap();
1800: returnItemInfo.put("returnId", returnId);
1801: returnItemInfo.put("returnReasonId", "RTN_DIG_FILL_FAIL");
1802: returnItemInfo.put("returnTypeId", "RTN_REFUND");
1803: returnItemInfo.put("returnItemType", "ITEM");
1804: returnItemInfo.put("description", orderItem
1805: .get("itemDescription"));
1806: returnItemInfo.put("orderId", orderItem.get("orderId"));
1807: returnItemInfo.put("orderItemSeqId", orderItem
1808: .get("orderItemSeqId"));
1809: returnItemInfo.put("returnQuantity", returnableQuantity);
1810: returnItemInfo.put("returnPrice", returnablePrice);
1811: returnItemInfo.put("userLogin", userLogin);
1812: Map returnItemResp = null;
1813: try {
1814: returnItemResp = dispatcher.runSync("createReturnItem",
1815: returnItemInfo);
1816: } catch (GenericServiceException e) {
1817: Debug.logError(e, module);
1818: return ServiceUtil
1819: .returnError("Unable to create return item");
1820: }
1821:
1822: if (returnItemResp != null) {
1823: String errorMessage = ServiceUtil
1824: .getErrorMessage(returnItemResp);
1825: if (errorMessage != null) {
1826: return ServiceUtil.returnError(errorMessage);
1827: }
1828: }
1829:
1830: String returnItemSeqId = null;
1831: if (returnItemResp != null) {
1832: returnItemSeqId = (String) returnItemResp
1833: .get("returnItemSeqId");
1834: }
1835:
1836: if (returnItemSeqId == null) {
1837: return ServiceUtil
1838: .returnError("Create return item did not return a valid sequence id");
1839: } else {
1840: Debug.logVerbose("Created return item : " + returnId
1841: + " / " + returnItemSeqId, module);
1842: }
1843:
1844: // need the admin userLogin to "fake" out the update service
1845: GenericValue admin = null;
1846: try {
1847: admin = delegator.findByPrimaryKey("UserLogin",
1848: UtilMisc.toMap("userLoginId", "admin"));
1849: } catch (GenericEntityException e) {
1850: Debug.logError(e, module);
1851: return ServiceUtil
1852: .returnError("Unable to look up UserLogin from database");
1853: }
1854:
1855: // update the status to received so it can process
1856: Map updateReturnInfo = new HashMap();
1857: updateReturnInfo.put("returnId", returnId);
1858: updateReturnInfo.put("statusId", "RETURN_RECEIVED");
1859: updateReturnInfo.put("currentStatusId", "RETURN_REQUESTED");
1860: updateReturnInfo.put("userLogin", admin);
1861: Map updateReturnResp = null;
1862: try {
1863: updateReturnResp = dispatcher.runSync(
1864: "updateReturnHeader", updateReturnInfo);
1865: } catch (GenericServiceException e) {
1866: Debug.logError(e, module);
1867: return ServiceUtil
1868: .returnError("Unable to update return header status");
1869: }
1870:
1871: if (updateReturnResp != null) {
1872: String errorMessage = ServiceUtil
1873: .getErrorMessage(updateReturnResp);
1874: if (errorMessage != null) {
1875: return ServiceUtil.returnError(errorMessage);
1876: }
1877: }
1878: }
1879:
1880: return ServiceUtil.returnSuccess();
1881: }
1882: }
|