Search in sources :

Example 86 with LocalDispatcher

use of org.apache.ofbiz.service.LocalDispatcher in project ofbiz-framework by apache.

the class FinAccountPaymentServices method finAccountPreAuth.

// base payment integration services
public static Map<String, Object> finAccountPreAuth(DispatchContext dctx, Map<String, Object> context) {
    LocalDispatcher dispatcher = dctx.getDispatcher();
    Delegator delegator = dctx.getDelegator();
    GenericValue userLogin = (GenericValue) context.get("userLogin");
    Locale locale = (Locale) context.get("locale");
    GenericValue paymentPref = (GenericValue) context.get("orderPaymentPreference");
    String finAccountCode = (String) context.get("finAccountCode");
    String finAccountPin = (String) context.get("finAccountPin");
    String finAccountId = (String) context.get("finAccountId");
    String orderId = (String) context.get("orderId");
    BigDecimal amount = (BigDecimal) context.get("processAmount");
    if (paymentPref != null) {
        // check for an existing auth trans and cancel it
        GenericValue authTrans = PaymentGatewayServices.getAuthTransaction(paymentPref);
        if (authTrans != null) {
            Map<String, Object> input = UtilMisc.toMap("userLogin", userLogin, "finAccountAuthId", authTrans.get("referenceNum"));
            try {
                Map<String, Object> result = dispatcher.runSync("expireFinAccountAuth", input);
                if (ServiceUtil.isError(result)) {
                    return ServiceUtil.returnError(ServiceUtil.getErrorMessage(result));
                }
            } catch (GenericServiceException e) {
                Debug.logError(e, module);
                return ServiceUtil.returnError(e.getMessage());
            }
        }
        if (finAccountId == null) {
            finAccountId = paymentPref.getString("finAccountId");
        }
    }
    // obtain the order information
    OrderReadHelper orh = new OrderReadHelper(delegator, orderId);
    // NOTE DEJ20070808: this means that we want store related settings for where
    // the item is being purchased,
    // NOT where the account was setup; should this be changed to use settings from
    // the store where the account was setup?
    String productStoreId = orh.getProductStoreId();
    // TODO, NOTE DEJ20070808: why is this setup this way anyway? for the
    // allowAuthToNegative wouldn't that be better setup
    // on the FinAccount and not on the ProductStoreFinActSetting? maybe an override
    // on the FinAccount would be good...
    // get the financial account
    GenericValue finAccount;
    if (finAccountId != null) {
        try {
            finAccount = EntityQuery.use(delegator).from("FinAccount").where("finAccountId", finAccountId).queryOne();
        } catch (GenericEntityException e) {
            Debug.logError(e, module);
            return ServiceUtil.returnError(e.getMessage());
        }
    } else {
        if (finAccountCode != null) {
            try {
                finAccount = FinAccountHelper.getFinAccountFromCode(finAccountCode, delegator);
            } catch (GenericEntityException e) {
                Debug.logError(e, module);
                return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "AccountingFinAccountCannotLocateItFromAccountCode", locale));
            }
        } else {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "AccountingFinAccountIdAndFinAccountCodeAreNull", locale));
        }
    }
    if (finAccount == null) {
        return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "AccountingFinAccountIdInvalid", locale));
    }
    String finAccountTypeId = finAccount.getString("finAccountTypeId");
    finAccountId = finAccount.getString("finAccountId");
    String statusId = finAccount.getString("statusId");
    try {
        // fin the store requires a pin number; validate the PIN with the code
        Map<String, Object> findProductStoreFinActSettingMap = UtilMisc.<String, Object>toMap("productStoreId", productStoreId, "finAccountTypeId", finAccountTypeId);
        GenericValue finAccountSettings = EntityQuery.use(delegator).from("ProductStoreFinActSetting").where(findProductStoreFinActSettingMap).cache().queryOne();
        if (finAccountSettings == null) {
            Debug.logWarning("In finAccountPreAuth could not find ProductStoreFinActSetting record, values searched by: " + findProductStoreFinActSettingMap, module);
        }
        if (Debug.verboseOn()) {
            Debug.logVerbose("In finAccountPreAuth finAccountSettings=" + finAccountSettings, module);
        }
        BigDecimal minBalance = FinAccountHelper.ZERO;
        String allowAuthToNegative = "N";
        if (finAccountSettings != null) {
            allowAuthToNegative = finAccountSettings.getString("allowAuthToNegative");
            minBalance = finAccountSettings.getBigDecimal("minBalance");
            if (minBalance == null) {
                minBalance = FinAccountHelper.ZERO;
            }
            // validate the PIN if the store requires it
            if ("Y".equals(finAccountSettings.getString("requirePinCode"))) {
                if (!FinAccountHelper.validatePin(delegator, finAccountCode, finAccountPin)) {
                    Map<String, Object> result = ServiceUtil.returnSuccess();
                    result.put("authMessage", UtilProperties.getMessage(resourceError, "AccountingFinAccountPinCodeCombinatorNotFound", locale));
                    result.put("authResult", Boolean.FALSE);
                    result.put("processAmount", amount);
                    result.put("authFlag", "0");
                    result.put("authCode", "A");
                    result.put("authRefNum", "0");
                    Debug.logWarning("Unable to auth FinAccount: " + result, module);
                    return result;
                }
            }
        }
        // check for expiration date
        if ((finAccount.getTimestamp("thruDate") != null) && (finAccount.getTimestamp("thruDate").before(UtilDateTime.nowTimestamp()))) {
            Map<String, Object> result = ServiceUtil.returnSuccess();
            result.put("authMessage", UtilProperties.getMessage(resourceError, "AccountingFinAccountExpired", UtilMisc.toMap("thruDate", finAccount.getTimestamp("thruDate")), locale));
            result.put("authResult", Boolean.FALSE);
            result.put("processAmount", amount);
            result.put("authFlag", "0");
            result.put("authCode", "A");
            result.put("authRefNum", "0");
            Debug.logWarning("Unable to auth FinAccount: " + result, module);
            return result;
        }
        // check for account being in bad standing somehow
        if ("FNACT_NEGPENDREPL".equals(statusId) || "FNACT_MANFROZEN".equals(statusId) || "FNACT_CANCELLED".equals(statusId)) {
            // refresh the finaccount
            finAccount.refresh();
            statusId = finAccount.getString("statusId");
            if ("FNACT_NEGPENDREPL".equals(statusId) || "FNACT_MANFROZEN".equals(statusId) || "FNACT_CANCELLED".equals(statusId)) {
                Map<String, Object> result = ServiceUtil.returnSuccess();
                if ("FNACT_NEGPENDREPL".equals(statusId)) {
                    result.put("authMessage", UtilProperties.getMessage(resourceError, "AccountingFinAccountNegative", locale));
                } else if ("FNACT_MANFROZEN".equals(statusId)) {
                    result.put("authMessage", UtilProperties.getMessage(resourceError, "AccountingFinAccountFrozen", locale));
                } else if ("FNACT_CANCELLED".equals(statusId)) {
                    result.put("authMessage", UtilProperties.getMessage(resourceError, "AccountingFinAccountCancelled", locale));
                }
                result.put("authResult", Boolean.FALSE);
                result.put("processAmount", amount);
                result.put("authFlag", "0");
                result.put("authCode", "A");
                result.put("authRefNum", "0");
                Debug.logWarning("Unable to auth FinAccount: " + result, module);
                return result;
            }
        }
        // check the amount to authorize against the available balance of fin account,
        // which includes active authorizations as well as transactions
        BigDecimal availableBalance = finAccount.getBigDecimal("availableBalance");
        if (availableBalance == null) {
            availableBalance = FinAccountHelper.ZERO;
        } else {
            BigDecimal availableBalanceOriginal = availableBalance;
            availableBalance = availableBalance.setScale(FinAccountHelper.decimals, FinAccountHelper.rounding);
            if (availableBalance.compareTo(availableBalanceOriginal) != 0) {
                Debug.logWarning("In finAccountPreAuth for finAccountId [" + finAccountId + "] availableBalance [" + availableBalanceOriginal + "] was different after rounding [" + availableBalance + "]; it should never have made it into the database this way, so check whatever put it there.", module);
            }
        }
        Map<String, Object> result = ServiceUtil.returnSuccess();
        String authMessage = null;
        Boolean processResult;
        String refNum;
        // make sure to round and scale it to the same as availableBalance
        amount = amount.setScale(FinAccountHelper.decimals, FinAccountHelper.rounding);
        Debug.logInfo("Allow auth to negative: " + allowAuthToNegative + " :: available: " + availableBalance + " comp: " + minBalance + " = " + availableBalance.compareTo(minBalance) + " :: req: " + amount, module);
        // check the available balance to see if we can auth this tx
        if (("Y".equals(allowAuthToNegative) && availableBalance.compareTo(minBalance) > -1) || (availableBalance.compareTo(amount) > -1)) {
            Timestamp thruDate;
            if (finAccountSettings != null && finAccountSettings.getLong("authValidDays") != null) {
                thruDate = UtilDateTime.getDayEnd(UtilDateTime.nowTimestamp(), finAccountSettings.getLong("authValidDays"));
            } else {
                // default 30 days for an auth
                thruDate = UtilDateTime.getDayEnd(UtilDateTime.nowTimestamp(), Long.valueOf(30));
            }
            Map<String, Object> tmpResult = dispatcher.runSync("createFinAccountAuth", UtilMisc.<String, Object>toMap("finAccountId", finAccountId, "amount", amount, "thruDate", thruDate, "userLogin", userLogin));
            if (ServiceUtil.isError(tmpResult)) {
                return ServiceUtil.returnError(ServiceUtil.getErrorMessage(tmpResult));
            }
            refNum = (String) tmpResult.get("finAccountAuthId");
            processResult = Boolean.TRUE;
            // refresh the account
            finAccount.refresh();
        } else {
            Debug.logWarning("Attempted to authorize [" + amount + "] against a balance of only [" + availableBalance + "] for finAccountId [" + finAccountId + "]", module);
            // a refNum is always required from authorization
            refNum = "0";
            authMessage = "Insufficient funds";
            processResult = Boolean.FALSE;
        }
        result.put("processAmount", amount);
        result.put("authMessage", authMessage);
        result.put("authResult", processResult);
        result.put("processAmount", amount);
        result.put("authFlag", "1");
        result.put("authCode", "A");
        result.put("authRefNum", refNum);
        Debug.logInfo("FinAccont Auth: " + result, module);
        return result;
    } catch (GenericEntityException | GenericServiceException ex) {
        Debug.logError(ex, "Cannot authorize financial account", module);
        return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "AccountingFinAccountCannotBeAuthorized", UtilMisc.toMap("errorString", ex.getMessage()), locale));
    }
}
Also used : Locale(java.util.Locale) GenericValue(org.apache.ofbiz.entity.GenericValue) LocalDispatcher(org.apache.ofbiz.service.LocalDispatcher) Timestamp(java.sql.Timestamp) BigDecimal(java.math.BigDecimal) OrderReadHelper(org.apache.ofbiz.order.order.OrderReadHelper) Delegator(org.apache.ofbiz.entity.Delegator) GenericEntityException(org.apache.ofbiz.entity.GenericEntityException) GenericServiceException(org.apache.ofbiz.service.GenericServiceException)

