📄 orderreturnservices.java
字号:
Iterator itemByOrderIt = itemSet.iterator(); while (itemByOrderIt.hasNext()) { Map.Entry entry = (Map.Entry) itemByOrderIt.next(); String orderId = (String) entry.getKey(); List items = (List) entry.getValue(); Double orderTotal = (Double) totalByOrder.get(orderId); // get order header & payment prefs GenericValue orderHeader = null; List orderPayPrefs = null; try { orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); // sort these desending by maxAmount orderPayPrefs = orderHeader.getRelated("OrderPaymentPreference", null, UtilMisc.toList("-maxAmount")); } catch (GenericEntityException e) { Debug.logError(e, "Cannot get Order details for #" + orderId, module); continue; } // get the payment prefs to use (will use them in order of amount charged) List prefsToUse = new ArrayList(); Map prefsAmount = new HashMap(); double neededAmount = orderTotal.doubleValue(); if (orderPayPrefs != null && orderPayPrefs.size() > 0) { Iterator payPrefIter = orderPayPrefs.iterator(); do { GenericValue pref = (GenericValue) payPrefIter.next(); Double maxAmount = pref.getDouble("maxAmount"); String statusId = pref.getString("statusId"); Debug.logInfo("maxAmount:" + maxAmount +", statusId:" + statusId, module); if ("PAYMENT_SETTLED".equals(statusId)) { if (maxAmount == null || maxAmount.doubleValue() == 0.00) { prefsToUse.add(pref); prefsAmount.put(pref, orderTotal); neededAmount = 0.00; } else if (maxAmount.doubleValue() > orderTotal.doubleValue()) { prefsToUse.add(pref); prefsAmount.put(pref, orderTotal); neededAmount = 0.00; } else { prefsToUse.add(pref); if (maxAmount.doubleValue() > neededAmount) { prefsAmount.put(pref, new Double(maxAmount.doubleValue() - neededAmount)); } else { prefsAmount.put(pref, maxAmount); } neededAmount -= maxAmount.doubleValue(); } } } while (neededAmount > 0 && payPrefIter.hasNext()); } if (neededAmount != 0) { Debug.logError("Was not able to find needed payment preferences for the order RTN: " + returnId + " ORD: " + orderId, module); return ServiceUtil.returnError("Unable to refund order #" + orderId + "; there are no available payment preferences."); } Map prefSplitMap = new HashMap(); if (prefsToUse == null || prefsToUse.size() == 0) { Debug.logError("We didn't find any possible payment prefs to use for RTN: " + returnId + " ORD: " + orderId, module); return ServiceUtil.returnError("Unable to refund order #" + orderId + "; there are no available payment preferences."); } else if (prefsToUse.size() > 1) { // we need to spit the items up to log which pref it was refunded to // TODO: add the split of items for multiple payment prefs } else { // single payment / single refund prefSplitMap.put(prefsToUse.get(0), items); } // now process all items for each preference Set prefItemSet = prefSplitMap.entrySet(); Iterator prefItemIt = prefItemSet.iterator(); while (prefItemIt.hasNext()) { Map.Entry prefItemEntry = (Map.Entry) prefItemIt.next(); GenericValue orderPayPref = (GenericValue) prefItemEntry.getKey(); List itemList = (List) prefItemEntry.getValue(); // Get the refund amount as a BigDecimal due to rounding issues (the createReturnItemResponse simple method will turn 203.37999999999997 into 203.37) BigDecimal thisRefundAmount = ZERO; Double thisRefundAmountDouble = (Double) prefsAmount.get(orderPayPref); if (thisRefundAmountDouble != null) thisRefundAmount = new BigDecimal(thisRefundAmountDouble.doubleValue()); thisRefundAmount = thisRefundAmount.setScale(decimals, rounding); String paymentId = null; // this can be extended to support additional electronic types List electronicTypes = UtilMisc.toList("CREDIT_CARD", "EFT_ACCOUNT", "GIFT_CARD"); //List electronicTypes = new ArrayList(); if (electronicTypes.contains(orderPayPref.getString("paymentMethodTypeId"))) { // call the refund service to refund the payment try { serviceResult = dispatcher.runSync("refundPayment", UtilMisc.toMap("orderPaymentPreference", orderPayPref, "refundAmount", new Double(thisRefundAmount.doubleValue()), "userLogin", userLogin)); if (ServiceUtil.isError(serviceResult)) { return ServiceUtil.returnError("Error in refund payment", null, null, serviceResult); } paymentId = (String) serviceResult.get("paymentId"); } catch (GenericServiceException e) { Debug.logError(e, "Problem running the refundPayment service", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemsWithTheRefundSeeLogs", locale)); } } else { // TODO: handle manual refunds (accounts payable) } //Debug.log("Finished handing refund payments", module); // now; for all timestamps Timestamp now = UtilDateTime.nowTimestamp(); // fill out the data for the new ReturnItemResponse Map response = FastMap.newInstance(); response.put("orderPaymentPreferenceId", orderPayPref.getString("orderPaymentPreferenceId")); response.put("responseAmount", new Double(thisRefundAmount.doubleValue())); response.put("responseDate", now); response.put("userLogin", userLogin); if (paymentId != null) { // a null payment ID means no electronic refund was available; manual refund needed response.put("paymentId", paymentId); } Map serviceResults = null; try { serviceResults = dispatcher.runSync("createReturnItemResponse", response); if (ServiceUtil.isError(serviceResults)) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemsCreatingReturnItemResponseEntity", locale), null, null, serviceResults); } } catch (GenericServiceException e) { Debug.logError(e, "Problems creating new ReturnItemResponse entity", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemsCreatingReturnItemResponseEntity", locale)); } String responseId = (String) serviceResults.get("returnItemResponseId"); // set the response on each item Iterator itemsIter = itemList.iterator(); while (itemsIter.hasNext()) { GenericValue item = (GenericValue) itemsIter.next(); item.set("returnItemResponseId", responseId); item.set("statusId", "RETURN_COMPLETED"); // create the status history String returnStatusId = delegator.getNextSeqId("ReturnStatus"); GenericValue returnStatus = delegator.makeValue("ReturnStatus", UtilMisc.toMap("returnStatusId", returnStatusId)); returnStatus.set("statusId", item.get("statusId")); returnStatus.set("returnId", item.get("returnId")); returnStatus.set("returnItemSeqId", item.get("returnItemSeqId")); returnStatus.set("statusDatetime", now); //Debug.log("Updating item status", module); try { item.store(); delegator.create(returnStatus); } catch (GenericEntityException e) { Debug.logError("Problem updating the ReturnItem entity", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemUpdatingReturnItemReturnItemResponseId", locale)); } //Debug.log("Item status and return status history created", module); } // create the payment applications for the return invoice try { serviceResults = dispatcher.runSync("createPaymentApplicationsFromReturnItemResponse", UtilMisc.toMap("returnItemResponseId", responseId, "userLogin", userLogin)); if (ServiceUtil.isError(serviceResults)) { return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemUpdatingReturnItemReturnItemResponseId", locale), null, null, serviceResults); } } catch (GenericServiceException e) { Debug.logError(e, "Problem creating PaymentApplication records for return invoice", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemUpdatingReturnItemReturnItemResponseId", locale)); } } } } return ServiceUtil.returnSuccess(); } public static Map createPaymentApplicationsFromReturnItemResponse(DispatchContext dctx, Map context) { LocalDispatcher dispatcher = dctx.getDispatcher(); GenericDelegator delegator = dctx.getDelegator(); GenericValue userLogin = (GenericValue) context.get("userLogin"); // the strategy for this service is to get a list of return invoices via the return items -> return item billing relationships // then split up the responseAmount among the invoices evenly String responseId = (String) context.get("returnItemResponseId"); String errorMsg = "Failed to create payment applications for return item response [" + responseId + "]. "; try { GenericValue response = delegator.findByPrimaryKey("ReturnItemResponse", UtilMisc.toMap("returnItemResponseId", responseId)); if (response == null) { return ServiceUtil.returnError(errorMsg + "Return Item Response not found with ID [" + responseId + "]."); } BigDecimal responseAmount = response.getBigDecimal("responseAmount").setScale(decimals, rounding); String paymentId = response.getString("paymentId"); // for each return item in the response, get the list of return item billings and then a list of invoices Map returnInvoices = FastMap.newInstance(); // key is invoiceId, value is Invoice GenericValue List items = response.getRelated("ReturnItem"); for (Iterator itemIter = items.iterator(); itemIter.hasNext(); ) { GenericValue item = (GenericValue) itemIter.next(); List billings = item.getRelated("ReturnItemBilling"); for (Iterator billIter = billings.iterator(); billIter.hasNext(); ) { GenericValue billing = (GenericValue) billIter.next(); GenericValue invoice = billing.getRelatedOne("Invoice"); // put the invoice in the map if it doesn't already exist (a very loopy way of doing group by invoiceId without creating a view) if (returnInvoices.get(invoice.getString("invoiceId")) == null) { returnInvoices.put(invoice.getString("invoiceId"), invoice); } } } // for each return invoice found, sum up the related billings Map invoiceTotals = FastMap.newInstance(); // key is invoiceId, value is the sum of all billings for that invoice BigDecimal grandTotal = ZERO; // The sum of all return invoice totals for (Iterator iter = returnInvoices.values().iterator(); iter.hasNext(); ) { GenericValue invoice = (GenericValue) iter.next(); List billings = invoice.getRelated("ReturnItemBilling"); BigDecimal runningTotal = ZERO; for (Iterator billIter = billings.iterator(); billIter.hasNext(); ) { GenericValue billing = (GenericValue) billIter.next(); runningTotal = runningTotal.add(billing.getBigDecimal("amount").multiply(billing.getBigDecimal("quantity")).setScale(decimals, rounding)); } invoiceTotals.put(invoice.getString("invoiceId"), runningTotal); grandTotal = grandTotal.add(runningTotal); } // now allocate responseAmount * invoiceTotal / grandTotal to each invoice for (Iterator iter = returnInvoices.values().iterator(); iter.hasNext(); ) { GenericValue invoice = (GenericValue) iter.next(); String invoiceId = invoice.getString("invoiceId"); BigDecimal invoiceTotal = (BigDecimal) invoiceTotals.get(invoiceId); BigDecimal amountApplied = responseAmount.multiply(invoiceTotal).divide(grandTotal, decimals, rounding).setScale(decimals, rounding); if (paymentId != null) { // create a payment application for the invoice Map input = UtilMisc.toMap("paymentId", paymentId, "invoiceId", invoice.getString("invoiceId")); input.put("amountApplied", new Double(amountApplied.doubleValue())); input.put("userLogin", userLogin); Map serviceResults = dispatcher.runSync("createPaymentApplication", input); if (ServiceUtil.isError(serviceResults)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -