1 2 package org.ofbiz.order.order; 3 4 import java.math.BigDecimal ; 5 import java.sql.Timestamp ; 6 import java.util.ArrayList ; 7 import java.util.HashMap ; 8 import java.util.Iterator ; 9 import java.util.LinkedList ; 10 import java.util.List ; 11 import java.util.Locale ; 12 import java.util.Map ; 13 import java.util.Set ; 14 15 import javolution.util.FastMap; 16 17 import org.ofbiz.base.util.Debug; 18 import org.ofbiz.base.util.GeneralRuntimeException; 19 import org.ofbiz.base.util.UtilDateTime; 20 import org.ofbiz.base.util.UtilMisc; 21 import org.ofbiz.base.util.UtilNumber; 22 import org.ofbiz.base.util.UtilProperties; 23 import org.ofbiz.base.util.UtilValidate; 24 import org.ofbiz.base.util.collections.ResourceBundleMapWrapper; 25 import org.ofbiz.entity.GenericDelegator; 26 import org.ofbiz.entity.GenericEntityException; 27 import org.ofbiz.entity.GenericValue; 28 import org.ofbiz.entity.util.EntityUtil; 29 import org.ofbiz.product.store.ProductStoreWorker; 30 import org.ofbiz.service.DispatchContext; 31 import org.ofbiz.service.GenericServiceException; 32 import org.ofbiz.service.LocalDispatcher; 33 import org.ofbiz.service.ModelParam; 34 import org.ofbiz.service.ModelService; 35 import org.ofbiz.service.ServiceUtil; 36 37 44 public class OrderReturnServices { 45 46 public static final String module = OrderReturnServices.class.getName(); 47 public static final String resource = "OrderUiLabels"; 48 public static final String resource_error = "OrderErrorUiLabels"; 49 50 private static BigDecimal ZERO = new BigDecimal ("0"); 52 private static int decimals = -1; 53 private static int rounding = -1; 54 static { 55 decimals = UtilNumber.getBigDecimalScale("invoice.decimals"); 56 rounding = UtilNumber.getBigDecimalRoundingMode("invoice.rounding"); 57 58 if (decimals != -1) ZERO.setScale(decimals); 60 } 61 62 public static Map getReturnItemInitialCost(DispatchContext dctx, Map context) { 64 GenericDelegator delegator = dctx.getDelegator(); 65 String returnId = (String ) context.get("returnId"); 66 String returnItemSeqId = (String ) context.get("returnItemSeqId"); 67 68 Map result = ServiceUtil.returnSuccess(); 69 result.put("initialItemCost", getReturnItemInitialCost(delegator, returnId, returnItemSeqId)); 70 return result; 71 } 72 73 public static Map getOrderAvailableReturnedTotal(DispatchContext dctx, Map context) { 75 GenericDelegator delegator = dctx.getDelegator(); 76 String orderId = (String ) context.get("orderId"); 77 OrderReadHelper orh = null; 78 try { 79 orh = new OrderReadHelper(delegator, orderId); 80 } catch (IllegalArgumentException e) { 81 return ServiceUtil.returnError(e.getMessage()); 82 } 83 84 Double adj = (Double ) context.get("adjustment"); 86 if (adj == null) { 87 adj = new Double (0); 88 } 89 90 Boolean countNewReturnItems = (Boolean ) context.get("countNewReturnItems"); 91 if (countNewReturnItems == null) { 92 countNewReturnItems = Boolean.FALSE; 93 } 94 double returnTotal = orh.getOrderReturnedTotal(countNewReturnItems.booleanValue()); 95 double orderTotal = orh.getOrderGrandTotal(); 96 double available = orderTotal - returnTotal - adj.doubleValue(); 97 98 99 Map result = ServiceUtil.returnSuccess(); 100 result.put("availableReturnTotal", new Double (available)); 101 result.put("orderTotal", new Double (orderTotal)); 102 result.put("returnTotal", new Double (returnTotal)); 103 return result; 104 } 105 106 public static Double getReturnItemInitialCost(GenericDelegator delegator, String returnId, String returnItemSeqId) { 108 if (delegator == null || returnId == null || returnItemSeqId == null) { 109 throw new IllegalArgumentException ("Method parameters cannot contain nulls"); 110 } 111 Debug.log("Finding the initial item cost for return item : " + returnId + " / " + returnItemSeqId, module); 112 113 Double itemCost = new Double (0.00); 115 116 GenericValue returnItem = null; 118 try { 119 returnItem = delegator.findByPrimaryKey("ReturnItem", UtilMisc.toMap("returnId", returnId, "returnItemSeqId", returnItemSeqId)); 120 } catch (GenericEntityException e) { 121 Debug.logError(e, module); 122 throw new GeneralRuntimeException(e.getMessage()); 123 } 124 Debug.log("Return item value object - " + returnItem, module); 125 126 if (returnItem != null) { 128 String orderId = returnItem.getString("orderId"); 129 String orderItemSeqId = returnItem.getString("orderItemSeqId"); 130 if (orderItemSeqId != null && orderId != null) { 131 Debug.log("Found order item reference", module); 132 List itemIssue = null; 134 try { 135 itemIssue = delegator.findByAnd("ItemIssuance", UtilMisc.toMap("orderId", orderId, "orderItemSeqId", orderItemSeqId)); 136 } catch (GenericEntityException e) { 137 Debug.logError(e, module); 138 throw new GeneralRuntimeException(e.getMessage()); 139 } 140 if (itemIssue != null && itemIssue.size() > 0) { 141 Debug.log("Found item issuance referece", module); 142 GenericValue issue = EntityUtil.getFirst(itemIssue); 145 GenericValue inventoryItem = null; 146 try { 147 inventoryItem = issue.getRelatedOne("InventoryItem"); 148 } catch (GenericEntityException e) { 149 Debug.logError(e, module); 150 throw new GeneralRuntimeException(e.getMessage()); 151 } 152 if (inventoryItem != null) { 153 Debug.log("Located inventory item - " + inventoryItem.getString("inventoryItemId"), module); 154 if (inventoryItem.get("unitCost") != null) { 155 itemCost = inventoryItem.getDouble("unitCost"); 156 } else { 157 Debug.logInfo("Found item cost; but cost was null. Returning default amount (0.00)", module); 158 } 159 } 160 } 161 } 162 } 163 164 Debug.log("Initial item cost - " + itemCost, module); 165 return itemCost; 166 } 167 168 private static Map sendReturnNotificationScreen(DispatchContext dctx, Map context, String emailType) { 170 GenericDelegator delegator = dctx.getDelegator(); 171 LocalDispatcher dispatcher = dctx.getDispatcher(); 172 GenericValue userLogin = (GenericValue) context.get("userLogin"); 173 String returnId = (String ) context.get("returnId"); 174 Locale locale = (Locale ) context.get("locale"); 175 176 GenericValue returnHeader = null; 178 try { 179 returnHeader = delegator.findByPrimaryKey("ReturnHeader", UtilMisc.toMap("returnId", returnId)); 180 } catch (GenericEntityException e) { 181 Debug.logError(e, module); 182 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorUnableToGetReturnHeaderForID", UtilMisc.toMap("returnId",returnId), locale)); 183 } 184 185 List returnItems = null; 187 try { 188 returnItems = returnHeader.getRelated("ReturnItem"); 189 } catch (GenericEntityException e) { 190 Debug.logError(e, module); 191 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorUnableToGetReturnItemRecordsFromReturnHeader", locale)); 192 } 193 194 String productStoreId = null; 196 String emailAddress = null; 197 if (returnItems != null && returnItems.size() > 0) { 198 GenericValue firstItem = EntityUtil.getFirst(returnItems); 199 GenericValue orderHeader = null; 200 try { 201 orderHeader = firstItem.getRelatedOne("OrderHeader"); 202 } catch (GenericEntityException e) { 203 Debug.logError(e, module); 204 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorUnableToGetOrderHeaderFromReturnItem", locale)); 205 } 206 207 if (orderHeader != null && UtilValidate.isNotEmpty(orderHeader.getString("productStoreId"))) { 208 OrderReadHelper orh = new OrderReadHelper(orderHeader); 209 productStoreId = orh.getProductStoreId(); 210 emailAddress = orh.getOrderEmailString(); 211 } 212 } 213 214 if (productStoreId != null && productStoreId.length() > 0) { 216 Map sendMap = FastMap.newInstance(); 217 218 GenericValue productStoreEmail = null; 219 try { 220 productStoreEmail = delegator.findByPrimaryKey("ProductStoreEmailSetting", UtilMisc.toMap("productStoreId", productStoreId, "emailType", emailType)); 221 } catch (GenericEntityException e) { 222 Debug.logError(e, module); 223 } 224 225 if (productStoreEmail != null && emailAddress != null) { 226 String bodyScreenLocation = productStoreEmail.getString("bodyScreenLocation"); 227 if (UtilValidate.isEmpty(bodyScreenLocation)) { 228 bodyScreenLocation = (String ) ProductStoreWorker.getDefaultProductStoreEmailScreenLocation(emailType); 229 } 230 sendMap.put("bodyScreenUri", bodyScreenLocation); 231 232 ResourceBundleMapWrapper uiLabelMap = (ResourceBundleMapWrapper) UtilProperties.getResourceBundleMap("EcommerceUiLabels", locale); 233 uiLabelMap.addBottomResourceBundle("OrderUiLabels"); 234 uiLabelMap.addBottomResourceBundle("CommonUiLabels"); 235 236 Map bodyParameters = UtilMisc.toMap("returnHeader", returnHeader, "returnItems", returnItems, "uiLabelMap", uiLabelMap, "locale", locale); 237 sendMap.put("bodyParameters", bodyParameters); 238 239 sendMap.put("subject", productStoreEmail.getString("subject")); 240 sendMap.put("contentType", productStoreEmail.get("contentType")); 241 sendMap.put("sendFrom", productStoreEmail.get("fromAddress")); 242 sendMap.put("sendCc", productStoreEmail.get("ccAddress")); 243 sendMap.put("sendBcc", productStoreEmail.get("bccAddress")); 244 sendMap.put("sendTo", emailAddress); 245 246 sendMap.put("userLogin", userLogin); 247 248 Map sendResp = null; 249 try { 250 sendResp = dispatcher.runSync("sendMailFromScreen", sendMap); 251 } catch (GenericServiceException e) { 252 Debug.logError(e, "Problem sending mail", module); 253 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderProblemSendingEmail", locale)); 254 } 255 256 if (sendResp != null && !ServiceUtil.isError(sendResp)) { 258 sendResp.put("emailType", emailType); 259 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderProblemSendingEmail", locale), null, null, sendResp); 260 } 261 return sendResp; 262 } 263 } 264 265 return ServiceUtil.returnFailure("No valid email setting for store"); 266 } 267 268 public static Map sendReturnAcceptNotification(DispatchContext dctx, Map context) { 270 return sendReturnNotificationScreen(dctx, context, "PRDS_RTN_ACCEPT"); 271 } 272 273 public static Map sendReturnCompleteNotification(DispatchContext dctx, Map context) { 275 return sendReturnNotificationScreen(dctx, context, "PRDS_RTN_COMPLETE"); 276 } 277 278 public static Map sendReturnCancelNotification(DispatchContext dctx, Map context) { 280 return sendReturnNotificationScreen(dctx, context, "PRDS_RTN_CANCEL"); 281 } 282 283 public static Map getReturnableQuantity(DispatchContext dctx, Map context) { 285 GenericDelegator delegator = dctx.getDelegator(); 286 GenericValue orderItem = (GenericValue) context.get("orderItem"); 287 GenericValue product = null; 288 Locale locale = (Locale ) context.get("locale"); 289 if (orderItem.get("productId") != null) { 290 try { 291 product = orderItem.getRelatedOne("Product"); 292 } catch (GenericEntityException e) { 293 Debug.logError(e, "ERROR: Unable to get Product from OrderItem", module); 294 } 295 } 296 297 boolean returnable = true; 299 300 if (product != null && product.get("returnable") != null && 302 "N".equalsIgnoreCase(product.getString("returnable"))) { 303 returnable = false; 305 } 306 307 if (product != null && product.get("supportDiscontinuationDate") != null && 309 !UtilDateTime.nowTimestamp().before(product.getTimestamp("supportDiscontinuationDate"))) { 310 returnable = false; 312 } 313 314 String itemStatus = orderItem.getString("statusId"); 315 double orderQty = orderItem.getDouble("quantity").doubleValue(); 316 if (orderItem.getDouble("cancelQuantity") != null) { 317 orderQty -= orderItem.getDouble("cancelQuantity").doubleValue(); 318 } 319 320 double returnableQuantity = 0.00; 322 if (returnable && itemStatus.equals("ITEM_COMPLETED")) { 323 List returnedItems = null; 324 try { 325 returnedItems = orderItem.getRelated("ReturnItem"); 326 } catch (GenericEntityException e) { 327 Debug.logError(e, module); 328 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorUnableToGetReturnItemInformation", locale)); 329 } 330 if (returnedItems == null || returnedItems.size() == 0) { 331 returnableQuantity = orderQty; 332 } else { 333 double returnedQty = 0.00; 334 Iterator ri = returnedItems.iterator(); 335 while (ri.hasNext()) { 336 GenericValue returnItem = (GenericValue) ri.next(); 337 GenericValue returnHeader = null; 338 try { 339 returnHeader = returnItem.getRelatedOne("ReturnHeader"); 340 } catch (GenericEntityException e) { 341 Debug.logError(e, module); 342 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorUnableToGetReturnHeaderFromItem", locale)); 343 } 344 String returnStatus = returnHeader.getString("statusId"); 345 if (!returnStatus.equals("RETURN_CANCELLED")) { 346 returnedQty += returnItem.getDouble("returnQuantity").doubleValue(); 347 } 348 } 349 if (returnedQty < orderQty) { 350 returnableQuantity = orderQty - returnedQty; 351 } 352 } 353 } 354 355 357 Map result = ServiceUtil.returnSuccess(); 358 result.put("returnableQuantity", new Double (returnableQuantity)); 359 result.put("returnablePrice", orderItem.get("unitPrice")); 360 return result; 361 } 362 363 public static Map getReturnableItems(DispatchContext dctx, Map context) { 365 LocalDispatcher dispatcher = dctx.getDispatcher(); 366 GenericDelegator delegator = dctx.getDelegator(); 367 String orderId = (String ) context.get("orderId"); 368 Locale locale = (Locale ) context.get("locale"); 369 370 GenericValue orderHeader = null; 371 try { 372 orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); 373 } catch (GenericEntityException e) { 374 Debug.logError(e, module); 375 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorUnableToGetReturnItemInformation", locale)); 376 } 377 378 Map returnable = new HashMap (); 379 if (orderHeader != null) { 380 List orderItems = null; 381 try { 382 orderItems = orderHeader.getRelatedByAnd("OrderItem", UtilMisc.toMap("statusId", "ITEM_COMPLETED")); 383 } catch (GenericEntityException e) { 384 Debug.logError(e, module); 385 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorUnableToGetReturnHeaderFromItem", locale)); 386 } 387 if (orderItems != null) { 388 Iterator i = orderItems.iterator(); 389 while (i.hasNext()) { 390 GenericValue item = (GenericValue) i.next(); 391 Map serviceResult = null; 392 try { 393 serviceResult = dispatcher.runSync("getReturnableQuantity", UtilMisc.toMap("orderItem", item)); 394 } catch (GenericServiceException e) { 395 Debug.logError(e, module); 396 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorUnableToGetTheItemReturnableQuantity", locale)); 397 } 398 if (serviceResult.containsKey(ModelService.ERROR_MESSAGE)) { 399 return ServiceUtil.returnError((String ) serviceResult.get(ModelService.ERROR_MESSAGE)); 400 } else { 401 Map returnInfo = new HashMap (); 402 returnInfo.put("returnableQuantity", serviceResult.get("returnableQuantity")); 404 returnInfo.put("returnablePrice", serviceResult.get("returnablePrice")); 405 406 String itemTypeKey = "FINISHED_GOOD"; GenericValue product = null; 409 if (item.get("productId") != null) { 410 try { 411 product = item.getRelatedOne("Product"); 412 } catch (GenericEntityException e) { 413 Debug.logError(e, module); 414 return ServiceUtil.returnError("Unable to obtain order item information!"); 415 } 416 } 417 if (product != null) { 418 itemTypeKey = product.getString("productTypeId"); 419 } else if (item != null) { 420 itemTypeKey = item.getString("orderItemTypeId"); 421 } 422 returnInfo.put("itemTypeKey", itemTypeKey); 423 424 returnable.put(item, returnInfo); 425 } 426 } 427 } else { 428 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorNoOrderItemsFound", locale)); 429 } 430 } else { 431 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorUnableToFindOrderHeader", locale)); 432 } 433 434 Map result = ServiceUtil.returnSuccess(); 435 result.put("returnableItems", returnable); 436 return result; 437 } 438 439 public static Map checkReturnComplete(DispatchContext dctx, Map context) { 441 GenericDelegator delegator = dctx.getDelegator(); 443 String returnId = (String ) context.get("returnId"); 444 Locale locale = (Locale ) context.get("locale"); 445 446 GenericValue returnHeader = null; 447 List returnItems = null; 448 try { 449 returnHeader = delegator.findByPrimaryKey("ReturnHeader", UtilMisc.toMap("returnId", returnId)); 450 if (returnHeader != null) { 451 returnItems = returnHeader.getRelated("ReturnItem"); 452 } 453 } catch (GenericEntityException e) { 454 Debug.logError(e, "Problems looking up return information", module); 455 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorGettingReturnHeaderItemInformation", locale)); 456 } 457 458 if (returnHeader != null && returnHeader.get("statusId") != null) { 460 String currentStatus = returnHeader.getString("statusId"); 461 if ("RETURN_COMPLETED".equals(currentStatus) || "RETURN_CANCELLED".equals(currentStatus)) { 462 return ServiceUtil.returnSuccess(); 463 } 464 } 465 466 Timestamp now = UtilDateTime.nowTimestamp(); 468 469 List completedItems = new ArrayList (); 470 if (returnHeader != null && returnItems != null && returnItems.size() > 0) { 471 Iterator itemsIter = returnItems.iterator(); 472 while (itemsIter.hasNext()) { 473 GenericValue item = (GenericValue) itemsIter.next(); 474 String itemStatus = item != null ? item.getString("statusId") : null; 475 if (itemStatus != null) { 476 if ("RETURN_COMPLETED".equals(itemStatus) || "RETURN_CANCELLED".equals(itemStatus)) { 478 completedItems.add(item); 479 } 480 } 481 } 482 483 if (completedItems.size() == returnItems.size()) { 485 List toStore = new LinkedList (); 486 returnHeader.set("statusId", "RETURN_COMPLETED"); 487 toStore.add(returnHeader); 488 489 String returnStatusId = delegator.getNextSeqId("ReturnStatus").toString(); 491 GenericValue returnStatus = delegator.makeValue("ReturnStatus", UtilMisc.toMap("returnStatusId", returnStatusId)); 492 returnStatus.set("statusId", "RETURN_COMPLETED"); 493 returnStatus.set("returnId", returnId); 494 returnStatus.set("statusDatetime", now); 495 toStore.add(returnStatus); 496 try { 497 delegator.storeAll(toStore); 498 } catch (GenericEntityException e) { 499 Debug.logError(e, module); 500 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorUnableToCreateReturnStatusHistory", locale)); 501 } 502 } 503 504 } 505 506 Map result = ServiceUtil.returnSuccess(); 507 result.put("statusId", returnHeader.get("statusId")); 508 return result; 509 } 510 511 public static Map processCreditReturn(DispatchContext dctx, Map context) { 513 LocalDispatcher dispatcher = dctx.getDispatcher(); 514 GenericDelegator delegator = dctx.getDelegator(); 515 String returnId = (String ) context.get("returnId"); 516 GenericValue userLogin = (GenericValue) context.get("userLogin"); 517 Locale locale = (Locale ) context.get("locale"); 518 519 GenericValue returnHeader = null; 520 List returnItems = null; 521 try { 522 returnHeader = delegator.findByPrimaryKey("ReturnHeader", UtilMisc.toMap("returnId", returnId)); 523 if (returnHeader != null) { 524 returnItems = returnHeader.getRelatedByAnd("ReturnItem", UtilMisc.toMap("returnTypeId", "RTN_CREDIT")); 525 } 526 } catch (GenericEntityException e) { 527 Debug.logError(e, "Problems looking up return information", module); 528 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorGettingReturnHeaderItemInformation", locale)); 529 } 530 531 if (returnHeader != null && returnItems != null && returnItems.size() > 0) { 532 String billingAccountId = returnHeader.getString("billingAccountId"); 533 String fromPartyId = returnHeader.getString("fromPartyId"); 534 String toPartyId = returnHeader.getString("toPartyId"); 535 536 Map serviceResult = null; 538 try { 539 serviceResult = dispatcher.runSync("checkPaymentAmountForRefund", UtilMisc.toMap("returnId", returnId)); 540 } catch (GenericServiceException e) { 541 Debug.logError(e, "Problem running the checkPaymentAmountForRefund service", module); 542 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemsWithCheckPaymentAmountForRefund", locale)); 543 } 544 if (ServiceUtil.isError(serviceResult)) { 545 return ServiceUtil.returnError(ServiceUtil.getErrorMessage(serviceResult)); 546 } 547 if (billingAccountId == null) { 548 try { 550 Map newBa = dispatcher.runSync("createBillingAccount", UtilMisc.toMap("accountLimit", new Double (0.00), "description", "Credit Account", "userLogin", userLogin, "accountCurrencyUomId", returnHeader.get("currencyUomId"))); 552 if (!newBa.get(ModelService.RESPONSE_MESSAGE).equals(ModelService.RESPOND_ERROR)) { 553 billingAccountId = (String ) newBa.get("billingAccountId"); 554 if (billingAccountId != null) { 555 Map newBaR = dispatcher.runSync("createBillingAccountRole", UtilMisc.toMap("billingAccountId", billingAccountId, "partyId", fromPartyId, "roleTypeId", "BILL_TO_CUSTOMER", "userLogin", userLogin)); 557 if (newBaR.get(ModelService.RESPONSE_MESSAGE).equals(ModelService.RESPOND_ERROR)) { 558 Debug.logError("Error with createBillingAccountRole: " + newBaR.get(ModelService.ERROR_MESSAGE), module); 559 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorWithCreateBillingAccountRole", locale) + newBaR.get(ModelService.ERROR_MESSAGE)); 560 } 561 } 562 } else { 563 Debug.logError("Error with createBillingAccount: " + newBa.get(ModelService.ERROR_MESSAGE), module); 564 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorWithCreateBillingAccount", locale) + newBa.get(ModelService.ERROR_MESSAGE)); 565 } 566 } catch (GenericServiceException e) { 567 Debug.logError(e, "Problems creating BillingAccount", module); 568 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemsCreatingBillingAccount", locale)); 569 } 570 } 571 572 if (billingAccountId == null) { 574 Debug.logError("No available billing account, none was created", module); 575 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderNoAvailableBillingAccount", locale)); 576 } 577 578 Timestamp now = UtilDateTime.nowTimestamp(); 580 581 BigDecimal creditTotal = ZERO; 583 for (Iterator itemsIter = returnItems.iterator(); itemsIter.hasNext(); ) { 584 GenericValue item = (GenericValue) itemsIter.next(); 585 BigDecimal quantity = item.getBigDecimal("returnQuantity"); 586 BigDecimal price = item.getBigDecimal("returnPrice"); 587 if (quantity == null) quantity = ZERO; 588 if (price == null) price = ZERO; 589 creditTotal = creditTotal.add(price.multiply(quantity).setScale(decimals, rounding)); 590 } 591 592 BigDecimal adjustments = new BigDecimal (getReturnAdjustmentTotal(delegator, UtilMisc.toMap("returnId", returnId))); 594 creditTotal = creditTotal.add(adjustments.setScale(decimals, rounding)); 595 596 String paymentId = delegator.getNextSeqId("Payment").toString(); 600 GenericValue payment = delegator.makeValue("Payment", UtilMisc.toMap("paymentId", paymentId)); 601 payment.set("paymentTypeId", "CUSTOMER_REFUND"); 602 payment.set("paymentMethodTypeId", "EXT_BILLACT"); 603 payment.set("partyIdFrom", toPartyId); payment.set("partyIdTo", fromPartyId); 605 payment.set("effectiveDate", now); 606 payment.set("amount", creditTotal); 607 payment.set("comments", "Return Credit"); 608 payment.set("statusId", "PMNT_CONFIRMED"); try { 610 delegator.create(payment); 611 } catch (GenericEntityException e) { 612 Debug.logError(e, "Problem creating Payment record", module); 613 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemCreatingPaymentRecord", locale)); 614 } 615 616 Map itemResponse = UtilMisc.toMap("paymentId", paymentId); 618 itemResponse.put("billingAccountId", billingAccountId); 619 itemResponse.put("responseAmount", new Double (creditTotal.doubleValue())); 620 itemResponse.put("responseDate", now); 621 itemResponse.put("userLogin", userLogin); 622 Map serviceResults = null; 623 try { 624 serviceResults = dispatcher.runSync("createReturnItemResponse", itemResponse); 625 if (ServiceUtil.isError(serviceResults)) { 626 return ServiceUtil.returnError("Could not create ReturnItemResponse record", null, null, serviceResults); 627 } 628 } catch (GenericServiceException e) { 629 Debug.logError(e, "Problem creating ReturnItemResponse record", module); 630 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemCreatingReturnItemResponseRecord", locale)); 631 } 632 633 String itemResponseId = (String ) serviceResults.get("returnItemResponseId"); 635 636 List toBeStored = new ArrayList (); 638 for (Iterator itemsIter = returnItems.iterator(); itemsIter.hasNext(); ) { 639 GenericValue item = (GenericValue) itemsIter.next(); 640 641 item.set("returnItemResponseId", itemResponseId); 643 item.set("statusId", "RETURN_COMPLETED"); 644 toBeStored.add(item); 645 646 String returnStatusId = delegator.getNextSeqId("ReturnStatus").toString(); 648 GenericValue returnStatus = delegator.makeValue("ReturnStatus", UtilMisc.toMap("returnStatusId", returnStatusId)); 649 returnStatus.set("statusId", item.get("statusId")); 650 returnStatus.set("returnId", item.get("returnId")); 651 returnStatus.set("returnItemSeqId", item.get("returnItemSeqId")); 652 returnStatus.set("statusDatetime", now); 653 toBeStored.add(returnStatus); 654 } 655 656 try { 658 delegator.storeAll(toBeStored); 659 } catch (GenericEntityException e) { 660 Debug.logError(e, "Problem storing ReturnItem updates", module); 661 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemStoringReturnItemUpdates", locale)); 662 } 663 664 String paId = delegator.getNextSeqId("PaymentApplication").toString(); 666 GenericValue pa = delegator.makeValue("PaymentApplication", UtilMisc.toMap("paymentApplicationId", paId)); 667 pa.set("paymentId", paymentId); 668 pa.set("billingAccountId", billingAccountId); 669 pa.set("amountApplied", creditTotal); 670 try { 671 delegator.create(pa); 672 } catch (GenericEntityException e) { 673 Debug.logError(e, "Problem creating PaymentApplication record for billing account", module); 674 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemCreatingPaymentApplicationRecord", locale)); 675 } 676 677 try { 679 serviceResults = dispatcher.runSync("createPaymentApplicationsFromReturnItemResponse", 680 UtilMisc.toMap("returnItemResponseId", itemResponseId, "userLogin", userLogin)); 681 if (ServiceUtil.isError(serviceResults)) { 682 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemCreatingPaymentApplicationRecord", locale), null, null, serviceResults); 683 } 684 } catch (GenericServiceException e) { 685 Debug.logError(e, "Problem creating PaymentApplication records for return invoice", module); 686 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemCreatingPaymentApplicationRecord", locale)); 687 } 688 } 689 690 return ServiceUtil.returnSuccess(); 691 } 692 693 public static Map processRefundReturn(DispatchContext dctx, Map context) { 696 GenericDelegator delegator = dctx.getDelegator(); 697 LocalDispatcher dispatcher = dctx.getDispatcher(); 698 String returnId = (String ) context.get("returnId"); 699 GenericValue userLogin = (GenericValue) context.get("userLogin"); 700 Locale locale = (Locale ) context.get("locale"); 701 702 GenericValue returnHeader = null; 703 List returnItems = null; 704 try { 705 returnHeader = delegator.findByPrimaryKey("ReturnHeader", UtilMisc.toMap("returnId", returnId)); 706 if (returnHeader != null) { 707 returnItems = returnHeader.getRelatedByAnd("ReturnItem", UtilMisc.toMap("returnTypeId", "RTN_REFUND")); 708 } 709 } catch (GenericEntityException e) { 710 Debug.logError(e, "Problems looking up return information", module); 711 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorGettingReturnHeaderItemInformation", locale)); 712 } 713 714 if (returnHeader != null && returnItems != null && returnItems.size() > 0) { 715 Map itemsByOrder = new HashMap (); 716 Map totalByOrder = new HashMap (); 717 718 Map serviceResult = null; 720 try { 721 serviceResult = dispatcher.runSync("checkPaymentAmountForRefund", UtilMisc.toMap("returnId", returnId)); 722 } catch (GenericServiceException e){ 723 Debug.logError(e, "Problem running the checkPaymentAmountForRefund service", module); 724 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemsWithCheckPaymentAmountForRefund", locale)); 725 } 726 if (ServiceUtil.isError(serviceResult)) { 727 return ServiceUtil.returnError(ServiceUtil.getErrorMessage(serviceResult)); 728 } 729 730 groupReturnItemsByOrder(returnItems, itemsByOrder, totalByOrder, delegator, returnId); 731 732 Set itemSet = itemsByOrder.entrySet(); 734 Iterator itemByOrderIt = itemSet.iterator(); 735 while (itemByOrderIt.hasNext()) { 736 Map.Entry entry = (Map.Entry ) itemByOrderIt.next(); 737 String orderId = (String ) entry.getKey(); 738 List items = (List ) entry.getValue(); 739 Double orderTotal = (Double ) totalByOrder.get(orderId); 740 741 GenericValue orderHeader = null; 743 List orderPayPrefs = null; 744 try { 745 orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); 746 orderPayPrefs = orderHeader.getRelated("OrderPaymentPreference", null, UtilMisc.toList("-maxAmount")); 748 } catch (GenericEntityException e) { 749 Debug.logError(e, "Cannot get Order details for #" + orderId, module); 750 continue; 751 } 752 753 List prefsToUse = new ArrayList (); 755 Map prefsAmount = new HashMap (); 756 double neededAmount = orderTotal.doubleValue(); 757 if (orderPayPrefs != null && orderPayPrefs.size() > 0) { 758 Iterator payPrefIter = orderPayPrefs.iterator(); 759 do { 760 GenericValue pref = (GenericValue) payPrefIter.next(); 761 Double maxAmount = pref.getDouble("maxAmount"); 762 String statusId = pref.getString("statusId"); 763 Debug.logInfo(" maxAmount:" + maxAmount +", statusId:" + statusId, module); 764 if ("PAYMENT_SETTLED".equals(statusId)) { 765 if (maxAmount == null || maxAmount.doubleValue() == 0.00) { 766 prefsToUse.add(pref); 767 prefsAmount.put(pref, orderTotal); 768 neededAmount = 0.00; 769 } else if (maxAmount.doubleValue() > orderTotal.doubleValue()) { 770 prefsToUse.add(pref); 771 prefsAmount.put(pref, orderTotal); 772 neededAmount = 0.00; 773 } else { 774 prefsToUse.add(pref); 775 if (maxAmount.doubleValue() > neededAmount) { 776 prefsAmount.put(pref, new Double (maxAmount.doubleValue() - neededAmount)); 777 } else { 778 prefsAmount.put(pref, maxAmount); 779 } 780 neededAmount -= maxAmount.doubleValue(); 781 } 782 } 783 } while (neededAmount > 0 && payPrefIter.hasNext()); 784 } 785 if (neededAmount != 0) { 786 Debug.logError("Was not able to find needed payment preferences for the order RTN: " + returnId + " ORD: " + orderId, module); 787 return ServiceUtil.returnError("Unable to refund order #" + orderId + "; there are no available payment preferences."); 788 } 789 790 Map prefSplitMap = new HashMap (); 791 if (prefsToUse == null || prefsToUse.size() == 0) { 792 Debug.logError("We didn't find any possible payment prefs to use for RTN: " + returnId + " ORD: " + orderId, module); 793 return ServiceUtil.returnError("Unable to refund order #" + orderId + "; there are no available payment preferences."); 794 } else if (prefsToUse.size() > 1) { 795 } else { 798 prefSplitMap.put(prefsToUse.get(0), items); 800 } 801 802 Set prefItemSet = prefSplitMap.entrySet(); 804 Iterator prefItemIt = prefItemSet.iterator(); 805 while (prefItemIt.hasNext()) { 806 Map.Entry prefItemEntry = (Map.Entry ) prefItemIt.next(); 807 GenericValue orderPayPref = (GenericValue) prefItemEntry.getKey(); 808 List itemList = (List ) prefItemEntry.getValue(); 809 810 BigDecimal thisRefundAmount = ZERO; 812 Double thisRefundAmountDouble = (Double ) prefsAmount.get(orderPayPref); 813 if (thisRefundAmountDouble != null) thisRefundAmount = new BigDecimal (thisRefundAmountDouble.doubleValue()); 814 thisRefundAmount = thisRefundAmount.setScale(decimals, rounding); 815 816 String paymentId = null; 817 818 List electronicTypes = UtilMisc.toList("CREDIT_CARD", "EFT_ACCOUNT", "GIFT_CARD"); 820 822 if (electronicTypes.contains(orderPayPref.getString("paymentMethodTypeId"))) { 823 try { 825 serviceResult = dispatcher.runSync("refundPayment", UtilMisc.toMap("orderPaymentPreference", orderPayPref, "refundAmount", new Double (thisRefundAmount.doubleValue()), "userLogin", userLogin)); 826 if (ServiceUtil.isError(serviceResult)) { 827 return ServiceUtil.returnError("Error in refund payment", null, null, serviceResult); 828 } 829 830 paymentId = (String ) serviceResult.get("paymentId"); 831 } catch (GenericServiceException e) { 832 Debug.logError(e, "Problem running the refundPayment service", module); 833 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemsWithTheRefundSeeLogs", locale)); 834 } 835 } else { 836 } 838 839 841 Timestamp now = UtilDateTime.nowTimestamp(); 843 844 Map response = FastMap.newInstance(); 846 response.put("orderPaymentPreferenceId", orderPayPref.getString("orderPaymentPreferenceId")); 847 response.put("responseAmount", new Double (thisRefundAmount.doubleValue())); 848 response.put("responseDate", now); 849 response.put("userLogin", userLogin); 850 if (paymentId != null) { 851 response.put("paymentId", paymentId); 853 } 854 Map serviceResults = null; 855 try { 856 serviceResults = dispatcher.runSync("createReturnItemResponse", response); 857 if (ServiceUtil.isError(serviceResults)) { 858 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemsCreatingReturnItemResponseEntity", locale), null, null, serviceResults); 859 } 860 } catch (GenericServiceException e) { 861 Debug.logError(e, "Problems creating new ReturnItemResponse entity", module); 862 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemsCreatingReturnItemResponseEntity", locale)); 863 } 864 String responseId = (String ) serviceResults.get("returnItemResponseId"); 865 866 Iterator itemsIter = itemList.iterator(); 868 while (itemsIter.hasNext()) { 869 GenericValue item = (GenericValue) itemsIter.next(); 870 item.set("returnItemResponseId", responseId); 871 item.set("statusId", "RETURN_COMPLETED"); 872 873 String returnStatusId = delegator.getNextSeqId("ReturnStatus"); 875 GenericValue returnStatus = delegator.makeValue("ReturnStatus", UtilMisc.toMap("returnStatusId", returnStatusId)); 876 returnStatus.set("statusId", item.get("statusId")); 877 returnStatus.set("returnId", item.get("returnId")); 878 returnStatus.set("returnItemSeqId", item.get("returnItemSeqId")); 879 returnStatus.set("statusDatetime", now); 880 881 try { 883 item.store(); 884 delegator.create(returnStatus); 885 } catch (GenericEntityException e) { 886 Debug.logError("Problem updating the ReturnItem entity", module); 887 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemUpdatingReturnItemReturnItemResponseId", locale)); 888 } 889 890 } 892 893 try { 895 serviceResults = dispatcher.runSync("createPaymentApplicationsFromReturnItemResponse", 896 UtilMisc.toMap("returnItemResponseId", responseId, "userLogin", userLogin)); 897 if (ServiceUtil.isError(serviceResults)) { 898 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemUpdatingReturnItemReturnItemResponseId", locale), null, null, serviceResults); 899 } 900 } catch (GenericServiceException e) { 901 Debug.logError(e, "Problem creating PaymentApplication records for return invoice", module); 902 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderProblemUpdatingReturnItemReturnItemResponseId", locale)); 903 } 904 } 905 } 906 } 907 908 return ServiceUtil.returnSuccess(); 909 } 910 911 public static Map createPaymentApplicationsFromReturnItemResponse(DispatchContext dctx, Map context) { 912 LocalDispatcher dispatcher = dctx.getDispatcher(); 913 GenericDelegator delegator = dctx.getDelegator(); 914 GenericValue userLogin = (GenericValue) context.get("userLogin"); 915 916 String responseId = (String ) context.get("returnItemResponseId"); 919 String errorMsg = "Failed to create payment applications for return item response [" + responseId + "]. "; 920 try { 921 GenericValue response = delegator.findByPrimaryKey("ReturnItemResponse", UtilMisc.toMap("returnItemResponseId", responseId)); 922 if (response == null) { 923 return ServiceUtil.returnError(errorMsg + "Return Item Response not found with ID [" + responseId + "]."); 924 } 925 BigDecimal responseAmount = response.getBigDecimal("responseAmount").setScale(decimals, rounding); 926 String paymentId = response.getString("paymentId"); 927 928 Map returnInvoices = FastMap.newInstance(); List items = response.getRelated("ReturnItem"); 931 for (Iterator itemIter = items.iterator(); itemIter.hasNext(); ) { 932 GenericValue item = (GenericValue) itemIter.next(); 933 List billings = item.getRelated("ReturnItemBilling"); 934 for (Iterator billIter = billings.iterator(); billIter.hasNext(); ) { 935 GenericValue billing = (GenericValue) billIter.next(); 936 GenericValue invoice = billing.getRelatedOne("Invoice"); 937 938 if (returnInvoices.get(invoice.getString("invoiceId")) == null) { 940 returnInvoices.put(invoice.getString("invoiceId"), invoice); 941 } 942 } 943 } 944 945 Map invoiceTotals = FastMap.newInstance(); BigDecimal grandTotal = ZERO; for (Iterator iter = returnInvoices.values().iterator(); iter.hasNext(); ) { 949 GenericValue invoice = (GenericValue) iter.next(); 950 951 List billings = invoice.getRelated("ReturnItemBilling"); 952 BigDecimal runningTotal = ZERO; 953 for (Iterator billIter = billings.iterator(); billIter.hasNext(); ) { 954 GenericValue billing = (GenericValue) billIter.next(); 955 runningTotal = runningTotal.add(billing.getBigDecimal("amount").multiply(billing.getBigDecimal("quantity")).setScale(decimals, rounding)); 956 } 957 958 invoiceTotals.put(invoice.getString("invoiceId"), runningTotal); 959 grandTotal = grandTotal.add(runningTotal); 960 } 961 962 for (Iterator iter = returnInvoices.values().iterator(); iter.hasNext(); ) { 964 GenericValue invoice = (GenericValue) iter.next(); 965 String invoiceId = invoice.getString("invoiceId"); 966 BigDecimal invoiceTotal = (BigDecimal ) invoiceTotals.get(invoiceId); 967 968 BigDecimal amountApplied = responseAmount.multiply(invoiceTotal).divide(grandTotal, decimals, rounding).setScale(decimals, rounding); 969 970 if (paymentId != null) { 971 Map input = UtilMisc.toMap("paymentId", paymentId, "invoiceId", invoice.getString("invoiceId")); 973 input.put("amountApplied", new Double (amountApplied.doubleValue())); 974 input.put("userLogin", userLogin); 975 Map serviceResults = dispatcher.runSync("createPaymentApplication", input); 976 if (ServiceUtil.isError(serviceResults)) { 977 return ServiceUtil.returnError(errorMsg, null, null, serviceResults); 978 } 979 if (Debug.verboseOn()) { Debug.logInfo("Created PaymentApplication for response with amountApplied " + amountApplied.toString(), module); } 980 } 981 } 982 } catch (GenericServiceException e) { 983 Debug.logError(e, errorMsg + e.getMessage(), module); 984 return ServiceUtil.returnError(errorMsg + e.getMessage()); 985 } catch (GenericEntityException e) { 986 Debug.logError(e, errorMsg + e.getMessage(), module); 987 return ServiceUtil.returnError(errorMsg + e.getMessage()); 988 } 989 return ServiceUtil.returnSuccess(); 990 } 991 992 public static Map processReplacementReturn(DispatchContext dctx, Map context) { 994 LocalDispatcher dispatcher = dctx.getDispatcher(); 995 GenericDelegator delegator = dctx.getDelegator(); 996 String returnId = (String ) context.get("returnId"); 997 GenericValue userLogin = (GenericValue) context.get("userLogin"); 998 Locale locale = (Locale ) context.get("locale"); 999 1000 GenericValue returnHeader = null; 1001 List returnItems = null; 1002 try { 1003 returnHeader = delegator.findByPrimaryKey("ReturnHeader", UtilMisc.toMap("returnId", returnId)); 1004 if (returnHeader != null) { 1005 returnItems = returnHeader.getRelatedByAnd("ReturnItem", UtilMisc.toMap("returnTypeId", "RTN_REPLACE")); 1006 } 1007 } catch (GenericEntityException e) { 1008 Debug.logError(e, "Problems looking up return information", module); 1009 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error,"OrderErrorGettingReturnHeaderItemInformation", locale)); 1010 } 1011 1012 List createdOrderIds = new ArrayList (); 1013 if (returnHeader != null && returnItems != null && returnItems.size() > 0) { 1014 Map itemsByOrder = new HashMap (); 1015 Map totalByOrder = new HashMap (); 1016 groupReturnItemsByOrder(returnItems, itemsByOrder, totalByOrder, delegator, returnId); 1017 1018 Set itemSet = itemsByOrder.entrySet(); 1020 Iterator itemByOrderIt = itemSet.iterator(); 1021 while (itemByOrderIt.hasNext()) { 1022 Map.Entry entry = (Map.Entry ) itemByOrderIt.next(); 1023 String orderId = (String ) entry.getKey(); 1024 List items = (List ) entry.getValue(); 1025 1026 GenericValue orderHeader = null; 1028 try { 1029 orderHeader = delegator.findByPrimaryKey("OrderHeader", UtilMisc.toMap("orderId", orderId)); 1030 } catch (GenericEntityException e) { 1031 Debug.logError(e, "Cannot get Order details for #" + orderId, module); 1032 continue; 1033 } 1034 1035 OrderReadHelper orh = new OrderReadHelper(orderHeader); 1036 1037 Map orderMap = UtilMisc.toMap("userLogin", userLogin); 1039 GenericValue placingParty = orh.getPlacingParty(); 1040 String placingPartyId = null; 1041 if (placingParty != null) { 1042 placingPartyId = placingParty.getString("partyId"); 1043 } 1044 1045 orderMap.put("orderTypeId", "SALES_ORDER"); 1046 orderMap.put("partyId", placingPartyId); 1047 orderMap.put("productStoreId", orderHeader.get("productStoreId")); 1048 orderMap.put("webSiteId", orderHeader.get("webSiteId")); 1049 orderMap.put("visitId", orderHeader.get("visitId")); 1050 orderMap.put("currencyUom", orderHeader.get("currencyUom")); 1051 orderMap.put("grandTotal", new Double (0.00)); 1052 1053 List contactMechs = new ArrayList (); 1055 List orderCm = null; 1056 try { 1057 orderCm = orderHeader.getRelated("OrderContactMech"); 1058 } catch (GenericEntityException e) { 1059 Debug.logError(e, module); 1060 } 1061 if (orderCm != null) { 1062 Iterator orderCmi = orderCm.iterator(); 1063 while (orderCmi.hasNext()) { 1064 GenericValue v = (GenericValue) orderCmi.next(); 1065 contactMechs.add(GenericValue.create(v)); 1066 } 1067 orderMap.put("orderContactMechs", contactMechs); 1068 } 1069 1070 List shipmentPrefs = new ArrayList (); 1072 List orderSp = null; 1073 try { 1074 orderSp = orderHeader.getRelated("OrderShipmentPreference"); 1075 } catch (GenericEntityException e) { 1076 Debug.logError(e, module); 1077 } 1078 if (orderSp != null) { 1079 Iterator orderSpi = orderSp.iterator(); 1080 while (orderSpi.hasNext()) { 1081 GenericValue v = (GenericValue) orderSpi.next(); 1082 shipmentPrefs.add(GenericValue.create(v)); 1083 } 1084 orderMap.put("orderShipmentPreferences", shipmentPrefs); 1085 } 1086 1087 double itemTotal = 0.00; 1089 List orderItems = new ArrayList (); 1090 if (items != null) { 1091 Iterator ri = items.iterator(); 1092 int itemCount = 1; 1093 while (ri.hasNext()) { 1094 GenericValue returnItem = (GenericValue) ri.next(); 1095 GenericValue orderItem = null; 1096 try { 1097 orderItem = returnItem.getRelatedOne("OrderItem"); 1098 } catch (GenericEntityException e) { 1099 Debug.logError(e, module); 1100 continue; 1101 } 1102 if (orderItem != null) { 1103 Double quantity = returnItem.getDouble("returnQuantity"); 1104 Double unitPrice = returnItem.getDouble("returnPrice"); 1105 if (quantity != null && unitPrice != null) { 1106 itemTotal = (quantity.doubleValue() * unitPrice.doubleValue()); 1107 GenericValue newItem = delegator.makeValue("OrderItem", UtilMisc.toMap("orderItemSeqId", new Integer (itemCount).toString())); 1108 1109 newItem.set("orderItemTypeId", orderItem.get("orderItemTypeId")); 1110 newItem.set("productId", orderItem.get("productId")); 1111 newItem.set("productFeatureId", orderItem.get("productFeatureId")); 1112 newItem.set("prodCatalogId", orderItem.get("prodCatalogId")); 1113 newItem.set("productCategoryId", orderItem.get("productCategoryId")); 1114 newItem.set("quantity", quantity); 1115 newItem.set("unitPrice", unitPrice); 1116 newItem.set("unitListPrice", orderItem.get("unitListPrice")); 1117 newItem.set("itemDescription", orderItem.get("itemDescription")); 1118 newItem.set("comments", orderItem.get("comments")); 1119 newItem.set("correspondingPoId", orderItem.get("correspondingPoId")); 1120 newItem.set("statusId", "ITEM_CREATED"); 1121 orderItems.add(newItem); 1122 } 1123 } 1124 } 1125 orderMap.put("orderItems", orderItems); 1126 } else { 1127 Debug.logError("No return items found??", module); 1128 continue; 1129 } 1130 1131 GenericValue adj = delegator.makeValue("OrderAdjustment", new HashMap ()); 1133 adj.set("orderAdjustmentTypeId", "REPLACE_ADJUSTMENT"); 1134 adj.set("amount", new Double (itemTotal * -1)); 1135 adj.set("comments", "Replacement Item Return #" + returnId); 1136 adj.set("createdDate", UtilDateTime.nowTimestamp()); 1137 adj.set("createdByUserLogin", userLogin.getString("userLoginId")); 1138 orderMap.put("orderAdjustments", UtilMisc.toList(adj)); 1139 1140 try { 1142 orderMap.put("orderTerms", orderHeader.getRelated("OrderTerm")); 1143 } catch (GenericEntityException e) { 1144 Debug.logError(e, "Cannot create replacement order because order terms for original order is not available", module); 1145 } 1146 1147 String createdOrderId = null; 1149 Map orderResult = null; 1150 try { 1151 orderResult = dispatcher.runSync("storeOrder", orderMap); 1152 } catch (GenericServiceException e) { 1153 Debug.logInfo(e, "Problem creating the order!", module); 1154 } 1155 if (orderResult != null) { 1156 createdOrderId = (String ) orderResult.get("orderId"); 1157 createdOrderIds.add(createdOrderId); 1158 } 1159 1160 if (createdOrderId != null) { 1162 OrderChangeHelper.approveOrder(dispatcher, userLogin, createdOrderId); 1163 } 1164 } 1165 } 1166 1167 StringBuffer successMessage = new StringBuffer (); 1168 if (createdOrderIds.size() > 0) { 1169 successMessage.append("The following new orders have been created : "); 1170 Iterator i = createdOrderIds.iterator(); 1171 while (i.hasNext()) { 1172 successMessage.append(i.next()); 1173 if (i.hasNext()) { 1174 successMessage.append(", "); 1175 } 1176 } 1177 } else { 1178 successMessage.append("No orders were created."); 1179 } 1180 1181 return ServiceUtil.returnSuccess(successMessage.toString()); 1182 } 1183 1184 1192 public static void groupReturnItemsByOrder(List returnItems, Map itemsByOrder, Map totalByOrder, GenericDelegator delegator, String returnId) { 1193 Iterator itemIt = returnItems.iterator(); 1194 while (itemIt.hasNext()) { 1195 GenericValue item = (GenericValue) itemIt.next(); 1196 String orderId = item.getString("orderId"); 1197 if (orderId != null) { 1198 if (itemsByOrder != null) { 1199 List orderList = (List ) itemsByOrder.get(orderId); 1200 Double totalForOrder = null; 1201 if (totalByOrder != null) { 1202 totalForOrder = (Double ) totalByOrder.get(orderId); 1203 } 1204 if (orderList == null) { 1205 orderList = new ArrayList (); 1206 } 1207 if (totalForOrder == null) { 1208 totalForOrder = new Double (0.00); 1209 } 1210 1211 orderList.add(item); 1213 itemsByOrder.put(orderId, orderList); 1214 1215 if (totalByOrder != null) { 1216 Double quantity = item.getDouble("returnQuantity"); 1218 Double amount = item.getDouble("returnPrice"); 1219 if (quantity == null) { 1220 quantity = new Double (0); 1221 } 1222 if (amount == null) { 1223 amount = new Double (0.00); 1224 } 1225 double thisTotal = amount.doubleValue() * quantity.doubleValue(); 1226 double existingTotal = totalForOrder.doubleValue(); 1227 Map condition = UtilMisc.toMap("returnId", item.get("returnId"), "returnItemSeqId", item.get("returnItemSeqId")); 1228 Double newTotal = new Double (existingTotal + thisTotal + getReturnAdjustmentTotal(delegator, condition) ); 1229 totalByOrder.put(orderId, newTotal); 1230 } 1231 } 1232 } 1233 } 1234 1235 if ((totalByOrder != null) && (totalByOrder.keySet() != null)) { 1237 Iterator orderIterator = totalByOrder.keySet().iterator(); 1238 while (orderIterator.hasNext()) { 1239 String orderId = (String ) orderIterator.next(); 1240 Map condition = UtilMisc.toMap("returnId", returnId, "returnItemSeqId", org.ofbiz.common.DataModelConstants.SEQ_ID_NA); 1242 double existingTotal = ((Double ) totalByOrder.get(orderId)).doubleValue() + getReturnAdjustmentTotal(delegator, condition); 1243 totalByOrder.put(orderId, new Double (existingTotal)); 1244 } 1245 } 1246 } 1247 1248 1249 public static Map getReturnAmountByOrder(DispatchContext dctx, Map context) { 1250 GenericDelegator delegator = dctx.getDelegator(); 1251 String returnId = (String ) context.get("returnId"); 1252 Locale locale = (Locale ) context.get("locale"); 1253 List returnItems = null; 1254 Map returnAmountByOrder = new HashMap (); 1255 try { 1256 returnItems = delegator.findByAnd("ReturnItem", UtilMisc.toMap("returnId", returnId)); 1257 1258 } catch (GenericEntityException e) { 1259 Debug.logError(e, "Problems looking up return information", module); 1260 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorGettingReturnHeaderItemInformation", locale)); 1261 } 1262 if ((returnItems != null) && (returnItems.size() > 0)) { 1263 Iterator returnItemIterator = returnItems.iterator(); 1264 GenericValue returnItem = null; 1265 GenericValue returnItemResponse = null; 1266 GenericValue payment = null; 1267 String orderId; 1268 List paymentList = new ArrayList (); 1269 while (returnItemIterator.hasNext()) { 1270 returnItem = (GenericValue) returnItemIterator.next(); 1271 orderId = returnItem.getString("orderId"); 1272 try { 1273 returnItemResponse = returnItem.getRelatedOne("ReturnItemResponse"); 1274 if ((returnItemResponse != null) && (orderId != null)) { 1275 payment = returnItemResponse.getRelatedOne("Payment"); 1277 if ((payment != null) && (payment.getDouble("amount") != null) && 1278 !paymentList.contains(payment.get("paymentId"))) { 1279 UtilMisc.addToDoubleInMap(returnAmountByOrder, orderId, payment.getDouble("amount")); 1280 paymentList.add(payment.get("paymentId")); } 1282 } 1283 } catch (GenericEntityException e) { 1284 Debug.logError(e, "Problems looking up return item related information", module); 1285 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderErrorGettingReturnHeaderItemInformation", locale)); 1286 } 1287 } 1288 } 1289 return UtilMisc.toMap("orderReturnAmountMap", returnAmountByOrder); 1290 } 1291 1292 public static Map checkPaymentAmountForRefund(DispatchContext dctx, Map context) { 1293 LocalDispatcher dispatcher = dctx.getDispatcher(); 1294 GenericDelegator delegator = dctx.getDelegator(); 1295 String returnId = (String ) context.get("returnId"); 1296 Locale locale = (Locale ) context.get("locale"); 1297 Map returnAmountByOrder = null; 1298 Map serviceResult = null; 1299 try { 1301 serviceResult = dispatcher.runSync("getReturnAmountByOrder", org.ofbiz.base.util.UtilMisc.toMap("returnId", returnId)); 1302 } catch (GenericServiceException e) { 1303 Debug.logError(e, "Problem running the getReturnAmountByOrder service", module); 1304 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderProblemsWithGetReturnAmountByOrder", locale)); 1305 } 1306 if (ServiceUtil.isError(serviceResult)) { 1307 return ServiceUtil.returnError((String ) serviceResult.get(ModelService.ERROR_MESSAGE)); 1308 } else { 1309 returnAmountByOrder = (Map ) serviceResult.get("orderReturnAmountMap"); 1310 } 1311 1312 if ((returnAmountByOrder != null) && (returnAmountByOrder.keySet() != null)) { 1313 Iterator orderIterator = returnAmountByOrder.keySet().iterator(); 1314 while (orderIterator.hasNext()) { 1315 String orderId = (String ) orderIterator.next(); 1316 Double returnAmount = (Double ) returnAmountByOrder.get(orderId); 1317 if (Math.abs(returnAmount.doubleValue()) < 0.000001) { 1318 Debug.logError("Order [" + orderId + "] refund amount[ " + returnAmount + "] less than zero", module); 1319 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderReturnTotalCannotLessThanZero", locale)); 1320 } 1321 OrderReadHelper helper = new OrderReadHelper(OrderReadHelper.getOrderHeader(delegator, orderId)); 1322 double grandTotal = helper.getOrderGrandTotal(); 1323 if (returnAmount == null) { 1324 Debug.logInfo("No returnAmount found for order:" + orderId, module); 1325 } else { 1326 if ((returnAmount.doubleValue() - grandTotal) > 0.01) { 1327 Debug.logError("Order [" + orderId + "] refund amount[ " + returnAmount + "] exceeds order total [" + grandTotal + "]", module); 1328 return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderRefundAmountExceedsOrderTotal", locale)); 1329 } 1330 } 1331 } 1332 } 1333 return ServiceUtil.returnSuccess(); 1334 } 1335 1336 public static Map createReturnAdjustment(DispatchContext dctx, Map context) { 1337 GenericDelegator delegator = dctx.getDelegator(); 1338 String orderAdjustmentId = (String ) context.get("orderAdjustmentId"); 1339 String returnAdjustmentTypeId = (String ) context.get("returnAdjustmentTypeId"); 1340 String returnId = (String ) context.get("returnId"); 1341 String returnItemSeqId = (String ) context.get("returnItemSeqId"); 1342 String description = (String ) context.get("description"); 1343 1344 GenericValue returnItemTypeMap = null; 1345 GenericValue orderAdjustment = null; 1346 GenericValue returnAdjustmentType = null; 1347 GenericValue orderItem = null; 1348 GenericValue returnItem = null; 1349 GenericValue returnHeader = null; 1350 1351 Double amount; 1352 1353 if (orderAdjustmentId != null) { 1355 try { 1356 orderAdjustment = delegator.findByPrimaryKey("OrderAdjustment", UtilMisc.toMap("orderAdjustmentId", orderAdjustmentId)); 1357 1358 returnHeader = delegator.findByPrimaryKey("ReturnHeader", UtilMisc.toMap("returnId", returnId)); 1360 String returnHeaderTypeId = ((returnHeader != null) && (returnHeader.getString("returnHeaderTypeId") != null)) ? returnHeader.getString("returnHeaderTypeId") : "CUSTOMER_RETURN"; 1361 returnItemTypeMap = delegator.findByPrimaryKey("ReturnItemTypeMap", 1362 UtilMisc.toMap("returnHeaderTypeId", returnHeaderTypeId, "returnItemMapKey", orderAdjustment.get("orderAdjustmentTypeId"))); 1363 returnAdjustmentType = returnItemTypeMap.getRelatedOne("ReturnAdjustmentType"); 1364 if (returnAdjustmentType != null && UtilValidate.isEmpty(description)) { 1365 description = returnAdjustmentType.getString("description"); 1366 } 1367 if ((returnItemSeqId != null) && !("_NA_".equals(returnItemSeqId))) { 1368 returnItem = delegator.findByPrimaryKey("ReturnItem", 1369 UtilMisc.toMap("returnId", returnId, "returnItemSeqId", returnItemSeqId)); 1370 Debug.log("returnId:" + returnId + ",returnItemSeqId:" + returnItemSeqId); 1371 orderItem = returnItem.getRelatedOne("OrderItem"); 1372 } 1373 } catch (GenericEntityException e) { 1374 Debug.logError(e, module); 1375 throw new GeneralRuntimeException(e.getMessage()); 1376 } 1377 context.putAll(orderAdjustment.getAllFields()); 1378 } 1379 1380 if (returnAdjustmentTypeId == null) { 1383 String mappingTypeId = returnItemTypeMap != null ? returnItemTypeMap.get("returnItemTypeId").toString() : null; 1384 returnAdjustmentTypeId = mappingTypeId != null ? mappingTypeId : "RET_MAN_ADJ"; 1385 } 1386 if (returnItem != null) { if (needRecalculate(returnAdjustmentTypeId)) { 1389 Debug.logInfo("returnPrice:" + returnItem.getDouble("returnPrice") + ",returnQuantity:" + returnItem.getDouble("returnQuantity") + ",sourcePercentage:" + orderAdjustment.getDouble("sourcePercentage"), module); 1390 if (orderAdjustment == null) { 1391 Debug.logError("orderAdjustment [" + orderAdjustmentId + "] not found", module); 1392 return ServiceUtil.returnError("orderAdjustment [" + orderAdjustmentId + "] not found"); 1393 } 1394 BigDecimal returnTotal = returnItem.getBigDecimal("returnPrice").multiply(returnItem.getBigDecimal("returnQuantity")); 1395 BigDecimal orderTotal = orderItem.getBigDecimal("quantity").multiply(orderItem.getBigDecimal("unitPrice")); 1396 amount = getAdjustmentAmount("RET_SALES_TAX_ADJ".equals(returnAdjustmentType), returnTotal, orderTotal, orderAdjustment.getBigDecimal("amount")); 1397 } else { 1398 amount = (Double ) context.get("amount"); 1399 } 1400 } else { amount = (Double ) context.get("amount"); 1402 } 1403 1404 String seqId = delegator.getNextSeqId("ReturnAdjustment"); 1406 GenericValue newReturnAdjustment = delegator.makeValue("ReturnAdjustment", 1407 UtilMisc.toMap("returnAdjustmentId", seqId)); 1408 1409 try { 1410 newReturnAdjustment.setNonPKFields(context); 1411 if (orderAdjustment != null && orderAdjustment.get("taxAuthorityRateSeqId") != null) { 1412 newReturnAdjustment.set("taxAuthorityRateSeqId", orderAdjustment.getString("taxAuthorityRateSeqId")); 1413 } 1414 newReturnAdjustment.set("amount", amount); 1415 newReturnAdjustment.set("returnAdjustmentTypeId", returnAdjustmentTypeId); 1416 newReturnAdjustment.set("description", description); 1417 newReturnAdjustment.set("returnItemSeqId", UtilValidate.isEmpty(returnItemSeqId) ? "_NA_" : returnItemSeqId); 1418 1419 delegator.create(newReturnAdjustment); 1420 Map result = ServiceUtil.returnSuccess("Create ReturnAdjustment with Id:" + seqId + " successfully."); 1421 result.put("returnAdjustmentId", seqId); 1422 return result; 1423 } catch (GenericEntityException e) { 1424 Debug.logError(e, "Failed to store returnAdjustment", module); 1425 return ServiceUtil.returnError("Failed to store returnAdjustment"); 1426 } 1427 } 1428 1429 public static Map updateReturnAdjustment(DispatchContext dctx, Map context) { 1430 GenericDelegator delegator = dctx.getDelegator(); 1431 1432 GenericValue returnItem = null; 1433 GenericValue returnAdjustment = null; 1434 String returnAdjustmentTypeId = null; 1435 Double amount; 1436 1437 1438 try { 1439 returnAdjustment = delegator.findByPrimaryKey("ReturnAdjustment", UtilMisc.toMap("returnAdjustmentId", context.get("returnAdjustmentId"))); 1440 1441 if (returnAdjustment != null) { 1442 returnItem = delegator.findByPrimaryKey("ReturnItem", 1443 UtilMisc.toMap("returnId", returnAdjustment.get("returnId"), "returnItemSeqId", returnAdjustment.get("returnItemSeqId"))); 1444 returnAdjustmentTypeId = returnAdjustment.getString("returnAdjustmentTypeId"); 1445 } 1446 1447 if (returnItem != null) { double originalReturnPrice = (context.get("originalReturnPrice") != null) ? ((Double ) context.get("originalReturnPrice")).doubleValue() : returnItem.getDouble("returnPrice").doubleValue(); 1450 double originalReturnQuantity = (context.get("originalReturnQuantity") != null) ? ((Double ) context.get("originalReturnQuantity")).doubleValue() : returnItem.getDouble("returnQuantity").doubleValue(); 1451 1452 if (needRecalculate(returnAdjustmentTypeId)) { 1453 BigDecimal returnTotal = returnItem.getBigDecimal("returnPrice").multiply(returnItem.getBigDecimal("returnQuantity")); 1454 BigDecimal originalReturnTotal = new BigDecimal (originalReturnPrice).multiply(new BigDecimal (originalReturnQuantity)); 1455 amount = getAdjustmentAmount("RET_SALES_TAX_ADJ".equals(returnAdjustmentTypeId), returnTotal, originalReturnTotal, returnAdjustment.getBigDecimal("amount")); 1456 } else { 1457 amount = (Double ) context.get("amount"); 1458 } 1459 } else { amount = (Double ) context.get("amount"); 1461 } 1462 1463 returnAdjustment.setNonPKFields(context); 1464 returnAdjustment.set("amount", amount); 1465 delegator.store(returnAdjustment); 1466 Debug.logInfo("Update ReturnAdjustment with Id:" + context.get("returnAdjustmentId") + " to amount " + amount +" successfully.", module); 1467 Map result = ServiceUtil.returnSuccess("Update ReturnAdjustment with Id:" + context.get("returnAdjustmentId") + " to amount " + amount +" successfully."); 1468 return result; 1469 } catch (GenericEntityException e) { 1470 Debug.logError(e, "Failed to store returnAdjustment", module); 1471 return ServiceUtil.returnError("Failed to store returnAdjustment"); 1472 } 1473 } 1474 1475 public static Map createReturnItemOrAdjustment(DispatchContext dctx, Map context){ 1477 Debug.logInfo("createReturnItemOrAdjustment's context:" + context, module); 1478 String orderItemSeqId = (String ) context.get("orderItemSeqId"); 1479 Debug.logInfo("orderItemSeqId:" + orderItemSeqId +"#", module); 1480 LocalDispatcher dispatcher = dctx.getDispatcher(); 1481 String serviceName = UtilValidate.isNotEmpty(orderItemSeqId) ? "createReturnItem" : "createReturnAdjustment"; 1483 Debug.logInfo("serviceName:" + serviceName, module); 1484 try { 1485 return dispatcher.runSync(serviceName, filterServiceContext(dctx, serviceName, context)); 1486 } catch (org.ofbiz.service.GenericServiceException e) { 1487 Debug.logError(e, module); 1488 return ServiceUtil.returnError(e.getMessage()); 1489 } 1490 } 1491 1492 public static Map updateReturnItemOrAdjustment(DispatchContext dctx, Map context){ 1494 Debug.logInfo("updateReturnItemOrAdjustment's context:" + context, module); 1495 String returnAdjustmentId = (String ) context.get("returnAdjustmentId"); 1496 Debug.logInfo("returnAdjustmentId:" + returnAdjustmentId +"#", module); 1497 LocalDispatcher dispatcher = dctx.getDispatcher(); 1498 String serviceName = UtilValidate.isEmpty(returnAdjustmentId) ? "updateReturnItem" : "updateReturnAdjustment"; 1500 Debug.logInfo("serviceName:" + serviceName, module); 1501 try { 1502 return dispatcher.runSync(serviceName, filterServiceContext(dctx, serviceName, context)); 1503 } catch (org.ofbiz.service.GenericServiceException e) { 1504 Debug.logError(e, module); 1505 return ServiceUtil.returnError(e.getMessage()); 1506 } 1507 } 1508 1509 1514 public static boolean needRecalculate(String returnAdjustmentTypeId) { 1515 return "RET_PROMOTION_ADJ".equals(returnAdjustmentTypeId) || 1516 "RET_DISCOUNT_ADJ".equals(returnAdjustmentTypeId) || 1517 "RET_SALES_TAX_ADJ".equals(returnAdjustmentTypeId); 1518 1519 } 1520 1521 1527 public static double getReturnAdjustmentTotal(GenericDelegator delegator, Map condition) { 1528 double total = 0.0; 1529 List adjustments; 1530 try { 1531 adjustments = delegator.findByAnd("ReturnAdjustment", condition); 1533 if (adjustments != null) { 1534 Iterator adjustmentIterator = adjustments.iterator(); 1535 while (adjustmentIterator.hasNext()) { 1536 GenericValue returnAdjustment = (GenericValue) adjustmentIterator.next(); 1537 total += returnAdjustment.getDouble("amount").doubleValue(); 1538 } 1539 } 1540 } catch (org.ofbiz.entity.GenericEntityException e) { 1541 Debug.logError(e, module); 1542 } 1543 return total; 1544 } 1545 1546 1554 public static Map filterServiceContext(DispatchContext dctx, String serviceName, Map context) throws GenericServiceException { 1555 ModelService modelService = dctx.getModelService(serviceName); 1556 1557 if (modelService == null) { 1558 throw new GenericServiceException("Problems getting the service model"); 1559 } 1560 Map serviceContext = FastMap.newInstance(); 1561 List modelParmInList = modelService.getInModelParamList(); 1562 Iterator modelParmInIter = modelParmInList.iterator(); 1563 while (modelParmInIter.hasNext()) { 1564 ModelParam modelParam = (ModelParam) modelParmInIter.next(); 1565 String paramName = modelParam.name; 1566 1567 Object value = context.get(paramName); 1568 if(value != null){ 1569 serviceContext.put(paramName, value); 1570 } 1571 } 1572 return serviceContext; 1573 } 1574 1575 1583 public static Double getAdjustmentAmount(boolean isSalesTax, BigDecimal returnTotal, BigDecimal originalTotal, BigDecimal amount) { 1584 String settingPrefix = isSalesTax ? "salestax" : "order"; 1585 String decimalsPrefix = isSalesTax ? ".calc" : ""; 1586 int decimals = UtilNumber.getBigDecimalScale(settingPrefix + decimalsPrefix + ".decimals"); 1587 int rounding = UtilNumber.getBigDecimalRoundingMode(settingPrefix + ".rounding"); 1588 int finalDecimals = isSalesTax ? UtilNumber.getBigDecimalScale(settingPrefix + ".final.decimals") : decimals; 1589 returnTotal = returnTotal.setScale(decimals, rounding); 1590 originalTotal = originalTotal.setScale(decimals, rounding); 1591 BigDecimal newAmount = returnTotal.divide(originalTotal, decimals, rounding).multiply(amount).setScale(finalDecimals, rounding); 1592 return new Double (newAmount.doubleValue()); 1593 } 1594} 1595 | Popular Tags |