Example 87 with LocalDispatcher

use of org.apache.ofbiz.service.LocalDispatcher in project ofbiz-framework by apache.

the class FinAccountPaymentServices method finAccountReplenish.

// auto-replenish service (deposit)
public static Map<String, Object> finAccountReplenish(DispatchContext dctx, Map<String, Object> context) {
    LocalDispatcher dispatcher = dctx.getDispatcher();
    Delegator delegator = dctx.getDelegator();
    Locale locale = (Locale) context.get("locale");
    GenericValue userLogin = (GenericValue) context.get("userLogin");
    String productStoreId = (String) context.get("productStoreId");
    String finAccountId = (String) context.get("finAccountId");
    // lookup the FinAccount
    GenericValue finAccount;
    try {
        finAccount = EntityQuery.use(delegator).from("FinAccount").where("finAccountId", finAccountId).queryOne();
    } catch (GenericEntityException e) {
        Debug.logError(e, module);
        return ServiceUtil.returnError(e.getMessage());
    }
    if (finAccount == null) {
        return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "AccountingFinAccountNotFound", UtilMisc.toMap("finAccountId", finAccountId), locale));
    }
    String currency = finAccount.getString("currencyUomId");
    String statusId = finAccount.getString("statusId");
    // look up the type -- determine auto-replenish is active
    GenericValue finAccountType;
    try {
        finAccountType = finAccount.getRelatedOne("FinAccountType", false);
    } catch (GenericEntityException e) {
        Debug.logError(e, module);
        return ServiceUtil.returnError(e.getMessage());
    }
    String replenishEnumId = finAccountType.getString("replenishEnumId");
    if (!"FARP_AUTOMATIC".equals(replenishEnumId)) {
        // type does not support auto-replenish
        return ServiceUtil.returnSuccess();
    }
    // attempt to lookup the product store from a previous deposit
    if (productStoreId == null) {
        productStoreId = getLastProductStoreId(delegator, finAccountId);
        if (productStoreId == null) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "AccountingFinAccountCannotBeReplenish", locale));
        }
    }
    // get the product store settings
    GenericValue finAccountSettings;
    Map<String, Object> psfasFindMap = UtilMisc.<String, Object>toMap("productStoreId", productStoreId, "finAccountTypeId", finAccount.getString("finAccountTypeId"));
    try {
        finAccountSettings = EntityQuery.use(delegator).from("ProductStoreFinActSetting").where(psfasFindMap).cache().queryOne();
    } catch (GenericEntityException e) {
        Debug.logError(e, module);
        return ServiceUtil.returnError(e.getMessage());
    }
    if (finAccountSettings == null) {
        Debug.logWarning("finAccountReplenish Warning: not replenishing FinAccount [" + finAccountId + "] because no ProductStoreFinActSetting record found for: " + psfasFindMap, module);
        // no settings; don't replenish
        return ServiceUtil.returnSuccess();
    }
    BigDecimal replenishThreshold = finAccountSettings.getBigDecimal("replenishThreshold");
    if (replenishThreshold == null) {
        Debug.logWarning("finAccountReplenish Warning: not replenishing FinAccount [" + finAccountId + "] because ProductStoreFinActSetting.replenishThreshold field was null for: " + psfasFindMap, module);
        return ServiceUtil.returnSuccess();
    }
    BigDecimal replenishLevel = finAccount.getBigDecimal("replenishLevel");
    if (replenishLevel == null || replenishLevel.compareTo(BigDecimal.ZERO) == 0) {
        Debug.logWarning("finAccountReplenish Warning: not replenishing FinAccount [" + finAccountId + "] because FinAccount.replenishLevel field was null or 0", module);
        // no replenish level set; this account goes not support auto-replenish
        return ServiceUtil.returnSuccess();
    }
    // get the current balance
    BigDecimal balance = finAccount.getBigDecimal("actualBalance");
    // see if we are within the threshold for replenishment
    if (balance.compareTo(replenishThreshold) > -1) {
        Debug.logInfo("finAccountReplenish Info: Not replenishing FinAccount [" + finAccountId + "] because balance [" + balance + "] is greater than the replenishThreshold [" + replenishThreshold + "]", module);
        // not ready
        return ServiceUtil.returnSuccess();
    }
    // configure rollback service to set status to Negative Pending Replenishment
    if ("FNACT_NEGPENDREPL".equals(statusId)) {
        try {
            Map<String, Object> rollbackCtx = UtilMisc.toMap("userLogin", userLogin, "finAccountId", finAccountId, "statusId", "FNACT_NEGPENDREPL");
            dispatcher.addRollbackService("updateFinAccount", rollbackCtx, true);
        } catch (GenericServiceException e) {
            Debug.logError(e, module);
            return ServiceUtil.returnError(e.getMessage());
        }
    }
    String replenishMethod = finAccountSettings.getString("replenishMethodEnumId");
    BigDecimal depositAmount;
    if (replenishMethod == null || "FARP_TOP_OFF".equals(replenishMethod)) {
        // the deposit is level - balance (500 - (-10) = 510 || 500 - (10) = 490)
        depositAmount = replenishLevel.subtract(balance);
    } else if ("FARP_REPLENISH_LEVEL".equals(replenishMethod)) {
        // the deposit is replenish-level itself
        depositAmount = replenishLevel;
    } else {
        return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "AccountingFinAccountUnknownReplenishMethod", locale));
    }
    // get the owner party
    String ownerPartyId = finAccount.getString("ownerPartyId");
    if (ownerPartyId == null) {
        // no owner cannot replenish; (not fatal, just not supported by this account)
        Debug.logWarning("finAccountReplenish Warning: No owner attached to financial account [" + finAccountId + "] cannot auto-replenish", module);
        return ServiceUtil.returnSuccess();
    }
    // get the payment method to use to replenish
    String paymentMethodId = finAccount.getString("replenishPaymentId");
    if (paymentMethodId == null) {
        Debug.logWarning("finAccountReplenish Warning: No payment method (replenishPaymentId) attached to financial account [" + finAccountId + "] cannot auto-replenish", module);
        return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "AccountingFinAccountNoPaymentMethodAssociatedWithReplenishAccount", locale));
    }
    GenericValue paymentMethod;
    try {
        paymentMethod = EntityQuery.use(delegator).from("PaymentMethod").where("paymentMethodId", paymentMethodId).queryOne();
    } catch (GenericEntityException e) {
        Debug.logError(e, module);
        return ServiceUtil.returnError(e.getMessage());
    }
    if (paymentMethod == null) {
        // no payment methods on file; cannot replenish
        Debug.logWarning("finAccountReplenish Warning: No payment method found for ID [" + paymentMethodId + "] for party [" + ownerPartyId + "] cannot auto-replenish", module);
        return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "AccountingFinAccountNoPaymentMethodAssociatedWithReplenishAccount", locale));
    }
    // hit the payment method for the amount to replenish
    Map<String, BigDecimal> orderItemMap = UtilMisc.toMap("Auto-Replenishment FA #" + finAccountId, depositAmount);
    Map<String, Object> replOrderCtx = new HashMap<>();
    replOrderCtx.put("productStoreId", productStoreId);
    replOrderCtx.put("paymentMethodId", paymentMethod.getString("paymentMethodId"));
    replOrderCtx.put("currency", currency);
    replOrderCtx.put("partyId", ownerPartyId);
    replOrderCtx.put("itemMap", orderItemMap);
    replOrderCtx.put("userLogin", userLogin);
    Map<String, Object> replResp;
    try {
        replResp = dispatcher.runSync("createSimpleNonProductSalesOrder", replOrderCtx);
    } catch (GenericServiceException e) {
        Debug.logError(e, module);
        return ServiceUtil.returnError(e.getMessage());
    }
    if (ServiceUtil.isError(replResp)) {
        return ServiceUtil.returnError(ServiceUtil.getErrorMessage(replResp));
    }
    String orderId = (String) replResp.get("orderId");
    // create the deposit
    Map<String, Object> depositCtx = new HashMap<>();
    depositCtx.put("productStoreId", productStoreId);
    depositCtx.put("finAccountId", finAccountId);
    depositCtx.put("currency", currency);
    depositCtx.put("partyId", ownerPartyId);
    depositCtx.put("orderId", orderId);
    // always one item on a replish order
    depositCtx.put("orderItemSeqId", "00001");
    depositCtx.put("amount", depositAmount);
    depositCtx.put("reasonEnumId", "FATR_REPLENISH");
    depositCtx.put("userLogin", userLogin);
    try {
        Map<String, Object> depositResp = dispatcher.runSync("finAccountDeposit", depositCtx);
        if (ServiceUtil.isError(depositResp)) {
            return ServiceUtil.returnError(ServiceUtil.getErrorMessage(depositResp));
        }
    } catch (GenericServiceException e) {
        Debug.logError(e, module);
        return ServiceUtil.returnError(e.getMessage());
    }
    // say we are in good standing again
    if ("FNACT_NEGPENDREPL".equals(statusId)) {
        try {
            Map<String, Object> ufaResp = dispatcher.runSync("updateFinAccount", UtilMisc.<String, Object>toMap("finAccountId", finAccountId, "statusId", "FNACT_ACTIVE", "userLogin", userLogin));
            if (ServiceUtil.isError(ufaResp)) {
                return ServiceUtil.returnError(ServiceUtil.getErrorMessage(ufaResp));
            }
        } catch (GenericServiceException e) {
            Debug.logError(e, module);
            return ServiceUtil.returnError(e.getMessage());
        }
    }
    return ServiceUtil.returnSuccess();
}
Also used : Locale(java.util.Locale) GenericValue(org.apache.ofbiz.entity.GenericValue) LocalDispatcher(org.apache.ofbiz.service.LocalDispatcher) Delegator(org.apache.ofbiz.entity.Delegator) HashMap(java.util.HashMap) GenericEntityException(org.apache.ofbiz.entity.GenericEntityException) GenericServiceException(org.apache.ofbiz.service.GenericServiceException) BigDecimal(java.math.BigDecimal)

