001: /*
002: * $Id: OrderChangeHelper.java,v 1.10 2003/12/06 23:57:46 ajzeneski Exp $
003: *
004: * Copyright (c) 2001, 2002 The Open For Business Project - www.ofbiz.org
005: *
006: * Permission is hereby granted, free of charge, to any person obtaining a
007: * copy of this software and associated documentation files (the "Software"),
008: * to deal in the Software without restriction, including without limitation
009: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
010: * and/or sell copies of the Software, and to permit persons to whom the
011: * Software is furnished to do so, subject to the following conditions:
012: *
013: * The above copyright notice and this permission notice shall be included
014: * in all copies or substantial portions of the Software.
015: *
016: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
017: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
018: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
019: * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
020: * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
021: * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
022: * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
023: *
024: */
025: package org.ofbiz.order.order;
026:
027: import java.util.Iterator;
028: import java.util.List;
029: import java.util.Map;
030:
031: import org.ofbiz.base.util.*;
032: import org.ofbiz.entity.GenericDelegator;
033: import org.ofbiz.entity.GenericEntityException;
034: import org.ofbiz.entity.GenericValue;
035: import org.ofbiz.entity.util.EntityUtil;
036: import org.ofbiz.service.GenericServiceException;
037: import org.ofbiz.service.LocalDispatcher;
038: import org.ofbiz.service.ModelService;
039: import org.ofbiz.service.ServiceUtil;
040: import org.ofbiz.workflow.WfException;
041: import org.ofbiz.workflow.client.WorkflowClient;
042:
043: /**
044: * Order Helper - Helper Methods For Non-Read Actions
045: *
046: * @author <a href="mailto:jaz@ofbiz.org">Andy Zeneski</a>
047: * @version $Revision: 1.10 $
048: * @since 2.0
049: */
050: public class OrderChangeHelper {
051:
052: public static final String module = OrderChangeHelper.class
053: .getName();
054:
055: public static boolean approveOrder(LocalDispatcher dispatcher,
056: GenericValue userLogin, String orderId) {
057: GenericValue productStore = OrderReadHelper
058: .getProductStoreFromOrder(dispatcher.getDelegator(),
059: orderId);
060: String HEADER_STATUS = "ORDER_PROCESSING";
061: String ITEM_STATUS = "ITEM_CREATED";
062: String DIGITAL_ITEM_STATUS = "ITEM_APPROVED";
063: if (productStore.get("headerApprovedStatus") != null) {
064: HEADER_STATUS = productStore
065: .getString("headerApprovedStatus");
066: }
067: if (productStore.get("itemApprovedStatus") != null) {
068: ITEM_STATUS = productStore.getString("itemApprovedStatus");
069: }
070: if (productStore.get("digitalItemApprovedStatus") != null) {
071: DIGITAL_ITEM_STATUS = productStore
072: .getString("digitalItemApprovedStatus");
073: }
074:
075: try {
076: OrderChangeHelper.orderStatusChanges(dispatcher, userLogin,
077: orderId, HEADER_STATUS, "ITEM_CREATED",
078: ITEM_STATUS, DIGITAL_ITEM_STATUS);
079: OrderChangeHelper.releaseInitialOrderHold(dispatcher,
080: orderId);
081:
082: // call the service to check/run digial fulfillment
083: Map checkDigi = dispatcher
084: .runSync("checkDigitalItemFulfillment", UtilMisc
085: .toMap("orderId", orderId, "userLogin",
086: userLogin));
087: // this service will return a message with success if there were any problems. Get this message and return it to the user
088: String message = (String) checkDigi
089: .get(ModelService.SUCCESS_MESSAGE);
090: if (UtilValidate.isNotEmpty(message)) {
091: throw new GeneralRuntimeException(message);
092: }
093: } catch (GenericServiceException e) {
094: Debug.logError(e,
095: "Service invocation error, status changes were not updated for order #"
096: + orderId, module);
097: return false;
098: }
099:
100: return true;
101: }
102:
103: public static boolean rejectOrder(LocalDispatcher dispatcher,
104: GenericValue userLogin, String orderId) {
105: GenericValue productStore = OrderReadHelper
106: .getProductStoreFromOrder(dispatcher.getDelegator(),
107: orderId);
108: String HEADER_STATUS = "ORDER_REJECTED";
109: String ITEM_STATUS = "ITEM_REJECTED";
110: if (productStore.get("headerDeclinedStatus") != null) {
111: HEADER_STATUS = productStore
112: .getString("headerDeclinedStatus");
113: }
114: if (productStore.get("itemDeclinedStatus") != null) {
115: ITEM_STATUS = productStore.getString("itemDeclinedStatus");
116: }
117:
118: try {
119: OrderChangeHelper.orderStatusChanges(dispatcher, userLogin,
120: orderId, HEADER_STATUS, null, ITEM_STATUS, null);
121: OrderChangeHelper.cancelInventoryReservations(dispatcher,
122: userLogin, orderId);
123: OrderChangeHelper.releasePaymentAuthorizations(dispatcher,
124: userLogin, orderId);
125: OrderChangeHelper.releaseInitialOrderHold(dispatcher,
126: orderId);
127: } catch (GenericServiceException e) {
128: Debug.logError(e,
129: "Service invocation error, status changes were not updated for order #"
130: + orderId, module);
131: return false;
132: }
133: return true;
134: }
135:
136: public static boolean cancelOrder(LocalDispatcher dispatcher,
137: GenericValue userLogin, String orderId) {
138: GenericValue productStore = OrderReadHelper
139: .getProductStoreFromOrder(dispatcher.getDelegator(),
140: orderId);
141: String HEADER_STATUS = "ORDER_CANCELLED";
142: String ITEM_STATUS = "ITEM_CANCELLED";
143: if (productStore.get("headerCancelStatus") != null) {
144: HEADER_STATUS = productStore
145: .getString("headerCancelStatus");
146: }
147: if (productStore.get("itemCancelStatus") != null) {
148: ITEM_STATUS = productStore.getString("itemCancelStatus");
149: }
150:
151: try {
152: OrderChangeHelper.orderStatusChanges(dispatcher, userLogin,
153: orderId, HEADER_STATUS, null, ITEM_STATUS, null);
154: OrderChangeHelper.cancelInventoryReservations(dispatcher,
155: userLogin, orderId);
156: OrderChangeHelper.releasePaymentAuthorizations(dispatcher,
157: userLogin, orderId);
158: OrderChangeHelper.releaseInitialOrderHold(dispatcher,
159: orderId);
160: } catch (GenericServiceException e) {
161: Debug.logError(e,
162: "Service invocation error, status changes were not updated for order #"
163: + orderId, module);
164: return false;
165: }
166: return true;
167: }
168:
169: public static void orderStatusChanges(LocalDispatcher dispatcher,
170: GenericValue userLogin, String orderId, String orderStatus,
171: String fromItemStatus, String toItemStatus,
172: String digitalItemStatus) throws GenericServiceException {
173: // set the status on the order header
174: Map statusFields = UtilMisc.toMap("orderId", orderId,
175: "statusId", orderStatus, "userLogin", userLogin);
176: Map statusResult = dispatcher.runSync("changeOrderStatus",
177: statusFields);
178: if (statusResult.containsKey(ModelService.ERROR_MESSAGE)) {
179: Debug.logError(
180: "Problems adjusting order header status for order #"
181: + orderId, module);
182: }
183:
184: // set the status on the order item(s)
185: Map itemStatusFields = UtilMisc.toMap("orderId", orderId,
186: "statusId", toItemStatus, "userLogin", userLogin);
187: if (fromItemStatus != null) {
188: itemStatusFields.put("fromStatusId", fromItemStatus);
189: }
190: Map itemStatusResult = dispatcher.runSync(
191: "changeOrderItemStatus", itemStatusFields);
192: if (itemStatusResult.containsKey(ModelService.ERROR_MESSAGE)) {
193: Debug.logError(
194: "Problems adjusting order item status for order #"
195: + orderId, module);
196: }
197:
198: // now set the status for digital items
199: if (digitalItemStatus != null
200: && !digitalItemStatus.equals(toItemStatus)) {
201: GenericDelegator delegator = dispatcher.getDelegator();
202: GenericValue orderHeader = null;
203: try {
204: orderHeader = delegator.findByPrimaryKey("OrderHeader",
205: UtilMisc.toMap("orderId", orderId));
206: } catch (GenericEntityException e) {
207: Debug.logError(e,
208: "ERROR: Unable to get OrderHeader for OrderID : "
209: + orderId, module);
210: }
211: if (orderHeader != null) {
212: List orderItems = null;
213: try {
214: orderItems = orderHeader.getRelated("OrderItem");
215: } catch (GenericEntityException e) {
216: Debug.logError(e,
217: "ERROR: Unable to get OrderItem records for OrderHeader : "
218: + orderId, module);
219: }
220: if (orderItems != null && orderItems.size() > 0) {
221: Iterator oii = orderItems.iterator();
222: while (oii.hasNext()) {
223: GenericValue orderItem = (GenericValue) oii
224: .next();
225: String orderItemSeqId = orderItem
226: .getString("orderItemSeqId");
227: GenericValue product = null;
228: try {
229: product = orderItem
230: .getRelatedOne("Product");
231: } catch (GenericEntityException e) {
232: Debug.logError(e,
233: "ERROR: Unable to get Product record for OrderItem : "
234: + orderId + "/"
235: + orderItemSeqId, module);
236: }
237: if (product != null) {
238: String productType = product
239: .getString("productTypeId");
240: if ("DIGITAL_GOOD".equals(productType)
241: || "FINDIG_GOOD"
242: .equals(productType)) {
243: // update the status
244: Map digitalStatusFields = UtilMisc
245: .toMap("orderId", orderId,
246: "orderItemSeqId",
247: orderItemSeqId,
248: "statusId",
249: digitalItemStatus,
250: "userLogin", userLogin);
251: Map digitalStatusChange = dispatcher
252: .runSync(
253: "changeOrderItemStatus",
254: digitalStatusFields);
255: if (ModelService.RESPOND_ERROR
256: .equals(digitalStatusChange
257: .get(ModelService.RESPONSE_MESSAGE))) {
258: Debug.logError(
259: "Problems with digital product status change : "
260: + product, module);
261: }
262: }
263: }
264: }
265: }
266: }
267: }
268: }
269:
270: public static void cancelInventoryReservations(
271: LocalDispatcher dispatcher, GenericValue userLogin,
272: String orderId) throws GenericServiceException {
273: // cancel the inventory reservations
274: Map cancelInvFields = UtilMisc.toMap("orderId", orderId,
275: "userLogin", userLogin);
276: Map cancelInvResult = dispatcher.runSync(
277: "cancelOrderInventoryReservation", cancelInvFields);
278: if (ModelService.RESPOND_ERROR.equals(cancelInvResult
279: .get(ModelService.RESPONSE_MESSAGE))) {
280: Debug.logError(
281: "Problems reversing inventory reservations for order #"
282: + orderId, module);
283: }
284: }
285:
286: public static void releasePaymentAuthorizations(
287: LocalDispatcher dispatcher, GenericValue userLogin,
288: String orderId) throws GenericServiceException {
289: Map releaseFields = UtilMisc.toMap("orderId", orderId,
290: "userLogin", userLogin);
291: Map releaseResult = dispatcher.runSync("releaseOrderPayments",
292: releaseFields);
293: if (ModelService.RESPOND_ERROR.equals(releaseResult
294: .get(ModelService.RESPONSE_MESSAGE))) {
295: Debug.logError(
296: "Problems releasing payment authorizations for order #"
297: + orderId, module);
298: }
299: }
300:
301: public static GenericValue createPaymentFromPreference(
302: GenericValue orderPaymentPreference,
303: String paymentRefNumber, String paymentFromId,
304: String comments) {
305: GenericDelegator delegator = orderPaymentPreference
306: .getDelegator();
307:
308: // get the order header
309: GenericValue orderHeader = null;
310: try {
311: orderHeader = orderPaymentPreference
312: .getRelatedOne("OrderHeader");
313: } catch (GenericEntityException e) {
314: Debug.logError(e,
315: "Cannot get OrderHeader from payment preference",
316: module);
317: }
318:
319: // get the store for the order
320: GenericValue productStore = null;
321: if (orderHeader != null) {
322: try {
323: productStore = delegator.findByPrimaryKey(
324: "ProductStore", UtilMisc.toMap(
325: "productStoreId", orderHeader
326: .getString("productStoreId")));
327: } catch (GenericEntityException e) {
328: Debug
329: .logError(
330: e,
331: "Cannot get the ProductStore for the order header",
332: module);
333: }
334: } else {
335: Debug.logWarning("No order header, cannot create payment",
336: module);
337: return null;
338: }
339:
340: if (productStore == null) {
341: Debug.logWarning("No product store, cannot create payment",
342: module);
343: return null;
344: }
345:
346: // set the payToPartyId
347: String payToPartyId = productStore.getString("payToPartyId");
348: if (payToPartyId == null) {
349: Debug.logWarning("No payToPartyId set on ProductStore : "
350: + productStore.getString("productStoreId"), module);
351: return null;
352: }
353:
354: // create the payment
355: Long payId = delegator.getNextSeqId("Payment");
356: GenericValue payment = delegator.makeValue("Payment", UtilMisc
357: .toMap("paymentId", payId.toString()));
358: payment.set("paymentTypeId", "RECEIPT");
359: payment.set("paymentMethodTypeId", orderPaymentPreference
360: .getString("paymentMethodTypeId"));
361: payment.set("paymentPreferenceId", orderPaymentPreference
362: .getString("orderPaymentPreferenceId"));
363: payment.set("amount", orderPaymentPreference
364: .getDouble("maxAmount"));
365: payment.set("statusId", "PMNT_RECEIVED");
366: payment.set("effectiveDate", UtilDateTime.nowTimestamp());
367: payment.set("partyIdTo", payToPartyId);
368: if (paymentRefNumber != null) {
369: payment.set("paymentRefNum", paymentRefNumber);
370: }
371: if (paymentFromId != null) {
372: payment.set("partyIdFrom", paymentFromId);
373: } else {
374: payment.set("partyIdFrom", "_NA_");
375: }
376: if (comments != null) {
377: payment.set("comments", comments);
378: }
379:
380: return payment;
381: }
382:
383: public static boolean releaseInitialOrderHold(
384: LocalDispatcher dispatcher, String orderId) {
385: // get the delegator from the dispatcher
386: GenericDelegator delegator = dispatcher.getDelegator();
387:
388: // find the workEffortId for this order
389: List workEfforts = null;
390: try {
391: workEfforts = delegator.findByAnd("WorkEffort", UtilMisc
392: .toMap("currentStatusId", "WF_SUSPENDED",
393: "sourceReferenceId", orderId));
394: } catch (GenericEntityException e) {
395: Debug.logError(e,
396: "Problems getting WorkEffort with order ref number: "
397: + orderId, module);
398: return false;
399: }
400:
401: if (workEfforts != null) {
402: // attempt to release the order workflow from 'Hold' status (resume workflow)
403: boolean allPass = true;
404: Iterator wei = workEfforts.iterator();
405: while (wei.hasNext()) {
406: GenericValue workEffort = (GenericValue) wei.next();
407: String workEffortId = workEffort
408: .getString("workEffortId");
409: try {
410: if (workEffort.getString("currentStatusId").equals(
411: "WF_SUSPENDED")) {
412: WorkflowClient client = new WorkflowClient(
413: dispatcher.getDispatchContext());
414: client.resume(workEffortId);
415: } else {
416: Debug.logVerbose("Current : --{" + workEffort
417: + "}-- not resuming", module);
418: }
419: } catch (WfException e) {
420: Debug.logError(e, "Problem resuming activity : "
421: + workEffortId, module);
422: allPass = false;
423: }
424: }
425: return allPass;
426: } else {
427: Debug.logWarning("No WF found for order ID : " + orderId,
428: module);
429: }
430: return false;
431: }
432:
433: public static boolean abortOrderProcessing(
434: LocalDispatcher dispatcher, String orderId) {
435: Debug.logInfo("Aborting workflow for order " + orderId, module);
436: GenericDelegator delegator = dispatcher.getDelegator();
437:
438: // find the workEffortId for this order
439: GenericValue workEffort = null;
440: try {
441: List workEfforts = delegator.findByAnd("WorkEffort",
442: UtilMisc.toMap("workEffortTypeId", "WORK_FLOW",
443: "sourceReferenceId", orderId));
444: if (workEfforts != null && workEfforts.size() > 1) {
445: Debug.logWarning(
446: "More then one workflow found for defined order: "
447: + orderId, module);
448: }
449: workEffort = EntityUtil.getFirst(workEfforts);
450: } catch (GenericEntityException e) {
451: Debug.logError(e,
452: "Problems getting WorkEffort with order ref number: "
453: + orderId, module);
454: return false;
455: }
456:
457: if (workEffort != null) {
458: String workEffortId = workEffort.getString("workEffortId");
459: if (workEffort.getString("currentStatusId").equals(
460: "WF_RUNNING")) {
461: Debug.logInfo("WF is running; trying to abort", module);
462: WorkflowClient client = new WorkflowClient(dispatcher
463: .getDispatchContext());
464: try {
465: client.abortProcess(workEffortId);
466: } catch (WfException e) {
467: Debug.logError(e, "Problem aborting workflow",
468: module);
469: return false;
470: }
471: return true;
472: }
473: }
474: return false;
475: }
476: }
|