Example 88 with LocalDispatcher

use of org.apache.ofbiz.service.LocalDispatcher in project ofbiz-framework by apache.

the class FinAccountPaymentServices method finAccountReleaseAuth.

public static Map<String, Object> finAccountReleaseAuth(DispatchContext dctx, Map<String, Object> context) {
    LocalDispatcher dispatcher = dctx.getDispatcher();
    GenericValue userLogin = (GenericValue) context.get("userLogin");
    GenericValue paymentPref = (GenericValue) context.get("orderPaymentPreference");
    Locale locale = (Locale) context.get("locale");
    String err = UtilProperties.getMessage(resourceError, "AccountingFinAccountCannotBeExpired", locale);
    try {
        // expire the related financial authorization transaction
        GenericValue authTransaction = PaymentGatewayServices.getAuthTransaction(paymentPref);
        if (authTransaction == null) {
            return ServiceUtil.returnError(err + UtilProperties.getMessage(resourceError, "AccountingFinAccountCannotFindAuthorization", locale));
        }
        Map<String, Object> input = UtilMisc.toMap("userLogin", userLogin, "finAccountAuthId", authTransaction.get("referenceNum"));
        Map<String, Object> serviceResults = dispatcher.runSync("expireFinAccountAuth", input);
        // if there's an error, don't release
        if (ServiceUtil.isError(serviceResults)) {
            return ServiceUtil.returnError(err + ServiceUtil.getErrorMessage(serviceResults));
        }
        Map<String, Object> result = ServiceUtil.returnSuccess();
        result.put("releaseRefNum", authTransaction.getString("referenceNum"));
        result.put("releaseAmount", authTransaction.getBigDecimal("amount"));
        result.put("releaseResult", Boolean.TRUE);
        return result;
    } catch (GenericServiceException e) {
        Debug.logError(e, e.getMessage(), module);
        return ServiceUtil.returnError(err + e.getMessage());
    }
}
Also used : Locale(java.util.Locale) GenericValue(org.apache.ofbiz.entity.GenericValue) LocalDispatcher(org.apache.ofbiz.service.LocalDispatcher) GenericServiceException(org.apache.ofbiz.service.GenericServiceException)

Example 89 with LocalDispatcher

use of org.apache.ofbiz.service.LocalDispatcher in project ofbiz-framework by apache.

the class FinAccountPaymentServices method finAccountCapture.

public static Map<String, Object> finAccountCapture(DispatchContext dctx, Map<String, Object> context) {
    LocalDispatcher dispatcher = dctx.getDispatcher();
    Delegator delegator = dctx.getDelegator();
    Locale locale = (Locale) context.get("locale");
    GenericValue orderPaymentPreference = (GenericValue) context.get("orderPaymentPreference");
    GenericValue userLogin = (GenericValue) context.get("userLogin");
    GenericValue authTrans = (GenericValue) context.get("authTrans");
    BigDecimal amount = (BigDecimal) context.get("captureAmount");
    String currency = (String) context.get("currency");
    // get the authorization transaction
    if (authTrans == null) {
        authTrans = PaymentGatewayServices.getAuthTransaction(orderPaymentPreference);
    }
    if (authTrans == null) {
        return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "AccountingFinAccountCannotCapture", locale));
    }
    // get the auth record
    String finAccountAuthId = authTrans.getString("referenceNum");
    GenericValue finAccountAuth;
    try {
        finAccountAuth = EntityQuery.use(delegator).from("FinAccountAuth").where("finAccountAuthId", finAccountAuthId).queryOne();
    } catch (GenericEntityException e) {
        Debug.logError(e, module);
        return ServiceUtil.returnError(e.getMessage());
    }
    Debug.logInfo("Financial account capture [" + finAccountAuth.get("finAccountId") + "] for the amount of $" + amount + " Tx #" + finAccountAuth.get("finAccountAuthId"), module);
    // get the financial account
    GenericValue finAccount;
    try {
        finAccount = finAccountAuth.getRelatedOne("FinAccount", false);
    } catch (GenericEntityException e) {
        Debug.logError(e, module);
        return ServiceUtil.returnError(e.getMessage());
    }
    // make sure authorization has not expired
    Timestamp authExpiration = finAccountAuth.getTimestamp("thruDate");
    if ((authExpiration != null) && (authExpiration.before(UtilDateTime.nowTimestamp()))) {
        return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "AccountingFinAccountAuthorizationExpired", UtilMisc.toMap("paymentGatewayResponseId", authTrans.getString("paymentGatewayResponseId"), "authExpiration", authExpiration), locale));
    }
    // make sure the fin account itself has not expired
    if ((finAccount.getTimestamp("thruDate") != null) && (finAccount.getTimestamp("thruDate").before(UtilDateTime.nowTimestamp()))) {
        return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "AccountingFinAccountExpired", UtilMisc.toMap("thruDate", finAccount.getTimestamp("thruDate")), locale));
    }
    String finAccountId = finAccount.getString("finAccountId");
    // need the product store ID & party ID
    String orderId = orderPaymentPreference.getString("orderId");
    String productStoreId = null;
    String partyId = null;
    if (orderId != null) {
        OrderReadHelper orh = new OrderReadHelper(delegator, orderId);
        productStoreId = orh.getProductStoreId();
        GenericValue billToParty = orh.getBillToParty();
        if (billToParty != null) {
            partyId = billToParty.getString("partyId");
        }
    }
    // BIG NOTE: make sure the expireFinAccountAuth and finAccountWithdraw services are done in the SAME TRANSACTION
    // (i.e. no require-new-transaction in either of them AND no running async)
    // cancel the authorization before doing the withdraw to avoid problems with way negative available amount on account; should happen in same transaction to avoid conflict problems
    Map<String, Object> releaseResult;
    try {
        releaseResult = dispatcher.runSync("expireFinAccountAuth", UtilMisc.<String, Object>toMap("userLogin", userLogin, "finAccountAuthId", finAccountAuthId));
        if (ServiceUtil.isError(releaseResult)) {
            return ServiceUtil.returnError(ServiceUtil.getErrorMessage(releaseResult));
        }
    } catch (GenericServiceException e) {
        Debug.logError(e, module);
        return ServiceUtil.returnError(e.getMessage());
    }
    // build the withdraw context
    Map<String, Object> withdrawCtx = new HashMap<>();
    withdrawCtx.put("finAccountId", finAccountId);
    withdrawCtx.put("productStoreId", productStoreId);
    withdrawCtx.put("currency", currency);
    withdrawCtx.put("partyId", partyId);
    withdrawCtx.put("orderId", orderId);
    withdrawCtx.put("amount", amount);
    withdrawCtx.put("reasonEnumId", "FATR_PURCHASE");
    // for captures; if auth passed, allow
    withdrawCtx.put("requireBalance", Boolean.FALSE);
    withdrawCtx.put("userLogin", userLogin);
    // call the withdraw service
    Map<String, Object> withdrawResp;
    try {
        withdrawResp = dispatcher.runSync("finAccountWithdraw", withdrawCtx);
    } catch (GenericServiceException e) {
        Debug.logError(e, module);
        return ServiceUtil.returnError(e.getMessage());
    }
    if (ServiceUtil.isError(withdrawResp)) {
        return ServiceUtil.returnError(ServiceUtil.getErrorMessage(withdrawResp));
    }
    // create the capture response
    Map<String, Object> result = ServiceUtil.returnSuccess();
    Boolean processResult = (Boolean) withdrawResp.get("processResult");
    BigDecimal withdrawAmount = (BigDecimal) withdrawResp.get("amount");
    String referenceNum = (String) withdrawResp.get("referenceNum");
    result.put("captureResult", processResult);
    result.put("captureRefNum", referenceNum);
    result.put("captureCode", "C");
    result.put("captureFlag", "1");
    result.put("captureAmount", withdrawAmount);
    return result;
}
Also used : Locale(java.util.Locale) GenericValue(org.apache.ofbiz.entity.GenericValue) LocalDispatcher(org.apache.ofbiz.service.LocalDispatcher) HashMap(java.util.HashMap) Timestamp(java.sql.Timestamp) BigDecimal(java.math.BigDecimal) OrderReadHelper(org.apache.ofbiz.order.order.OrderReadHelper) Delegator(org.apache.ofbiz.entity.Delegator) GenericEntityException(org.apache.ofbiz.entity.GenericEntityException) GenericServiceException(org.apache.ofbiz.service.GenericServiceException)

Example 90 with LocalDispatcher

use of org.apache.ofbiz.service.LocalDispatcher in project ofbiz-framework by apache.

the class FinAccountPaymentServices method finAccountWithdraw.

// base account transaction services
public static Map<String, Object> finAccountWithdraw(DispatchContext dctx, Map<String, Object> context) {
    LocalDispatcher dispatcher = dctx.getDispatcher();
    Delegator delegator = dctx.getDelegator();
    Locale locale = (Locale) context.get("locale");
    GenericValue userLogin = (GenericValue) context.get("userLogin");
    String productStoreId = (String) context.get("productStoreId");
    String finAccountId = (String) context.get("finAccountId");
    String orderItemSeqId = (String) context.get("orderItemSeqId");
    String reasonEnumId = (String) context.get("reasonEnumId");
    String orderId = (String) context.get("orderId");
    Boolean requireBalance = (Boolean) context.get("requireBalance");
    BigDecimal amount = (BigDecimal) context.get("amount");
    if (requireBalance == null) {
        requireBalance = Boolean.TRUE;
    }
    final String WITHDRAWAL = "WITHDRAWAL";
    String partyId = (String) context.get("partyId");
    if (UtilValidate.isEmpty(partyId)) {
        partyId = "_NA_";
    }
    String currencyUom = (String) context.get("currency");
    if (UtilValidate.isEmpty(currencyUom)) {
        currencyUom = EntityUtilProperties.getPropertyValue("general", "currency.uom.id.default", "USD", delegator);
    }
    // validate the amount
    if (amount.compareTo(BigDecimal.ZERO) < 0) {
        return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "AccountingFinAccountMustBePositive", locale));
    }
    GenericValue finAccount;
    try {
        finAccount = EntityQuery.use(delegator).from("FinAccount").where("finAccountId", finAccountId).queryOne();
    } catch (GenericEntityException e) {
        Debug.logError(e, module);
        return ServiceUtil.returnError(e.getMessage());
    }
    // verify we have a financial account
    if (finAccount == null) {
        return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "AccountingFinAccountNotFound", UtilMisc.toMap("finAccountId", ""), locale));
    }
    // make sure the fin account itself has not expired
    if ((finAccount.getTimestamp("thruDate") != null) && (finAccount.getTimestamp("thruDate").before(UtilDateTime.nowTimestamp()))) {
        return ServiceUtil.returnError(UtilProperties.getMessage(resourceError, "AccountingFinAccountExpired", UtilMisc.toMap("thruDate", finAccount.getTimestamp("thruDate")), locale));
    }
    // check the actual balance (excluding authorized amounts) and create the
    // transaction if it is sufficient
    BigDecimal previousBalance = finAccount.getBigDecimal("actualBalance");
    if (previousBalance == null) {
        previousBalance = FinAccountHelper.ZERO;
    }
    BigDecimal balance;
    String refNum;
    Boolean procResult;
    if (requireBalance && previousBalance.compareTo(amount) < 0) {
        procResult = Boolean.FALSE;
        balance = previousBalance;
        refNum = "N/A";
    } else {
        try {
            refNum = FinAccountPaymentServices.createFinAcctPaymentTransaction(delegator, dispatcher, userLogin, amount, productStoreId, partyId, orderId, orderItemSeqId, currencyUom, WITHDRAWAL, finAccountId, reasonEnumId);
            finAccount.refresh();
            balance = finAccount.getBigDecimal("actualBalance");
            procResult = Boolean.TRUE;
        } catch (GeneralException e) {
            Debug.logError(e, module);
            return ServiceUtil.returnError(e.getMessage());
        }
    }
    // make sure balance is not null
    if (balance == null) {
        balance = FinAccountHelper.ZERO;
    }
    Map<String, Object> result = ServiceUtil.returnSuccess();
    result.put("previousBalance", previousBalance);
    result.put("balance", balance);
    result.put("amount", amount);
    result.put("processResult", procResult);
    result.put("referenceNum", refNum);
    return result;
}
Also used : Locale(java.util.Locale) GenericValue(org.apache.ofbiz.entity.GenericValue) LocalDispatcher(org.apache.ofbiz.service.LocalDispatcher) GeneralException(org.apache.ofbiz.base.util.GeneralException) Delegator(org.apache.ofbiz.entity.Delegator) GenericEntityException(org.apache.ofbiz.entity.GenericEntityException) BigDecimal(java.math.BigDecimal)

Aggregations

LocalDispatcher (org.apache.ofbiz.service.LocalDispatcher)427 GenericValue (org.apache.ofbiz.entity.GenericValue)356 Delegator (org.apache.ofbiz.entity.Delegator)324 GenericServiceException (org.apache.ofbiz.service.GenericServiceException)321 Locale (java.util.Locale)296 GenericEntityException (org.apache.ofbiz.entity.GenericEntityException)270 HashMap (java.util.HashMap)214 BigDecimal (java.math.BigDecimal)135 GeneralException (org.apache.ofbiz.base.util.GeneralException)87 Timestamp (java.sql.Timestamp)81 LinkedList (java.util.LinkedList)79 IOException (java.io.IOException)59 Map (java.util.Map)51 HttpSession (javax.servlet.http.HttpSession)49 OrderReadHelper (org.apache.ofbiz.order.order.OrderReadHelper)28 ModelService (org.apache.ofbiz.service.ModelService)28 EntityCondition (org.apache.ofbiz.entity.condition.EntityCondition)24 ShoppingCart (org.apache.ofbiz.order.shoppingcart.ShoppingCart)23 Security (org.apache.ofbiz.security.Security)20 ByteBuffer (java.nio.ByteBuffer)19