Source Code Cross Referenced for OrderServices.java in  » ERP-CRM-Financial » SourceTap-CRM » org » ofbiz » order » order » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » ERP CRM Financial » SourceTap CRM » org.ofbiz.order.order 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * $Id: OrderServices.java,v 1.34 2004/03/05 20:30:26 ajzeneski Exp $
0003:         *
0004:         *  Copyright (c) 2001, 2002 The Open For Business Project - www.ofbiz.org
0005:         *
0006:         *  Permission is hereby granted, free of charge, to any person obtaining a
0007:         *  copy of this software and associated documentation files (the "Software"),
0008:         *  to deal in the Software without restriction, including without limitation
0009:         *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
0010:         *  and/or sell copies of the Software, and to permit persons to whom the
0011:         *  Software is furnished to do so, subject to the following conditions:
0012:         *
0013:         *  The above copyright notice and this permission notice shall be included
0014:         *  in all copies or substantial portions of the Software.
0015:         *
0016:         *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
0017:         *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0018:         *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
0019:         *  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
0020:         *  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
0021:         *  OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
0022:         *  THE USE OR OTHER DEALINGS IN THE SOFTWARE.
0023:         */
0024:        package org.ofbiz.order.order;
0025:
0026:        import java.sql.Timestamp;
0027:        import java.text.DecimalFormat;
0028:        import java.text.ParseException;
0029:        import java.util.*;
0030:
0031:        import org.ofbiz.base.util.*;
0032:        import org.ofbiz.common.DataModelConstants;
0033:        import org.ofbiz.entity.GenericDelegator;
0034:        import org.ofbiz.entity.GenericEntityException;
0035:        import org.ofbiz.entity.GenericValue;
0036:        import org.ofbiz.entity.condition.EntityCondition;
0037:        import org.ofbiz.entity.condition.EntityConditionList;
0038:        import org.ofbiz.entity.condition.EntityExpr;
0039:        import org.ofbiz.entity.condition.EntityOperator;
0040:        import org.ofbiz.entity.condition.EntityFieldMap;
0041:        import org.ofbiz.entity.util.EntityListIterator;
0042:        import org.ofbiz.entity.util.EntityUtil;
0043:        import org.ofbiz.entity.util.EntityFindOptions;
0044:        import org.ofbiz.order.shoppingcart.ShoppingCart;
0045:        import org.ofbiz.order.shoppingcart.shipping.ShippingEvents;
0046:        import org.ofbiz.party.contact.ContactHelper;
0047:        import org.ofbiz.product.store.ProductStoreWorker;
0048:        import org.ofbiz.security.Security;
0049:        import org.ofbiz.service.*;
0050:        import org.ofbiz.workflow.WfUtil;
0051:
0052:        /**
0053:         * Order Processing Services
0054:         *
0055:         * @author     <a href="mailto:jaz@ofbiz.org">Andy Zeneski</a>
0056:         * @author     <a href="mailto:cnelson@einnovation.com">Chris Nelson</a>
0057:         * @author     <a href="mailto:jonesde@ofbiz.org">David E. Jones</a>
0058:         * @version    $Revision: 1.34 $
0059:         * @since      2.0
0060:         */
0061:
0062:        public class OrderServices {
0063:
0064:            public static final String module = OrderServices.class.getName();
0065:            public static final String resource = "org.ofbiz.order.order.PackageMessages";
0066:
0067:            /** Service for creating a new order */
0068:            public static Map createOrder(DispatchContext ctx, Map context) {
0069:                Map result = new HashMap();
0070:                GenericDelegator delegator = ctx.getDelegator();
0071:                LocalDispatcher dispatcher = ctx.getDispatcher();
0072:                Security security = ctx.getSecurity();
0073:                List toBeStored = new LinkedList();
0074:                Locale locale = (Locale) context.get("locale");
0075:
0076:                GenericValue userLogin = (GenericValue) context
0077:                        .get("userLogin");
0078:                // check security
0079:                String partyId = ServiceUtil.getPartyIdCheckSecurity(userLogin,
0080:                        security, context, result, "ORDERMGR", "_CREATE");
0081:
0082:                if (result.size() > 0) {
0083:                    return result;
0084:                }
0085:
0086:                // get the order type
0087:                String orderTypeId = (String) context.get("orderTypeId");
0088:                result.put("orderTypeId", orderTypeId);
0089:
0090:                // lookup the order type entity
0091:                GenericValue orderType = null;
0092:                try {
0093:                    orderType = delegator.findByPrimaryKeyCache("OrderType",
0094:                            UtilMisc.toMap("orderTypeId", orderTypeId));
0095:                } catch (GenericEntityException e) {
0096:                    result.put(ModelService.RESPONSE_MESSAGE,
0097:                            ModelService.RESPOND_ERROR);
0098:                    result.put(ModelService.ERROR_MESSAGE,
0099:                            "ERROR: OrderType lookup failed: " + e.toString());
0100:                    return result;
0101:                }
0102:
0103:                // make sure we have a valid order type
0104:                if (orderType == null) {
0105:                    result.put(ModelService.RESPONSE_MESSAGE,
0106:                            ModelService.RESPOND_ERROR);
0107:                    result.put(ModelService.ERROR_MESSAGE,
0108:                            "ERROR: Invalid OrderType");
0109:                    return result;
0110:                }
0111:
0112:                // check to make sure we have something to order
0113:                List orderItems = (List) context.get("orderItems");
0114:
0115:                if (orderItems.size() < 1) {
0116:                    result.put(ModelService.RESPONSE_MESSAGE,
0117:                            ModelService.RESPOND_ERROR);
0118:                    result.put(ModelService.ERROR_MESSAGE, UtilProperties
0119:                            .getMessage(resource, "items.none", locale));
0120:                    return result;
0121:                }
0122:
0123:                // check inventory and other things for each item
0124:                String productStoreId = (String) context.get("productStoreId");
0125:                List errorMessages = new LinkedList();
0126:                Map normalizedItemQuantities = new HashMap();
0127:                Map normalizedItemNames = new HashMap();
0128:                Iterator itemIter = orderItems.iterator();
0129:                java.sql.Timestamp nowTimestamp = UtilDateTime.nowTimestamp();
0130:
0131:                // need to run through the items combining any cases where multiple lines refer to the
0132:                // same product so the inventory check will work correctly
0133:                while (itemIter.hasNext()) {
0134:                    GenericValue orderItem = (GenericValue) itemIter.next();
0135:                    String currentProductId = (String) orderItem
0136:                            .get("productId");
0137:                    if (currentProductId != null) {
0138:                        // only normalize items with a product associated (ignore non-product items)
0139:                        if (normalizedItemQuantities.get(currentProductId) == null) {
0140:                            normalizedItemQuantities.put(currentProductId,
0141:                                    new Double(orderItem.getDouble("quantity")
0142:                                            .doubleValue()));
0143:                            normalizedItemNames.put(currentProductId,
0144:                                    new String(orderItem
0145:                                            .getString("itemDescription")));
0146:                        } else {
0147:                            Double currentQuantity = (Double) normalizedItemQuantities
0148:                                    .get(currentProductId);
0149:                            normalizedItemQuantities.put(currentProductId,
0150:                                    new Double(currentQuantity.doubleValue()
0151:                                            + orderItem.getDouble("quantity")
0152:                                                    .doubleValue()));
0153:                        }
0154:                    }
0155:                }
0156:
0157:                if (!"PURCHASE_ORDER".equals(orderTypeId)
0158:                        && productStoreId == null) {
0159:                    return ServiceUtil
0160:                            .returnError("ERROR: The productStoreId can only be null for purchase orders");
0161:                }
0162:
0163:                Iterator normalizedIter = normalizedItemQuantities.keySet()
0164:                        .iterator();
0165:                while (normalizedIter.hasNext()) {
0166:                    // lookup the product entity for each normalized item; error on products not found
0167:                    String currentProductId = (String) normalizedIter.next();
0168:                    Double currentQuantity = (Double) normalizedItemQuantities
0169:                            .get(currentProductId);
0170:                    String itemName = (String) normalizedItemNames
0171:                            .get(currentProductId);
0172:                    GenericValue product = null;
0173:
0174:                    try {
0175:                        product = delegator.findByPrimaryKeyCache("Product",
0176:                                UtilMisc.toMap("productId", currentProductId));
0177:                    } catch (GenericEntityException e) {
0178:                        String errMsg = UtilProperties.getMessage(resource,
0179:                                "product.not_found",
0180:                                new Object[] { currentProductId }, locale);
0181:                        Debug.logError(e, errMsg, module);
0182:                        errorMessages.add(errMsg);
0183:                        continue;
0184:                    }
0185:
0186:                    if (product == null) {
0187:                        String errMsg = UtilProperties.getMessage(resource,
0188:                                "product.not_found",
0189:                                new Object[] { currentProductId }, locale);
0190:                        Debug.logError(errMsg, module);
0191:                        errorMessages.add(errMsg);
0192:                        continue;
0193:                    }
0194:
0195:                    if ("SALES_ORDER".equals(orderTypeId)
0196:                            || "WORK_ORDER".equals(orderTypeId)) {
0197:                        // check to see if introductionDate hasn't passed yet
0198:                        if (product.get("introductionDate") != null
0199:                                && nowTimestamp.before(product
0200:                                        .getTimestamp("introductionDate"))) {
0201:                            String excMsg = UtilProperties.getMessage(resource,
0202:                                    "product.not_yet_for_sale", new Object[] {
0203:                                            getProductName(product, itemName),
0204:                                            product.getString("productId") },
0205:                                    locale);
0206:                            Debug.logWarning(excMsg, module);
0207:                            errorMessages.add(excMsg);
0208:                            continue;
0209:                        }
0210:                    }
0211:
0212:                    if ("SALES_ORDER".equals(orderTypeId)
0213:                            || "WORK_ORDER".equals(orderTypeId)) {
0214:                        // check to see if salesDiscontinuationDate has passed
0215:                        if (product.get("salesDiscontinuationDate") != null
0216:                                && nowTimestamp
0217:                                        .after(product
0218:                                                .getTimestamp("salesDiscontinuationDate"))) {
0219:                            String excMsg = UtilProperties.getMessage(resource,
0220:                                    "product.no_longer_for_sale", new Object[] {
0221:                                            getProductName(product, itemName),
0222:                                            product.getString("productId") },
0223:                                    locale);
0224:                            Debug.logWarning(excMsg, module);
0225:                            errorMessages.add(excMsg);
0226:                            continue;
0227:                        }
0228:                    }
0229:
0230:                    if ("SALES_ORDER".equals(orderTypeId)
0231:                            || "WORK_ORDER".equals(orderTypeId)) {
0232:                        // check to see if we have inventory available
0233:                        if (ProductStoreWorker.isStoreInventoryRequired(
0234:                                productStoreId, product, delegator)) {
0235:                            if (!ProductStoreWorker.isStoreInventoryAvailable(
0236:                                    productStoreId, currentProductId,
0237:                                    currentQuantity.doubleValue(), delegator,
0238:                                    dispatcher)) {
0239:                                String invErrMsg = UtilProperties.getMessage(
0240:                                        resource, "product.out_of_stock",
0241:                                        new Object[] {
0242:                                                getProductName(product,
0243:                                                        itemName),
0244:                                                currentProductId }, locale);
0245:                                Debug.logWarning(invErrMsg, module);
0246:                                errorMessages.add(invErrMsg);
0247:                                continue;
0248:                            }
0249:                        }
0250:                    }
0251:                }
0252:
0253:                if (errorMessages.size() > 0) {
0254:                    result.put(ModelService.RESPONSE_MESSAGE,
0255:                            ModelService.RESPOND_ERROR);
0256:                    result.put(ModelService.ERROR_MESSAGE_LIST, errorMessages);
0257:                    return result;
0258:                }
0259:
0260:                // the inital status for ALL order types
0261:                String initialStatus = "ORDER_CREATED";
0262:                result.put("statusId", initialStatus);
0263:
0264:                // create the order object
0265:                String orderId = delegator.getNextSeqId("OrderHeader")
0266:                        .toString();
0267:                String billingAccountId = (String) context
0268:                        .get("billingAccountId");
0269:                GenericValue order = delegator.makeValue("OrderHeader",
0270:                        UtilMisc.toMap("orderId", orderId, "orderTypeId",
0271:                                orderTypeId, "orderDate", nowTimestamp,
0272:                                "entryDate", nowTimestamp, "statusId",
0273:                                initialStatus, "billingAccountId",
0274:                                billingAccountId));
0275:
0276:                if (context.get("currencyUom") != null) {
0277:                    order.set("currencyUom", context.get("currencyUom"));
0278:                }
0279:
0280:                if (context.get("firstAttemptOrderId") != null) {
0281:                    order.set("firstAttemptOrderId", context
0282:                            .get("firstAttemptOrderId"));
0283:                }
0284:
0285:                if (context.get("grandTotal") != null) {
0286:                    order.set("grandTotal", context.get("grandTotal"));
0287:                }
0288:
0289:                if (UtilValidate.isNotEmpty((String) context.get("visitId"))) {
0290:                    order.set("visitId", context.get("visitId"));
0291:                }
0292:
0293:                if (UtilValidate.isNotEmpty((String) context
0294:                        .get("productStoreId"))) {
0295:                    order.set("productStoreId", context.get("productStoreId"));
0296:                }
0297:
0298:                if (UtilValidate.isNotEmpty((String) context.get("webSiteId"))) {
0299:                    order.set("webSiteId", context.get("webSiteId"));
0300:                }
0301:
0302:                if (userLogin != null && userLogin.get("userLoginId") != null) {
0303:                    order.set("createdBy", userLogin.getString("userLoginId"));
0304:                }
0305:
0306:                // first try to create the OrderHeader; if this does not fail, continue.
0307:                try {
0308:                    delegator.create(order);
0309:                } catch (GenericEntityException e) {
0310:                    Debug
0311:                            .logError(
0312:                                    e,
0313:                                    "Cannot create OrderHeader entity; problems with insert",
0314:                                    module);
0315:                    result.put(ModelService.RESPONSE_MESSAGE,
0316:                            ModelService.RESPOND_ERROR);
0317:                    result
0318:                            .put(ModelService.ERROR_MESSAGE,
0319:                                    "Order creation failed; please notify customer service.");
0320:                    return result;
0321:                }
0322:
0323:                // create the order status record
0324:                String orderStatusSeqId = delegator.getNextSeqId("OrderStatus")
0325:                        .toString();
0326:                GenericValue orderStatus = delegator.makeValue("OrderStatus",
0327:                        UtilMisc.toMap("orderStatusId", orderStatusSeqId));
0328:                orderStatus.set("orderId", orderId);
0329:                orderStatus.set("statusId", order.getString("statusId"));
0330:                orderStatus.set("statusDatetime", nowTimestamp);
0331:                toBeStored.add(orderStatus);
0332:
0333:                // set the orderId on all adjustments; this list will include order and item adjustments...
0334:                List orderAdjustments = (List) context.get("orderAdjustments");
0335:                if (orderAdjustments != null && orderAdjustments.size() > 0) {
0336:                    Iterator iter = orderAdjustments.iterator();
0337:
0338:                    while (iter.hasNext()) {
0339:                        GenericValue orderAdjustment = (GenericValue) iter
0340:                                .next();
0341:                        Long adjSeqId = delegator
0342:                                .getNextSeqId("OrderAdjustment");
0343:
0344:                        if (adjSeqId == null) {
0345:                            result.put(ModelService.RESPONSE_MESSAGE,
0346:                                    ModelService.RESPOND_ERROR);
0347:                            result
0348:                                    .put(
0349:                                            ModelService.ERROR_MESSAGE,
0350:                                            "ERROR: Could not get next sequence id for OrderAdjustment, cannot create order.");
0351:                            return result;
0352:                        }
0353:                        orderAdjustment.set("orderAdjustmentId", adjSeqId
0354:                                .toString());
0355:                        orderAdjustment.set("orderId", orderId);
0356:
0357:                        if (orderAdjustment.get("orderItemSeqId") == null
0358:                                || orderAdjustment.getString("orderItemSeqId")
0359:                                        .length() == 0) {
0360:                            orderAdjustment.set("orderItemSeqId",
0361:                                    DataModelConstants.SEQ_ID_NA); // set the orderItemSeqId to _NA_ if not alredy set...
0362:                        }
0363:
0364:                        toBeStored.add(orderAdjustment);
0365:                    }
0366:                }
0367:
0368:                // set the order contact mechs
0369:                List orderContactMechs = (List) context
0370:                        .get("orderContactMechs");
0371:                if (orderContactMechs != null && orderContactMechs.size() > 0) {
0372:                    Iterator ocmi = orderContactMechs.iterator();
0373:
0374:                    while (ocmi.hasNext()) {
0375:                        GenericValue ocm = (GenericValue) ocmi.next();
0376:                        ocm.set("orderId", orderId);
0377:                        toBeStored.add(ocm);
0378:                    }
0379:                }
0380:
0381:                // set the order item contact mechs
0382:                List orderItemContactMechs = (List) context
0383:                        .get("orderItemContactMechs");
0384:                if (orderItemContactMechs != null
0385:                        && orderItemContactMechs.size() > 0) {
0386:                    Iterator oicmi = orderItemContactMechs.iterator();
0387:
0388:                    while (oicmi.hasNext()) {
0389:                        GenericValue oicm = (GenericValue) oicmi.next();
0390:                        oicm.set("orderId", orderId);
0391:                        toBeStored.add(oicm);
0392:                    }
0393:                }
0394:
0395:                // set the shipment preferences
0396:                List orderShipmentPreferences = (List) context
0397:                        .get("orderShipmentPreferences");
0398:                if (orderShipmentPreferences != null
0399:                        && orderShipmentPreferences.size() > 0) {
0400:                    Iterator oshprefs = orderShipmentPreferences.iterator();
0401:
0402:                    while (oshprefs.hasNext()) {
0403:                        GenericValue orderShipmentPreference = (GenericValue) oshprefs
0404:                                .next();
0405:                        orderShipmentPreference.set("orderId", orderId);
0406:                        orderShipmentPreference.set("carrierRoleTypeId",
0407:                                "CARRIER");
0408:                        if (orderShipmentPreference.get("orderItemSeqId") == null
0409:                                || orderShipmentPreference.getString(
0410:                                        "orderItemSeqId").length() == 0) {
0411:                            orderShipmentPreference.set("orderItemSeqId",
0412:                                    DataModelConstants.SEQ_ID_NA); // set the orderItemSeqId to _NA_ if not alredy set...
0413:                        }
0414:                        toBeStored.add(orderShipmentPreference);
0415:                    }
0416:                }
0417:
0418:                // set the order items
0419:                Iterator oi = orderItems.iterator();
0420:                while (oi.hasNext()) {
0421:                    GenericValue orderItem = (GenericValue) oi.next();
0422:                    orderItem.set("orderId", orderId);
0423:                    toBeStored.add(orderItem);
0424:
0425:                    // create the item status record
0426:                    String itemStatusId = delegator.getNextSeqId("OrderStatus")
0427:                            .toString();
0428:                    GenericValue itemStatus = delegator.makeValue(
0429:                            "OrderStatus", UtilMisc.toMap("orderStatusId",
0430:                                    itemStatusId));
0431:                    itemStatus.put("statusId", orderItem.get("statusId"));
0432:                    itemStatus.put("orderId", orderId);
0433:                    itemStatus.put("orderItemSeqId", orderItem
0434:                            .get("orderItemSeqId"));
0435:                    itemStatus.put("statusDatetime", nowTimestamp);
0436:                    toBeStored.add(itemStatus);
0437:                }
0438:
0439:                // set the item survey responses
0440:                List surveyResponses = (List) context
0441:                        .get("orderItemSurveyResponses");
0442:                if (surveyResponses != null && surveyResponses.size() > 0) {
0443:                    Iterator oisr = surveyResponses.iterator();
0444:                    while (oisr.hasNext()) {
0445:                        GenericValue surveyResponse = (GenericValue) oisr
0446:                                .next();
0447:                        surveyResponse.set("orderId", orderId);
0448:                        toBeStored.add(surveyResponse);
0449:                    }
0450:                }
0451:
0452:                // set the item price info; NOTE: this must be after the orderItems are stored for referential integrity
0453:                List orderItemPriceInfo = (List) context
0454:                        .get("orderItemPriceInfos");
0455:                if (orderItemPriceInfo != null && orderItemPriceInfo.size() > 0) {
0456:                    Iterator oipii = orderItemPriceInfo.iterator();
0457:
0458:                    while (oipii.hasNext()) {
0459:                        GenericValue oipi = (GenericValue) oipii.next();
0460:                        Long oipiSeqId = delegator
0461:                                .getNextSeqId("OrderItemPriceInfo");
0462:
0463:                        if (oipiSeqId == null) {
0464:                            result.put(ModelService.RESPONSE_MESSAGE,
0465:                                    ModelService.RESPOND_ERROR);
0466:                            result
0467:                                    .put(
0468:                                            ModelService.ERROR_MESSAGE,
0469:                                            "ERROR: Could not get next sequence id for OrderItemPriceInfo, cannot create order.");
0470:                            return result;
0471:                        }
0472:                        oipi.set("orderItemPriceInfoId", oipiSeqId.toString());
0473:                        oipi.set("orderId", orderId);
0474:                        toBeStored.add(oipi);
0475:                    }
0476:                }
0477:
0478:                // store the orderProductPromoUseInfos
0479:                List orderProductPromoUses = (List) context
0480:                        .get("orderProductPromoUses");
0481:                if (orderProductPromoUses != null
0482:                        && orderProductPromoUses.size() > 0) {
0483:                    Iterator orderProductPromoUseIter = orderProductPromoUses
0484:                            .iterator();
0485:                    while (orderProductPromoUseIter.hasNext()) {
0486:                        GenericValue productPromoUse = (GenericValue) orderProductPromoUseIter
0487:                                .next();
0488:                        productPromoUse.set("orderId", orderId);
0489:                        toBeStored.add(productPromoUse);
0490:                    }
0491:                }
0492:
0493:                // define the roles for the order
0494:                List userOrderRoleTypes = null;
0495:                if ("SALES_ORDER".equals(orderTypeId)) {
0496:                    userOrderRoleTypes = UtilMisc.toList("END_USER_CUSTOMER",
0497:                            "SHIP_TO_CUSTOMER", "BILL_TO_CUSTOMER",
0498:                            "PLACING_CUSTOMER");
0499:                } else if ("PURCHASE_ORDER".equals(orderTypeId)) {
0500:                    userOrderRoleTypes = UtilMisc.toList("SHIP_FROM_VENDOR",
0501:                            "BILL_FROM_VENDOR", "SUPPLIER_AGENT");
0502:                } else if ("WORK_ORDER".equals(orderTypeId)) {
0503:                    // TODO: set the work order roles
0504:                } else {
0505:                    // TODO: some default behavior
0506:                }
0507:
0508:                // now add the roles
0509:                if (userOrderRoleTypes != null) {
0510:                    Iterator i = userOrderRoleTypes.iterator();
0511:                    while (i.hasNext()) {
0512:                        String roleType = (String) i.next();
0513:                        String this Party = partyId;
0514:                        if (this Party == null) {
0515:                            this Party = "_NA_"; // will always set these roles so we can query
0516:                        }
0517:                        // make sure the party is in the role before adding
0518:                        toBeStored.add(delegator.makeValue("PartyRole",
0519:                                UtilMisc.toMap("partyId", partyId,
0520:                                        "roleTypeId", roleType)));
0521:                        toBeStored.add(delegator.makeValue("OrderRole",
0522:                                UtilMisc.toMap("orderId", orderId, "partyId",
0523:                                        partyId, "roleTypeId", roleType)));
0524:                    }
0525:                }
0526:
0527:                // set the affiliate -- This is going to be removed...
0528:                String affiliateId = (String) context.get("affiliateId");
0529:                if (UtilValidate.isNotEmpty(affiliateId)) {
0530:                    toBeStored.add(delegator.makeValue("OrderRole", UtilMisc
0531:                            .toMap("orderId", orderId, "partyId", affiliateId,
0532:                                    "roleTypeId", "AFFILIATE")));
0533:                }
0534:
0535:                // set the distributor
0536:                String distributorId = (String) context.get("distributorId");
0537:                if (UtilValidate.isNotEmpty(distributorId)) {
0538:                    toBeStored.add(delegator
0539:                            .makeValue("OrderRole", UtilMisc.toMap("orderId",
0540:                                    orderId, "partyId", distributorId,
0541:                                    "roleTypeId", "DISTRIBUTOR")));
0542:                }
0543:
0544:                // find all parties in role VENDOR associated with WebSite OR ProductStore (where WebSite overrides, if specified), associated first valid with the Order
0545:                if (UtilValidate.isNotEmpty((String) context
0546:                        .get("productStoreId"))) {
0547:                    try {
0548:                        List productStoreRoles = delegator.findByAnd(
0549:                                "ProductStoreRole", UtilMisc.toMap(
0550:                                        "roleTypeId", "VENDOR",
0551:                                        "productStoreId", context
0552:                                                .get("productStoreId")),
0553:                                UtilMisc.toList("-fromDate"));
0554:                        productStoreRoles = EntityUtil.filterByDate(
0555:                                productStoreRoles, true);
0556:                        GenericValue productStoreRole = EntityUtil
0557:                                .getFirst(productStoreRoles);
0558:                        if (productStoreRole != null) {
0559:                            toBeStored.add(delegator.makeValue("OrderRole",
0560:                                    UtilMisc.toMap("orderId", orderId,
0561:                                            "partyId", productStoreRole
0562:                                                    .get("partyId"),
0563:                                            "roleTypeId", "VENDOR")));
0564:                        }
0565:                    } catch (GenericEntityException e) {
0566:                        Debug
0567:                                .logError(
0568:                                        e,
0569:                                        "Error looking up Vendor for the current Product Store",
0570:                                        module);
0571:                    }
0572:
0573:                }
0574:                if (UtilValidate.isNotEmpty((String) context.get("webSiteId"))) {
0575:                    try {
0576:                        List webSiteRoles = delegator.findByAnd("WebSiteRole",
0577:                                UtilMisc.toMap("roleTypeId", "VENDOR",
0578:                                        "webSiteId", context.get("webSiteId")),
0579:                                UtilMisc.toList("-fromDate"));
0580:                        webSiteRoles = EntityUtil.filterByDate(webSiteRoles,
0581:                                true);
0582:                        GenericValue webSiteRole = EntityUtil
0583:                                .getFirst(webSiteRoles);
0584:                        if (webSiteRole != null) {
0585:                            toBeStored.add(delegator.makeValue("OrderRole",
0586:                                    UtilMisc.toMap("orderId", orderId,
0587:                                            "partyId", webSiteRole
0588:                                                    .get("partyId"),
0589:                                            "roleTypeId", "VENDOR")));
0590:                        }
0591:                    } catch (GenericEntityException e) {
0592:                        Debug
0593:                                .logError(
0594:                                        e,
0595:                                        "Error looking up Vendor for the current Web Site",
0596:                                        module);
0597:                    }
0598:
0599:                }
0600:
0601:                // set the order payment preferences
0602:                List paymentPreferences = (List) context
0603:                        .get("orderPaymentPreferences");
0604:                if (paymentPreferences != null && paymentPreferences.size() > 0) {
0605:                    Iterator oppIter = paymentPreferences.iterator();
0606:                    while (oppIter.hasNext()) {
0607:                        GenericValue paymentPreference = (GenericValue) oppIter
0608:                                .next();
0609:                        if (paymentPreference.get("orderPaymentPreferenceId") == null)
0610:                            paymentPreference.set("orderPaymentPreferenceId",
0611:                                    delegator.getNextSeqId(
0612:                                            "OrderPaymentPreference")
0613:                                            .toString());
0614:                        if (paymentPreference.get("statusId") == null)
0615:                            paymentPreference.set("statusId",
0616:                                    "PAYMENT_NOT_RECEIVED");
0617:                        paymentPreference.set("orderId", orderId);
0618:                        toBeStored.add(paymentPreference);
0619:                    }
0620:                }
0621:
0622:                // store the trackingCodeOrder entities
0623:                List trackingCodeOrders = (List) context
0624:                        .get("trackingCodeOrders");
0625:                if (trackingCodeOrders != null && trackingCodeOrders.size() > 0) {
0626:                    Iterator tkcdordIter = trackingCodeOrders.iterator();
0627:                    while (tkcdordIter.hasNext()) {
0628:                        GenericValue trackingCodeOrder = (GenericValue) tkcdordIter
0629:                                .next();
0630:                        trackingCodeOrder.set("orderId", orderId);
0631:                        toBeStored.add(trackingCodeOrder);
0632:                    }
0633:                }
0634:
0635:                try {
0636:                    // store line items, etc so that they will be there for the foreign key checks
0637:                    delegator.storeAll(toBeStored);
0638:
0639:                    if ("SALES_ORDER".equals(orderTypeId)
0640:                            || "WORK_ORDER".equals(orderTypeId)) {
0641:                        // START inventory reservation
0642:                        // decrement inventory available for each item, within the same transaction
0643:                        List resErrorMessages = new LinkedList();
0644:                        Iterator invDecItemIter = orderItems.iterator();
0645:
0646:                        while (invDecItemIter.hasNext()) {
0647:                            GenericValue orderItem = (GenericValue) invDecItemIter
0648:                                    .next();
0649:                            if (orderItem.get("productId") != null) {
0650:                                // only reserve product items; ignore non-product items
0651:                                Double inventoryNotReserved = ProductStoreWorker
0652:                                        .reserveStoreInventory(
0653:                                                productStoreId,
0654:                                                orderItem
0655:                                                        .getString("productId"),
0656:                                                orderItem.getDouble("quantity"),
0657:                                                orderItem.getString("orderId"),
0658:                                                orderItem
0659:                                                        .getString("orderItemSeqId"),
0660:                                                userLogin, delegator,
0661:                                                dispatcher);
0662:
0663:                                if (inventoryNotReserved != null) {
0664:                                    // if inventoryNotReserved is not 0.0 then that is the amount that it couldn't reserve
0665:                                    GenericValue product = null;
0666:
0667:                                    try {
0668:                                        product = delegator
0669:                                                .findByPrimaryKeyCache(
0670:                                                        "Product",
0671:                                                        UtilMisc
0672:                                                                .toMap(
0673:                                                                        "productId",
0674:                                                                        orderItem
0675:                                                                                .getString("productId")));
0676:                                    } catch (GenericEntityException e) {
0677:                                        Debug
0678:                                                .logError(
0679:                                                        e,
0680:                                                        "Error when looking up product in createOrder service, product failed inventory reservation",
0681:                                                        module);
0682:                                    }
0683:                                    String invErrMsg = "The product ";
0684:
0685:                                    if (product != null) {
0686:                                        invErrMsg += getProductName(product,
0687:                                                orderItem);
0688:                                    }
0689:                                    invErrMsg += " with ID "
0690:                                            + orderItem.getString("productId")
0691:                                            + " is no longer in stock. Please try reducing the quantity or removing the product from this order.";
0692:                                    resErrorMessages.add(invErrMsg);
0693:                                }
0694:                            }
0695:                        }
0696:
0697:                        if (resErrorMessages.size() > 0) {
0698:                            result.put(ModelService.RESPONSE_MESSAGE,
0699:                                    ModelService.RESPOND_ERROR);
0700:                            result.put(ModelService.ERROR_MESSAGE_LIST,
0701:                                    resErrorMessages);
0702:                            return result;
0703:                        }
0704:                        // END inventory reservation
0705:                    }
0706:
0707:                    result.put("orderId", orderId);
0708:                    result.put(ModelService.RESPONSE_MESSAGE,
0709:                            ModelService.RESPOND_SUCCESS);
0710:                } catch (GenericEntityException e) {
0711:                    Debug.logError(e, "Problem with reservations", module);
0712:                    result.put(ModelService.RESPONSE_MESSAGE,
0713:                            ModelService.RESPOND_ERROR);
0714:                    result.put(ModelService.ERROR_MESSAGE,
0715:                            "ERROR: Could not create order (write error: "
0716:                                    + e.getMessage() + ").");
0717:                }
0718:
0719:                return result;
0720:            }
0721:
0722:            public static String getProductName(GenericValue product,
0723:                    GenericValue orderItem) {
0724:                if (UtilValidate.isNotEmpty(product.getString("productName"))) {
0725:                    return product.getString("productName");
0726:                } else {
0727:                    return orderItem.getString("itemDescription");
0728:                }
0729:            }
0730:
0731:            public static String getProductName(GenericValue product,
0732:                    String orderItemName) {
0733:                if (UtilValidate.isNotEmpty(product.getString("productName"))) {
0734:                    return product.getString("productName");
0735:                } else {
0736:                    return orderItemName;
0737:                }
0738:            }
0739:
0740:            /** Service for resetting the OrderHeader grandTotal */
0741:            public static Map resetGrandTotal(DispatchContext ctx, Map context) {
0742:                GenericDelegator delegator = ctx.getDelegator();
0743:                //appears to not be used: GenericValue userLogin = (GenericValue) context.get("userLogin");
0744:                String orderId = (String) context.get("orderId");
0745:
0746:                GenericValue orderHeader = null;
0747:                try {
0748:                    orderHeader = delegator.findByPrimaryKey("OrderHeader",
0749:                            UtilMisc.toMap("orderId", orderId));
0750:                } catch (GenericEntityException e) {
0751:                    String errMsg = "ERROR: Could not set grantTotal on OrderHeader entity: "
0752:                            + e.toString();
0753:                    Debug.logError(e, errMsg, module);
0754:                    return ServiceUtil.returnError(errMsg);
0755:                }
0756:
0757:                if (orderHeader != null) {
0758:                    OrderReadHelper orh = new OrderReadHelper(orderHeader);
0759:                    Double currentTotal = orderHeader.getDouble("grandTotal");
0760:                    if (orh.getOrderGrandTotal() != currentTotal.doubleValue()) {
0761:                        orderHeader.set("grandTotal", new Double(orh
0762:                                .getOrderGrandTotal()));
0763:                        try {
0764:                            orderHeader.store();
0765:                        } catch (GenericEntityException e) {
0766:                            String errMsg = "ERROR: Could not set grantTotal on OrderHeader entity: "
0767:                                    + e.toString();
0768:                            Debug.logError(e, errMsg, module);
0769:                            return ServiceUtil.returnError(errMsg);
0770:                        }
0771:                    }
0772:                }
0773:
0774:                return ServiceUtil.returnSuccess();
0775:            }
0776:
0777:            /** Service for setting the OrderHeader grandTotal for all OrderHeaders with no grandTotal */
0778:            public static Map setEmptyGrandTotals(DispatchContext ctx,
0779:                    Map context) {
0780:                GenericDelegator delegator = ctx.getDelegator();
0781:                LocalDispatcher dispatcher = ctx.getDispatcher();
0782:                GenericValue userLogin = (GenericValue) context
0783:                        .get("userLogin");
0784:
0785:                try {
0786:                    EntityListIterator eli = delegator
0787:                            .findListIteratorByCondition("OrderHeader",
0788:                                    new EntityExpr("grandTotal",
0789:                                            EntityOperator.EQUALS, null),
0790:                                    UtilMisc.toList("orderId"), null);
0791:                    GenericValue orderHeader = null;
0792:                    List orderIdList = new LinkedList();
0793:                    while ((orderHeader = (GenericValue) eli.next()) != null) {
0794:                        orderIdList.add(orderHeader.get("orderId"));
0795:                    }
0796:                    eli.close();
0797:
0798:                    Iterator orderIdIter = orderIdList.iterator();
0799:                    while (orderIdIter.hasNext()) {
0800:                        String orderId = (String) orderIdIter.next();
0801:                        Map results = dispatcher.runSync("resetGrandTotal",
0802:                                UtilMisc.toMap("orderId", orderId, "userLogin",
0803:                                        userLogin));
0804:                        if (ServiceUtil.isError(results)) {
0805:                            return ServiceUtil.returnError(null, null, null,
0806:                                    results);
0807:                        }
0808:                    }
0809:                } catch (GenericServiceException e) {
0810:                    String errMsg = "ERROR: Could not set grantTotal on OrderHeader entity: "
0811:                            + e.toString();
0812:                    Debug.logError(e, errMsg, module);
0813:                    return ServiceUtil.returnError(errMsg);
0814:                } catch (GenericEntityException e) {
0815:                    String errMsg = "ERROR: Could not set grantTotal on OrderHeader entity: "
0816:                            + e.toString();
0817:                    Debug.logError(e, errMsg, module);
0818:                    return ServiceUtil.returnError(errMsg);
0819:                }
0820:
0821:                return ServiceUtil.returnSuccess();
0822:            }
0823:
0824:            /** Service for checking and re-clac the tax amount */
0825:            public static Map recalcOrderTax(DispatchContext ctx, Map context) {
0826:                LocalDispatcher dispatcher = ctx.getDispatcher();
0827:                GenericDelegator delegator = ctx.getDelegator();
0828:                String orderId = (String) context.get("orderId");
0829:                GenericValue userLogin = (GenericValue) context
0830:                        .get("userLogin");
0831:
0832:                // check and make sure we have permission to change the order
0833:                Security security = ctx.getSecurity();
0834:                if (!security.hasEntityPermission("ORDERMGR", "_UPDATE",
0835:                        userLogin)) {
0836:                    GenericValue placingCustomer = null;
0837:                    try {
0838:                        Map placingCustomerFields = UtilMisc.toMap("orderId",
0839:                                orderId, "partyId", userLogin
0840:                                        .getString("partyId"), "roleTypeId",
0841:                                "PLACING_CUSTOMER");
0842:                        placingCustomer = delegator.findByPrimaryKey(
0843:                                "OrderRole", placingCustomerFields);
0844:                    } catch (GenericEntityException e) {
0845:                        return ServiceUtil
0846:                                .returnError("ERROR: Cannot get OrderRole entity: "
0847:                                        + e.getMessage());
0848:                    }
0849:                    if (placingCustomer == null)
0850:                        return ServiceUtil
0851:                                .returnError("You do not have permission to change this order's status.");
0852:                }
0853:
0854:                // get the order header
0855:                GenericValue orderHeader = null;
0856:                try {
0857:                    orderHeader = delegator.findByPrimaryKey("OrderHeader",
0858:                            UtilMisc.toMap("orderId", orderId));
0859:                } catch (GenericEntityException e) {
0860:                    return ServiceUtil
0861:                            .returnError("ERROR: Cannot get OrderHeader entity: "
0862:                                    + e.getMessage());
0863:                }
0864:
0865:                if (orderHeader == null) {
0866:                    return ServiceUtil
0867:                            .returnError("ERROR: No valid order header found for orderId : "
0868:                                    + orderId);
0869:                }
0870:
0871:                // remove the tax adjustments
0872:                int removed = 0;
0873:                try {
0874:                    removed = delegator.removeByAnd("OrderAdjustment", UtilMisc
0875:                            .toMap("orderId", orderId, "orderAdjustmentTypeId",
0876:                                    "SALES_TAX"));
0877:                } catch (GenericEntityException e) {
0878:                    Debug.logError(e,
0879:                            "Unable to remove SALES_TAX adjustments for order : "
0880:                                    + orderId, module);
0881:                    return ServiceUtil
0882:                            .returnError("Unable to remove SALES_TAX adjustments");
0883:                }
0884:                Debug.logInfo("Removed : " + removed
0885:                        + " SALES_TAX adjustments for order [" + orderId + "]",
0886:                        module);
0887:
0888:                OrderReadHelper orh = new OrderReadHelper(orderHeader);
0889:                List validOrderItems = orh.getValidOrderItems();
0890:                if (validOrderItems != null) {
0891:                    // prepare the inital lists
0892:                    List products = new ArrayList(validOrderItems.size());
0893:                    List amounts = new ArrayList(validOrderItems.size());
0894:                    List shipAmts = new ArrayList(validOrderItems.size());
0895:
0896:                    // adjustments and total
0897:                    List allAdjustments = orh.getAdjustments();
0898:                    List orderHeaderAdjustments = OrderReadHelper
0899:                            .getOrderHeaderAdjustments(allAdjustments);
0900:                    double orderSubTotal = OrderReadHelper
0901:                            .getOrderItemsSubTotal(validOrderItems,
0902:                                    allAdjustments);
0903:
0904:                    // shipping amount
0905:                    Double orderShipping = new Double(OrderReadHelper
0906:                            .calcOrderAdjustments(orderHeaderAdjustments,
0907:                                    orderSubTotal, false, false, true));
0908:
0909:                    // build up the list of tax calc service parameters
0910:                    for (int i = 0; i < validOrderItems.size(); i++) {
0911:                        GenericValue orderItem = (GenericValue) validOrderItems
0912:                                .get(i);
0913:
0914:                        try {
0915:                            products.add(i, orderItem.getRelatedOne("Product")); // get the product entity
0916:                            amounts.add(i, new Double(OrderReadHelper
0917:                                    .getOrderItemSubTotal(orderItem,
0918:                                            allAdjustments, true, false))); // get the item amount
0919:                            shipAmts.add(i,
0920:                                    new Double(OrderReadHelper
0921:                                            .getOrderItemAdjustmentsTotal(
0922:                                                    orderItem, allAdjustments,
0923:                                                    false, false, true))); // get the shipping amount
0924:                        } catch (GenericEntityException e) {
0925:                            Debug.logError(e,
0926:                                    "Cannot read order item entity : "
0927:                                            + orderItem, module);
0928:                            return ServiceUtil
0929:                                    .returnError("Cannot read the order item entity");
0930:                        }
0931:                    }
0932:
0933:                    // prepare the service context
0934:                    Map serviceContext = UtilMisc.toMap("productStoreId", orh
0935:                            .getProductStoreId(), "itemProductList", products,
0936:                            "itemAmountList", amounts, "itemShippingList",
0937:                            shipAmts, "orderShippingAmount", orderShipping,
0938:                            "shippingAddress", orh.getShippingAddress());
0939:
0940:                    // invoke the calcTax service
0941:                    Map serviceResult = null;
0942:                    try {
0943:                        serviceResult = dispatcher.runSync("calcTax",
0944:                                serviceContext);
0945:                    } catch (GenericServiceException e) {
0946:                        Debug.logError(e, module);
0947:                        return ServiceUtil
0948:                                .returnError("Problem occurred in tax service");
0949:                    }
0950:
0951:                    if (ServiceUtil.isError(serviceResult)) {
0952:                        return ServiceUtil.returnError(ServiceUtil
0953:                                .getErrorMessage(serviceResult));
0954:                    }
0955:
0956:                    // the adjustments (returned in order) from the tax service
0957:                    List orderAdj = (List) serviceResult
0958:                            .get("orderAdjustments");
0959:                    List itemAdj = (List) serviceResult.get("itemAdjustments");
0960:
0961:                    // the toStore List
0962:                    List toStore = new ArrayList();
0963:
0964:                    // set the order adjustments
0965:                    if (orderAdj != null && orderAdj.size() > 0) {
0966:                        Iterator oai = orderAdj.iterator();
0967:                        while (oai.hasNext()) {
0968:                            GenericValue oa = (GenericValue) oai.next();
0969:
0970:                            Long adjSeqId = delegator
0971:                                    .getNextSeqId("OrderAdjustment");
0972:                            oa.set("orderAdjustmentId", adjSeqId.toString());
0973:                            oa.set("orderId", orderId);
0974:                            toStore.add(oa);
0975:                        }
0976:                    }
0977:
0978:                    // set the item adjustments
0979:                    if (itemAdj != null && itemAdj.size() > 0) {
0980:                        for (int i = 0; i < validOrderItems.size(); i++) {
0981:                            GenericValue orderItem = (GenericValue) validOrderItems
0982:                                    .get(i);
0983:                            List itemAdjustments = (List) itemAdj.get(i);
0984:                            Iterator ida = itemAdjustments.iterator();
0985:                            while (ida.hasNext()) {
0986:                                GenericValue ia = (GenericValue) ida.next();
0987:
0988:                                Long adjSeqId = delegator
0989:                                        .getNextSeqId("OrderAdjustment");
0990:                                ia
0991:                                        .set("orderAdjustmentId", adjSeqId
0992:                                                .toString());
0993:                                ia.set("orderId", orderId);
0994:                                ia.set("orderItemSeqId", orderItem
0995:                                        .getString("orderItemSeqId"));
0996:                                toStore.add(ia);
0997:                            }
0998:                        }
0999:                    }
1000:
1001:                    // store the new adjustments
1002:                    try {
1003:                        delegator.storeAll(toStore);
1004:                    } catch (GenericEntityException e) {
1005:                        Debug.logError(e, module);
1006:                        return ServiceUtil
1007:                                .returnError("Unable to update order tax information : "
1008:                                        + orderId);
1009:                    }
1010:                }
1011:
1012:                return ServiceUtil.returnSuccess();
1013:            }
1014:
1015:            /** Service for checking and re-calc the shipping amount */
1016:            public static Map recalcOrderShipping(DispatchContext ctx,
1017:                    Map context) {
1018:                GenericDelegator delegator = ctx.getDelegator();
1019:                String orderId = (String) context.get("orderId");
1020:                GenericValue userLogin = (GenericValue) context
1021:                        .get("userLogin");
1022:
1023:                // check and make sure we have permission to change the order
1024:                Security security = ctx.getSecurity();
1025:                if (!security.hasEntityPermission("ORDERMGR", "_UPDATE",
1026:                        userLogin)) {
1027:                    GenericValue placingCustomer = null;
1028:                    try {
1029:                        Map placingCustomerFields = UtilMisc.toMap("orderId",
1030:                                orderId, "partyId", userLogin
1031:                                        .getString("partyId"), "roleTypeId",
1032:                                "PLACING_CUSTOMER");
1033:                        placingCustomer = delegator.findByPrimaryKey(
1034:                                "OrderRole", placingCustomerFields);
1035:                    } catch (GenericEntityException e) {
1036:                        return ServiceUtil
1037:                                .returnError("ERROR: Cannot get OrderRole entity: "
1038:                                        + e.getMessage());
1039:                    }
1040:                    if (placingCustomer == null)
1041:                        return ServiceUtil
1042:                                .returnError("You do not have permission to change this order's status.");
1043:                }
1044:
1045:                // get the order header
1046:                GenericValue orderHeader = null;
1047:                try {
1048:                    orderHeader = delegator.findByPrimaryKey("OrderHeader",
1049:                            UtilMisc.toMap("orderId", orderId));
1050:                } catch (GenericEntityException e) {
1051:                    return ServiceUtil
1052:                            .returnError("ERROR: Cannot get OrderHeader entity: "
1053:                                    + e.getMessage());
1054:                }
1055:
1056:                if (orderHeader == null) {
1057:                    return ServiceUtil
1058:                            .returnError("ERROR: No valid order header found for orderId : "
1059:                                    + orderId);
1060:                }
1061:
1062:                OrderReadHelper orh = new OrderReadHelper(orderHeader);
1063:                if (Debug.verboseOn()) {
1064:                    Debug.logVerbose("Shippable Total : "
1065:                            + orh.getShippableTotal(), module);
1066:                }
1067:
1068:                Map shippingEstMap = ShippingEvents.getShipEstimate(delegator,
1069:                        orh);
1070:
1071:                Double shippingTotal = null;
1072:                if (orh.getValidOrderItems() == null
1073:                        || orh.getValidOrderItems().size() == 0) {
1074:                    shippingTotal = new Double(0.00);
1075:                } else {
1076:                    shippingTotal = (Double) shippingEstMap
1077:                            .get("shippingTotal");
1078:                }
1079:                if (Debug.verboseOn()) {
1080:                    Debug.logVerbose("New Shipping Total : " + shippingTotal,
1081:                            module);
1082:                }
1083:
1084:                double currentShipping = OrderReadHelper
1085:                        .getAllOrderItemsAdjustmentsTotal(orh.getOrderItems(),
1086:                                orh.getAdjustments(), false, false, true);
1087:                currentShipping += OrderReadHelper.calcOrderAdjustments(orh
1088:                        .getOrderHeaderAdjustments(), orh
1089:                        .getOrderItemsSubTotal(), false, false, true);
1090:
1091:                if (Debug.verboseOn()) {
1092:                    Debug.log("Old Shipping Total : " + currentShipping);
1093:                }
1094:
1095:                List errorMessageList = (List) shippingEstMap
1096:                        .get(ModelService.ERROR_MESSAGE_LIST);
1097:                if (errorMessageList != null) {
1098:                    return ServiceUtil.returnError(errorMessageList);
1099:                }
1100:
1101:                if (shippingTotal.doubleValue() != currentShipping) {
1102:                    // place the difference as a new shipping adjustment
1103:                    Double adjustmentAmount = new Double(shippingTotal
1104:                            .doubleValue()
1105:                            - currentShipping);
1106:                    String adjSeqId = delegator.getNextSeqId("OrderAdjustment")
1107:                            .toString();
1108:                    GenericValue orderAdjustment = delegator.makeValue(
1109:                            "OrderAdjustment", UtilMisc.toMap(
1110:                                    "orderAdjustmentId", adjSeqId));
1111:                    orderAdjustment.set("orderAdjustmentTypeId",
1112:                            "SHIPPING_CHARGES");
1113:                    orderAdjustment.set("amount", adjustmentAmount);
1114:                    orderAdjustment.set("orderId", orh.getOrderId());
1115:                    orderAdjustment.set("orderItemSeqId",
1116:                            DataModelConstants.SEQ_ID_NA);
1117:                    //orderAdjustment.set("comments", "Shipping Re-Calc Adjustment");
1118:                    try {
1119:                        orderAdjustment.create();
1120:                    } catch (GenericEntityException e) {
1121:                        Debug.logError(e,
1122:                                "Problem creating shipping re-calc adjustment : "
1123:                                        + orderAdjustment, module);
1124:                        return ServiceUtil
1125:                                .returnError("ERROR: Cannot create adjustment");
1126:                    }
1127:                }
1128:
1129:                // TODO: re-balance free shipping adjustment
1130:
1131:                return ServiceUtil.returnSuccess();
1132:
1133:            }
1134:
1135:            /** Service for checking to see if an order is fully completed or canceled */
1136:            public static Map checkItemStatus(DispatchContext ctx, Map context) {
1137:                GenericDelegator delegator = ctx.getDelegator();
1138:                LocalDispatcher dispatcher = ctx.getDispatcher();
1139:
1140:                GenericValue userLogin = (GenericValue) context
1141:                        .get("userLogin");
1142:                String orderId = (String) context.get("orderId");
1143:
1144:                // check and make sure we have permission to change the order
1145:                Security security = ctx.getSecurity();
1146:                if (!security.hasEntityPermission("ORDERMGR", "_UPDATE",
1147:                        userLogin)) {
1148:                    GenericValue placingCustomer = null;
1149:                    try {
1150:                        Map placingCustomerFields = UtilMisc.toMap("orderId",
1151:                                orderId, "partyId", userLogin
1152:                                        .getString("partyId"), "roleTypeId",
1153:                                "PLACING_CUSTOMER");
1154:                        placingCustomer = delegator.findByPrimaryKey(
1155:                                "OrderRole", placingCustomerFields);
1156:                    } catch (GenericEntityException e) {
1157:                        return ServiceUtil
1158:                                .returnError("ERROR: Cannot get OrderRole entity: "
1159:                                        + e.getMessage());
1160:                    }
1161:                    if (placingCustomer == null)
1162:                        return ServiceUtil
1163:                                .returnError("You do not have permission to change this order's status.");
1164:                }
1165:
1166:                // get the order header
1167:                GenericValue orderHeader = null;
1168:                try {
1169:                    orderHeader = delegator.findByPrimaryKey("OrderHeader",
1170:                            UtilMisc.toMap("orderId", orderId));
1171:                } catch (GenericEntityException e) {
1172:                    Debug.logError(e, "Cannot get OrderHeader record", module);
1173:                }
1174:                if (orderHeader == null) {
1175:                    Debug.logError("OrderHeader came back as null", module);
1176:                    return ServiceUtil
1177:                            .returnError("Cannot update null order header ["
1178:                                    + orderId + "]");
1179:                }
1180:
1181:                // get the order items
1182:                List orderItems = null;
1183:                try {
1184:                    orderItems = delegator.findByAnd("OrderItem", UtilMisc
1185:                            .toMap("orderId", orderId));
1186:                } catch (GenericEntityException e) {
1187:                    Debug.logError(e, "Cannot get OrderItem records", module);
1188:                    return ServiceUtil
1189:                            .returnError("Problem getting OrderItem records");
1190:                }
1191:
1192:                boolean allCanceled = true;
1193:                boolean allComplete = true;
1194:                boolean allApproved = true;
1195:                if (orderItems != null) {
1196:                    Iterator itemIter = orderItems.iterator();
1197:                    while (itemIter.hasNext()) {
1198:                        GenericValue item = (GenericValue) itemIter.next();
1199:                        String statusId = item.getString("statusId");
1200:                        //Debug.log("Item Status: " + statusId, module);
1201:                        if (!"ITEM_CANCELLED".equals(statusId)) {
1202:                            //Debug.log("Not set to cancel", module);
1203:                            allCanceled = false;
1204:                            if (!"ITEM_COMPLETED".equals(statusId)) {
1205:                                //Debug.log("Not set to complete", module);
1206:                                allComplete = false;
1207:                                if (!"ITEM_APPROVED".equals(statusId)) {
1208:                                    //Debug.log("Not set to approve", module);
1209:                                    allApproved = false;
1210:                                    break;
1211:                                }
1212:                            }
1213:                        }
1214:                    }
1215:
1216:                    // find the next status to set to (if any)
1217:                    String newStatus = null;
1218:                    if (allCanceled) {
1219:                        newStatus = "ORDER_CANCELLED";
1220:                    } else if (allComplete) {
1221:                        newStatus = "ORDER_COMPLETED";
1222:                    } else if (allApproved) {
1223:                        if (!"ORDER_SENT".equals(orderHeader
1224:                                .getString("statusId"))) {
1225:                            newStatus = "ORDER_APPROVED";
1226:                        }
1227:                    }
1228:
1229:                    // now set the new order status
1230:                    if (newStatus != null) {
1231:                        Map serviceContext = UtilMisc.toMap("orderId", orderId,
1232:                                "statusId", newStatus, "userLogin", userLogin);
1233:                        try {
1234:                            Map result = dispatcher.runSync(
1235:                                    "changeOrderStatus", serviceContext);
1236:                        } catch (GenericServiceException e) {
1237:                            Debug
1238:                                    .logError(
1239:                                            e,
1240:                                            "Problem calling the changeOrderStatus service",
1241:                                            module);
1242:                        }
1243:                    }
1244:                } else {
1245:                    Debug.logWarning(
1246:                            "Received NULL for OrderItem records orderId : "
1247:                                    + orderId, module);
1248:                }
1249:
1250:                return ServiceUtil.returnSuccess();
1251:            }
1252:
1253:            /** Service to cancel an order item quantity */
1254:            public static Map cancelOrderItem(DispatchContext ctx, Map context) {
1255:                LocalDispatcher dispatcher = ctx.getDispatcher();
1256:                GenericDelegator delegator = ctx.getDelegator();
1257:
1258:                GenericValue userLogin = (GenericValue) context
1259:                        .get("userLogin");
1260:                Double cancelQuantity = (Double) context.get("cancelQuantity");
1261:                String orderId = (String) context.get("orderId");
1262:                String orderItemSeqId = (String) context.get("orderItemSeqId");
1263:
1264:                // debugging message info
1265:                String itemMsgInfo = orderId + " / " + orderItemSeqId;
1266:
1267:                // check and make sure we have permission to change the order
1268:                Security security = ctx.getSecurity();
1269:                if (!security.hasEntityPermission("ORDERMGR", "_UPDATE",
1270:                        userLogin)) {
1271:                    GenericValue placingCustomer = null;
1272:                    try {
1273:                        Map placingCustomerFields = UtilMisc.toMap("orderId",
1274:                                orderId, "partyId", userLogin
1275:                                        .getString("partyId"), "roleTypeId",
1276:                                "PLACING_CUSTOMER");
1277:                        placingCustomer = delegator.findByPrimaryKey(
1278:                                "OrderRole", placingCustomerFields);
1279:                    } catch (GenericEntityException e) {
1280:                        Debug.logError(e, module);
1281:                        return ServiceUtil
1282:                                .returnError("ERROR: Cannot get OrderRole entity: "
1283:                                        + itemMsgInfo);
1284:                    }
1285:                    if (placingCustomer == null)
1286:                        return ServiceUtil
1287:                                .returnError("You do not have permission to change this order's status.");
1288:                }
1289:
1290:                Map fields = UtilMisc.toMap("orderId", orderId);
1291:                if (orderItemSeqId != null) {
1292:                    fields.put("orderItemSeqId", orderItemSeqId);
1293:                }
1294:
1295:                List orderItems = null;
1296:                try {
1297:                    orderItems = delegator.findByAnd("OrderItem", fields);
1298:                } catch (GenericEntityException e) {
1299:                    Debug.logError(e, module);
1300:                    return ServiceUtil
1301:                            .returnError("ERROR: Cannot get OrderItem entity: "
1302:                                    + itemMsgInfo);
1303:                }
1304:
1305:                if (orderItems != null && orderItems.size() > 0) {
1306:                    Iterator itemsIterator = orderItems.iterator();
1307:                    while (itemsIterator.hasNext()) {
1308:                        GenericValue orderItem = (GenericValue) itemsIterator
1309:                                .next();
1310:                        if (orderItem == null) {
1311:                            ServiceUtil
1312:                                    .returnError("ERROR: Cannot cancel item; item not found : "
1313:                                            + itemMsgInfo);
1314:                        }
1315:
1316:                        Double quantity = orderItem.getDouble("quantity");
1317:                        Double cancelQty = orderItem
1318:                                .getDouble("cancelQuantity");
1319:                        if (quantity == null)
1320:                            quantity = new Double(0.0);
1321:                        if (cancelQty == null)
1322:                            cancelQty = new Double(0.0);
1323:                        Double this CancelQty = null;
1324:                        if (cancelQuantity != null) {
1325:                            this CancelQty = new Double(cancelQuantity
1326:                                    .doubleValue());
1327:                        } else {
1328:                            this CancelQty = new Double(quantity.doubleValue());
1329:                        }
1330:                        orderItem.set("cancelQuantity", this CancelQty);
1331:                        try {
1332:                            orderItem.store();
1333:                        } catch (GenericEntityException e) {
1334:                            Debug.logError(e, module);
1335:                            return ServiceUtil
1336:                                    .returnError("Unable to set cancel quantity : "
1337:                                            + itemMsgInfo);
1338:                        }
1339:                        if (this CancelQty.doubleValue() >= quantity
1340:                                .doubleValue()) {
1341:                            // all items are cancelled -- mark the item as cancelled
1342:                            Map statusCtx = UtilMisc.toMap("orderId", orderId,
1343:                                    "orderItemSeqId", orderItemSeqId,
1344:                                    "statusId", "ITEM_CANCELLED", "userLogin",
1345:                                    userLogin);
1346:                            try {
1347:                                dispatcher.runSyncIgnore(
1348:                                        "changeOrderItemStatus", statusCtx);
1349:                            } catch (GenericServiceException e) {
1350:                                Debug.logError(e, module);
1351:                                return ServiceUtil
1352:                                        .returnError("Unable to cancel order line : "
1353:                                                + itemMsgInfo);
1354:                            }
1355:                        } else {
1356:                            // reverse the inventory reservation
1357:                            Map invCtx = UtilMisc.toMap("orderId", orderId,
1358:                                    "orderItemSeqId", orderItemSeqId,
1359:                                    "cancelQuantity", this CancelQty,
1360:                                    "userLogin", userLogin);
1361:                            try {
1362:                                dispatcher.runSyncIgnore(
1363:                                        "cancelOrderItemInvResQty", invCtx);
1364:                            } catch (GenericServiceException e) {
1365:                                Debug.logError(e, module);
1366:                                return ServiceUtil
1367:                                        .returnError("Unable to update inventory reservations : "
1368:                                                + itemMsgInfo);
1369:                            }
1370:                        }
1371:                    }
1372:                }
1373:
1374:                return ServiceUtil.returnSuccess();
1375:            }
1376:
1377:            /** Service for changing the status on order item(s) */
1378:            public static Map setItemStatus(DispatchContext ctx, Map context) {
1379:                GenericDelegator delegator = ctx.getDelegator();
1380:
1381:                GenericValue userLogin = (GenericValue) context
1382:                        .get("userLogin");
1383:                String orderId = (String) context.get("orderId");
1384:                String orderItemSeqId = (String) context.get("orderItemSeqId");
1385:                String fromStatusId = (String) context.get("fromStatusId");
1386:                String statusId = (String) context.get("statusId");
1387:
1388:                // check and make sure we have permission to change the order
1389:                Security security = ctx.getSecurity();
1390:                if (!security.hasEntityPermission("ORDERMGR", "_UPDATE",
1391:                        userLogin)) {
1392:                    GenericValue placingCustomer = null;
1393:                    try {
1394:                        Map placingCustomerFields = UtilMisc.toMap("orderId",
1395:                                orderId, "partyId", userLogin
1396:                                        .getString("partyId"), "roleTypeId",
1397:                                "PLACING_CUSTOMER");
1398:                        placingCustomer = delegator.findByPrimaryKey(
1399:                                "OrderRole", placingCustomerFields);
1400:                    } catch (GenericEntityException e) {
1401:                        return ServiceUtil
1402:                                .returnError("ERROR: Cannot get OrderRole entity: "
1403:                                        + e.getMessage());
1404:                    }
1405:                    if (placingCustomer == null)
1406:                        return ServiceUtil
1407:                                .returnError("You do not have permission to change this order's status.");
1408:                }
1409:
1410:                Map fields = UtilMisc.toMap("orderId", orderId);
1411:                if (orderItemSeqId != null)
1412:                    fields.put("orderItemSeqId", orderItemSeqId);
1413:                if (fromStatusId != null)
1414:                    fields.put("statusId", fromStatusId);
1415:
1416:                List orderItems = null;
1417:                try {
1418:                    orderItems = delegator.findByAnd("OrderItem", fields);
1419:                } catch (GenericEntityException e) {
1420:                    return ServiceUtil
1421:                            .returnError("ERROR: Cannot get OrderItem entity: "
1422:                                    + e.getMessage());
1423:                }
1424:
1425:                if (orderItems != null && orderItems.size() > 0) {
1426:                    List toBeStored = new ArrayList();
1427:                    Iterator itemsIterator = orderItems.iterator();
1428:                    while (itemsIterator.hasNext()) {
1429:                        GenericValue orderItem = (GenericValue) itemsIterator
1430:                                .next();
1431:                        if (orderItem == null)
1432:                            ServiceUtil
1433:                                    .returnError("ERROR: Cannot change item status; item not found.");
1434:                        if (Debug.verboseOn())
1435:                            Debug
1436:                                    .logVerbose(
1437:                                            "[OrderServices.setItemStatus] : Status Change: ["
1438:                                                    + orderId
1439:                                                    + "] ("
1440:                                                    + orderItem
1441:                                                            .getString("orderItemSeqId"),
1442:                                            module);
1443:                        if (Debug.verboseOn())
1444:                            Debug.logVerbose(
1445:                                    "[OrderServices.setIte,Status] : From Status : "
1446:                                            + orderItem.getString("statusId"),
1447:                                    module);
1448:                        if (Debug.verboseOn())
1449:                            Debug.logVerbose(
1450:                                    "[OrderServices.setOrderStatus] : To Status : "
1451:                                            + statusId, module);
1452:
1453:                        if (orderItem.getString("statusId").equals(statusId)) {
1454:                            continue;
1455:                        }
1456:
1457:                        try {
1458:                            Map statusFields = UtilMisc.toMap("statusId",
1459:                                    orderItem.getString("statusId"),
1460:                                    "statusIdTo", statusId);
1461:                            GenericValue statusChange = delegator
1462:                                    .findByPrimaryKeyCache("StatusValidChange",
1463:                                            statusFields);
1464:
1465:                            if (statusChange == null) {
1466:                                Debug.logWarning("Item status not changed "
1467:                                        + orderItem.getString("statusId")
1468:                                        + " -> " + statusId
1469:                                        + " is not a valid change.", module);
1470:                                continue;
1471:                            }
1472:                        } catch (GenericEntityException e) {
1473:                            return ServiceUtil
1474:                                    .returnError("ERROR: Could not change item status: "
1475:                                            + e.getMessage());
1476:                        }
1477:
1478:                        orderItem.set("statusId", statusId);
1479:                        toBeStored.add(orderItem);
1480:
1481:                        // now create a status change
1482:                        Map changeFields = new HashMap();
1483:                        changeFields.put("orderStatusId", delegator
1484:                                .getNextSeqId("OrderStatus").toString());
1485:                        changeFields.put("statusId", statusId);
1486:                        changeFields.put("orderId", orderId);
1487:                        changeFields.put("orderItemSeqId", orderItem
1488:                                .getString("orderItemSeqId"));
1489:                        changeFields.put("statusDatetime", UtilDateTime
1490:                                .nowTimestamp());
1491:                        GenericValue orderStatus = delegator.makeValue(
1492:                                "OrderStatus", changeFields);
1493:                        toBeStored.add(orderStatus);
1494:                    }
1495:
1496:                    // store the changes
1497:                    if (toBeStored.size() > 0) {
1498:                        try {
1499:                            delegator.storeAll(toBeStored);
1500:                        } catch (GenericEntityException e) {
1501:                            return ServiceUtil
1502:                                    .returnError("ERROR: Cannot store status changes: "
1503:                                            + e.getMessage());
1504:                        }
1505:                    }
1506:
1507:                }
1508:
1509:                return ServiceUtil.returnSuccess();
1510:            }
1511:
1512:            /** Service for changing the status on an order header */
1513:            public static Map setOrderStatus(DispatchContext ctx, Map context) {
1514:                Map result = new HashMap();
1515:                GenericDelegator delegator = ctx.getDelegator();
1516:
1517:                GenericValue userLogin = (GenericValue) context
1518:                        .get("userLogin");
1519:                String orderId = (String) context.get("orderId");
1520:                String statusId = (String) context.get("statusId");
1521:
1522:                // check and make sure we have permission to change the order
1523:                Security security = ctx.getSecurity();
1524:                if (!security.hasEntityPermission("ORDERMGR", "_UPDATE",
1525:                        userLogin)) {
1526:                    GenericValue placingCustomer = null;
1527:                    try {
1528:                        Map placingCustomerFields = UtilMisc.toMap("orderId",
1529:                                orderId, "partyId", userLogin
1530:                                        .getString("partyId"), "roleTypeId",
1531:                                "PLACING_CUSTOMER");
1532:                        placingCustomer = delegator.findByPrimaryKey(
1533:                                "OrderRole", placingCustomerFields);
1534:                    } catch (GenericEntityException e) {
1535:                        return ServiceUtil
1536:                                .returnError("ERROR: Cannot get OrderRole entity: "
1537:                                        + e.getMessage());
1538:                    }
1539:                    if (placingCustomer == null)
1540:                        return ServiceUtil
1541:                                .returnError("You do not have permission to change this order's status.");
1542:                }
1543:
1544:                try {
1545:                    GenericValue orderHeader = delegator.findByPrimaryKey(
1546:                            "OrderHeader", UtilMisc.toMap("orderId", orderId));
1547:
1548:                    if (orderHeader == null) {
1549:                        result.put(ModelService.RESPONSE_MESSAGE,
1550:                                ModelService.RESPOND_ERROR);
1551:                        result
1552:                                .put(ModelService.ERROR_MESSAGE,
1553:                                        "ERROR: Could not change order status; order cannot be found.");
1554:                        return result;
1555:                    }
1556:                    if (Debug.verboseOn())
1557:                        Debug.logVerbose(
1558:                                "[OrderServices.setOrderStatus] : From Status : "
1559:                                        + orderHeader.getString("statusId"),
1560:                                module);
1561:                    if (Debug.verboseOn())
1562:                        Debug.logVerbose(
1563:                                "[OrderServices.setOrderStatus] : To Status : "
1564:                                        + statusId, module);
1565:
1566:                    if (orderHeader.getString("statusId").equals(statusId)) {
1567:                        result.put(ModelService.RESPONSE_MESSAGE,
1568:                                ModelService.RESPOND_SUCCESS);
1569:                        return result;
1570:                    }
1571:                    try {
1572:                        Map statusFields = UtilMisc.toMap("statusId",
1573:                                orderHeader.getString("statusId"),
1574:                                "statusIdTo", statusId);
1575:                        GenericValue statusChange = delegator
1576:                                .findByPrimaryKeyCache("StatusValidChange",
1577:                                        statusFields);
1578:
1579:                        if (statusChange == null) {
1580:                            result.put(ModelService.RESPONSE_MESSAGE,
1581:                                    ModelService.RESPOND_ERROR);
1582:                            result
1583:                                    .put(ModelService.ERROR_MESSAGE,
1584:                                            "ERROR: Could not change order status; status is not a valid change.");
1585:                            return result;
1586:                        }
1587:                    } catch (GenericEntityException e) {
1588:                        result.put(ModelService.RESPONSE_MESSAGE,
1589:                                ModelService.RESPOND_ERROR);
1590:                        result.put(ModelService.ERROR_MESSAGE,
1591:                                "ERROR: Could not change order status ("
1592:                                        + e.getMessage() + ").");
1593:                        return result;
1594:                    }
1595:
1596:                    // update the current status
1597:                    orderHeader.set("statusId", statusId);
1598:
1599:                    // now create a status change
1600:                    Map fields = new HashMap();
1601:                    fields.put("orderStatusId", delegator.getNextSeqId(
1602:                            "OrderStatus").toString());
1603:                    fields.put("statusId", statusId);
1604:                    fields.put("orderId", orderId);
1605:                    fields.put("statusDatetime", UtilDateTime.nowTimestamp());
1606:                    GenericValue orderStatus = delegator.makeValue(
1607:                            "OrderStatus", fields);
1608:                    List toBeStored = new ArrayList();
1609:
1610:                    toBeStored.add(orderHeader);
1611:                    toBeStored.add(orderStatus);
1612:                    delegator.storeAll(toBeStored);
1613:                } catch (GenericEntityException e) {
1614:                    result.put(ModelService.RESPONSE_MESSAGE,
1615:                            ModelService.RESPOND_ERROR);
1616:                    result.put(ModelService.ERROR_MESSAGE,
1617:                            "ERROR: Could not change order status ("
1618:                                    + e.getMessage() + ").");
1619:                    return result;
1620:                }
1621:
1622:                // release the inital hold if we are cancelled or approved
1623:                if ("ORDER_CANCELLED".equals(statusId)
1624:                        || "ORDER_APPROVED".equals(statusId)) {
1625:                    OrderChangeHelper.releaseInitialOrderHold(ctx
1626:                            .getDispatcher(), orderId);
1627:
1628:                    // cancel any order processing if we are cancelled
1629:                    if ("ORDER_CANCELLED".equals(statusId)) {
1630:                        OrderChangeHelper.abortOrderProcessing(ctx
1631:                                .getDispatcher(), orderId);
1632:                    }
1633:                }
1634:
1635:                result.put(ModelService.RESPONSE_MESSAGE,
1636:                        ModelService.RESPOND_SUCCESS);
1637:                result.put("orderStatusId", statusId);
1638:                return result;
1639:            }
1640:
1641:            /** Service to update the order tracking number */
1642:            public static Map updateTrackingNumber(DispatchContext dctx,
1643:                    Map context) {
1644:                Map result = new HashMap();
1645:                GenericDelegator delegator = dctx.getDelegator();
1646:                String orderId = (String) context.get("orderId");
1647:                String orderItemSeqId = (String) context.get("orderItemSeqId");
1648:                String trackingNumber = (String) context.get("trackingNumber");
1649:
1650:                if (orderItemSeqId == null || orderItemSeqId.length() == 0)
1651:                    orderItemSeqId = DataModelConstants.SEQ_ID_NA;
1652:                try {
1653:                    GenericValue shipPref = delegator.findByPrimaryKey(
1654:                            "OrderShipmentPreference", UtilMisc.toMap(
1655:                                    "orderId", orderId, "orderItemSeqId",
1656:                                    orderItemSeqId));
1657:
1658:                    if (shipPref == null) {
1659:                        result.put(ModelService.RESPONSE_MESSAGE,
1660:                                ModelService.RESPOND_ERROR);
1661:                        result.put(ModelService.ERROR_MESSAGE,
1662:                                "ERROR: No order shipment preference found!");
1663:                    } else {
1664:                        shipPref.set("trackingNumber", trackingNumber);
1665:                        shipPref.store();
1666:                        result.put(ModelService.RESPONSE_MESSAGE,
1667:                                ModelService.RESPOND_SUCCESS);
1668:                    }
1669:                } catch (GenericEntityException e) {
1670:                    Debug.logError(e, module);
1671:                    result.put(ModelService.RESPONSE_MESSAGE,
1672:                            ModelService.RESPOND_ERROR);
1673:                    result.put(ModelService.ERROR_MESSAGE,
1674:                            "ERROR: Could not set tracking number ("
1675:                                    + e.getMessage() + ").");
1676:                }
1677:                return result;
1678:            }
1679:
1680:            /** Service to add a role type to an order */
1681:            public static Map addRoleType(DispatchContext ctx, Map context) {
1682:                Map result = new HashMap();
1683:                GenericDelegator delegator = ctx.getDelegator();
1684:                String orderId = (String) context.get("orderId");
1685:                String partyId = (String) context.get("partyId");
1686:                String roleTypeId = (String) context.get("roleTypeId");
1687:                Boolean removeOld = (Boolean) context.get("removeOld");
1688:
1689:                if (removeOld != null && removeOld.booleanValue()) {
1690:                    try {
1691:                        delegator.removeByAnd("OrderRole", UtilMisc.toMap(
1692:                                "orderId", orderId, "roleTypeId", roleTypeId));
1693:                    } catch (GenericEntityException e) {
1694:                        result.put(ModelService.RESPONSE_MESSAGE,
1695:                                ModelService.RESPOND_ERROR);
1696:                        result.put(ModelService.ERROR_MESSAGE,
1697:                                "ERROR: Could not remove old roles ("
1698:                                        + e.getMessage() + ").");
1699:                        return result;
1700:                    }
1701:                }
1702:
1703:                Map fields = UtilMisc.toMap("orderId", orderId, "partyId",
1704:                        partyId, "roleTypeId", roleTypeId);
1705:
1706:                try {
1707:                    // first check and see if we are already there; if so, just return success
1708:                    GenericValue testValue = delegator.findByPrimaryKey(
1709:                            "OrderRole", fields);
1710:                    if (testValue != null) {
1711:                        ServiceUtil.returnSuccess();
1712:                    } else {
1713:                        GenericValue value = delegator.makeValue("OrderRole",
1714:                                fields);
1715:                        delegator.create(value);
1716:                    }
1717:                } catch (GenericEntityException e) {
1718:                    result.put(ModelService.RESPONSE_MESSAGE,
1719:                            ModelService.RESPOND_ERROR);
1720:                    result.put(ModelService.ERROR_MESSAGE,
1721:                            "ERROR: Could not add role to order ("
1722:                                    + e.getMessage() + ").");
1723:                    return result;
1724:                }
1725:                result.put(ModelService.RESPONSE_MESSAGE,
1726:                        ModelService.RESPOND_SUCCESS);
1727:                return result;
1728:            }
1729:
1730:            /** Service to remove a role type from an order */
1731:            public static Map removeRoleType(DispatchContext ctx, Map context) {
1732:                Map result = new HashMap();
1733:                GenericDelegator delegator = ctx.getDelegator();
1734:                String orderId = (String) context.get("orderId");
1735:                String partyId = (String) context.get("partyId");
1736:                String roleTypeId = (String) context.get("roleTypeId");
1737:                Map fields = UtilMisc.toMap("orderId", orderId, "partyId",
1738:                        partyId, "roleTypeId", roleTypeId);
1739:
1740:                GenericValue testValue = null;
1741:
1742:                try {
1743:                    testValue = delegator.findByPrimaryKey("OrderRole", fields);
1744:                } catch (GenericEntityException e) {
1745:                    result.put(ModelService.RESPONSE_MESSAGE,
1746:                            ModelService.RESPOND_ERROR);
1747:                    result.put(ModelService.ERROR_MESSAGE,
1748:                            "ERROR: Could not add role to order ("
1749:                                    + e.getMessage() + ").");
1750:                    return result;
1751:                }
1752:
1753:                if (testValue == null) {
1754:                    result.put(ModelService.RESPONSE_MESSAGE,
1755:                            ModelService.RESPOND_SUCCESS);
1756:                    return result;
1757:                }
1758:
1759:                try {
1760:                    GenericValue value = delegator.findByPrimaryKey(
1761:                            "OrderRole", fields);
1762:
1763:                    value.remove();
1764:                } catch (GenericEntityException e) {
1765:                    result.put(ModelService.RESPONSE_MESSAGE,
1766:                            ModelService.RESPOND_ERROR);
1767:                    result.put(ModelService.ERROR_MESSAGE,
1768:                            "ERROR: Could not remove role from order ("
1769:                                    + e.getMessage() + ").");
1770:                    return result;
1771:                }
1772:                result.put(ModelService.RESPONSE_MESSAGE,
1773:                        ModelService.RESPOND_SUCCESS);
1774:                return result;
1775:            }
1776:
1777:            /** Service to prepare notification data */
1778:            public static Map prepareOrderEmailData(DispatchContext ctx,
1779:                    Map context) {
1780:                Map result = new HashMap();
1781:                GenericDelegator delegator = ctx.getDelegator();
1782:                String orderId = (String) context.get("orderId");
1783:
1784:                try {
1785:                    GenericValue orderHeader = delegator.findByPrimaryKey(
1786:                            "OrderHeader", UtilMisc.toMap("orderId", orderId));
1787:                    OrderReadHelper orh = new OrderReadHelper(orderHeader);
1788:                    List orderItems = orh.getOrderItems();
1789:                    List orderAdjustments = orh.getAdjustments();
1790:                    List orderHeaderAdjustments = orh
1791:                            .getOrderHeaderAdjustments();
1792:                    double orderSubTotal = orh.getOrderItemsSubTotal();
1793:                    List headerAdjustmentsToShow = orh
1794:                            .getOrderHeaderAdjustmentsToShow();
1795:
1796:                    //templateContext.put("localOrderReadHelper", orh);
1797:                    result.put("orderId", orderId);
1798:                    result.put("orderItemSeqId", context.get("orderItemSeqId"));
1799:                    result.put("orderHeader", orderHeader);
1800:                    result.put("orderItems", orh.getOrderItems());
1801:                    result.put("statusString", orh.getStatusString());
1802:                    result.put("orderAdjustments", orderAdjustments);
1803:                    result
1804:                            .put("orderHeaderAdjustments",
1805:                                    orderHeaderAdjustments);
1806:                    result.put("orderSubTotal", new Double(orderSubTotal));
1807:                    result.put("headerAdjustmentsToShow",
1808:                            headerAdjustmentsToShow);
1809:
1810:                    double shippingAmount = OrderReadHelper
1811:                            .getAllOrderItemsAdjustmentsTotal(orderItems,
1812:                                    orderAdjustments, false, false, true);
1813:                    shippingAmount += OrderReadHelper.calcOrderAdjustments(
1814:                            orderHeaderAdjustments, orderSubTotal, false,
1815:                            false, true);
1816:                    result
1817:                            .put("orderShippingTotal", new Double(
1818:                                    shippingAmount));
1819:
1820:                    double taxAmount = OrderReadHelper
1821:                            .getAllOrderItemsAdjustmentsTotal(orderItems,
1822:                                    orderAdjustments, false, true, false);
1823:                    taxAmount += OrderReadHelper.calcOrderAdjustments(
1824:                            orderHeaderAdjustments, orderSubTotal, false, true,
1825:                            false);
1826:                    result.put("orderTaxTotal", new Double(taxAmount));
1827:                    result.put("orderGrandTotal", new Double(OrderReadHelper
1828:                            .getOrderGrandTotal(orderItems, orderAdjustments)));
1829:
1830:                    List placingCustomerOrderRoles = delegator.findByAnd(
1831:                            "OrderRole", UtilMisc.toMap("orderId", orderId,
1832:                                    "roleTypeId", "PLACING_CUSTOMER"));
1833:                    GenericValue placingCustomerOrderRole = EntityUtil
1834:                            .getFirst(placingCustomerOrderRoles);
1835:                    GenericValue placingCustomerPerson = placingCustomerOrderRole == null ? null
1836:                            : delegator.findByPrimaryKey("Person", UtilMisc
1837:                                    .toMap("partyId", placingCustomerOrderRole
1838:                                            .getString("partyId")));
1839:                    result.put("placingCustomerPerson", placingCustomerPerson);
1840:
1841:                    GenericValue shippingAddress = orh.getShippingAddress();
1842:                    result.put("shippingAddress", shippingAddress);
1843:                    GenericValue billingAccount = orderHeader
1844:                            .getRelatedOne("BillingAccount");
1845:                    result.put("billingAccount", billingAccount);
1846:
1847:                    Iterator orderPaymentPreferences = UtilMisc
1848:                            .toIterator(orderHeader
1849:                                    .getRelated("OrderPaymentPreference"));
1850:                    if (orderPaymentPreferences != null) {
1851:                        List paymentMethods = new ArrayList();
1852:                        while (orderPaymentPreferences.hasNext()) {
1853:                            GenericValue opp = (GenericValue) orderPaymentPreferences
1854:                                    .next();
1855:                            GenericValue paymentMethod = opp
1856:                                    .getRelatedOne("PaymentMethod");
1857:                            if (paymentMethod != null) {
1858:                                paymentMethods.add(paymentMethod);
1859:                            } else {
1860:                                GenericValue paymentMethodType = opp
1861:                                        .getRelatedOne("PaymentMethodType");
1862:                                if (paymentMethodType != null) {
1863:                                    result.put("paymentMethodType",
1864:                                            paymentMethodType);
1865:                                }
1866:                            }
1867:                        }
1868:                        result.put("paymentMethods", paymentMethods);
1869:                    }
1870:
1871:                    Iterator orderShipmentPreferences = UtilMisc
1872:                            .toIterator(orderHeader
1873:                                    .getRelated("OrderShipmentPreference"));
1874:                    if (orderShipmentPreferences != null
1875:                            && orderShipmentPreferences.hasNext()) {
1876:                        GenericValue shipmentPreference = (GenericValue) orderShipmentPreferences
1877:                                .next();
1878:                        result.put("carrierPartyId", shipmentPreference
1879:                                .getString("carrierPartyId"));
1880:                        result.put("shipmentMethodTypeId", shipmentPreference
1881:                                .getString("shipmentMethodTypeId"));
1882:                        GenericValue shipmentMethodType = delegator
1883:                                .findByPrimaryKey(
1884:                                        "ShipmentMethodType",
1885:                                        UtilMisc
1886:                                                .toMap(
1887:                                                        "shipmentMethodTypeId",
1888:                                                        shipmentPreference
1889:                                                                .getString("shipmentMethodTypeId")));
1890:                        result.put("shipMethDescription", shipmentMethodType
1891:                                .getString("description"));
1892:                        result.put("shippingInstructions", shipmentPreference
1893:                                .getString("shippingInstructions"));
1894:                        result.put("maySplit", shipmentPreference
1895:                                .getBoolean("maySplit"));
1896:                        result.put("giftMessage", shipmentPreference
1897:                                .getString("giftMessage"));
1898:                        result.put("isGift", shipmentPreference
1899:                                .getBoolean("isGift"));
1900:                        result.put("trackingNumber", shipmentPreference
1901:                                .getString("trackingNumber"));
1902:                    }
1903:
1904:                    Iterator orderItemPOIter = UtilMisc.toIterator(orderItems);
1905:                    if (orderItemPOIter != null && orderItemPOIter.hasNext()) {
1906:                        GenericValue orderItemPo = (GenericValue) orderItemPOIter
1907:                                .next();
1908:                        result.put("customerPoNumber", orderItemPo
1909:                                .getString("correspondingPoId"));
1910:                    }
1911:
1912:                    // get Shipment tracking info
1913:                    EntityCondition osisCond = new EntityFieldMap(UtilMisc
1914:                            .toMap("orderId", orderId), EntityOperator.AND);
1915:                    List osisOrder = UtilMisc.toList("shipmentId",
1916:                            "shipmentRouteSegmentId", "shipmentPackageSeqId");
1917:                    List osisFields = UtilMisc.toList("shipmentId",
1918:                            "shipmentRouteSegmentId", "carrierPartyId",
1919:                            "shipmentMethodTypeId");
1920:                    osisFields.add("shipmentPackageSeqId");
1921:                    osisFields.add("trackingCode");
1922:                    osisFields.add("boxNumber");
1923:
1924:                    EntityFindOptions osisFindOptions = new EntityFindOptions();
1925:                    osisFindOptions.setDistinct(true);
1926:
1927:                    List orderShipmentInfoSummaryList = null;
1928:                    EntityListIterator osisEli = delegator
1929:                            .findListIteratorByCondition(
1930:                                    "OrderShipmentInfoSummary", osisCond, null,
1931:                                    osisFields, osisOrder, osisFindOptions);
1932:                    if (osisEli != null) {
1933:                        orderShipmentInfoSummaryList = osisEli
1934:                                .getCompleteList();
1935:                        osisEli.close();
1936:                    }
1937:                    result.put("orderShipmentInfoSummaryList",
1938:                            orderShipmentInfoSummaryList);
1939:
1940:                } catch (GenericEntityException e) {
1941:                    Debug.logError(e, "Entity read error", module);
1942:                    ServiceUtil
1943:                            .returnError("Problem with entity lookup, see error log");
1944:                }
1945:                return result;
1946:            }
1947:
1948:            /** Service to email a customer with initial order confirmation */
1949:            public static Map prepareOrderConfirmation(DispatchContext ctx,
1950:                    Map context) {
1951:                context.put("emailType", "PRDS_ODR_CONFIRM");
1952:                return prepareOrderEmail(ctx, context);
1953:            }
1954:
1955:            /** Service to email a customer with order changes */
1956:            public static Map prepareOrderComplete(DispatchContext ctx,
1957:                    Map context) {
1958:                context.put("emailType", "PRDS_ODR_COMPLETE");
1959:                return prepareOrderEmail(ctx, context);
1960:            }
1961:
1962:            /** Service to email a customer with order changes */
1963:            public static Map prepareOrderBackorder(DispatchContext ctx,
1964:                    Map context) {
1965:                context.put("emailType", "PRDS_ODR_BACKORDER");
1966:                return prepareOrderEmail(ctx, context);
1967:            }
1968:
1969:            /** Service to email a customer with order changes */
1970:            public static Map prepareOrderChange(DispatchContext ctx,
1971:                    Map context) {
1972:                context.put("emailType", "PRDS_ODR_CHANGE");
1973:                return prepareOrderEmail(ctx, context);
1974:            }
1975:
1976:            public static Map prepareOrderEmail(DispatchContext ctx, Map context) {
1977:                Map result = new HashMap();
1978:                GenericDelegator delegator = ctx.getDelegator();
1979:                String orderId = (String) context.get("orderId");
1980:                String emailType = (String) context.get("emailType");
1981:                String ofbizHome = System.getProperty("ofbiz.home");
1982:
1983:                // get the order header and store
1984:                GenericValue orderHeader = null;
1985:                try {
1986:                    orderHeader = delegator.findByPrimaryKey("OrderHeader",
1987:                            UtilMisc.toMap("orderId", orderId));
1988:                } catch (GenericEntityException e) {
1989:                    Debug.logError(e, "Problem getting OrderHeader", module);
1990:                }
1991:
1992:                GenericValue productStoreEmail = null;
1993:                if (orderHeader != null) {
1994:                    try {
1995:                        productStoreEmail = delegator.findByPrimaryKey(
1996:                                "ProductStoreEmailSetting", UtilMisc.toMap(
1997:                                        "productStoreId", orderHeader
1998:                                                .get("productStoreId"),
1999:                                        "emailType", emailType));
2000:                    } catch (GenericEntityException e) {
2001:                        Debug.logError(e,
2002:                                "Problem getting the ProductStoreEmailSetting",
2003:                                module);
2004:                    }
2005:                }
2006:
2007:                if (productStoreEmail == null) {
2008:                    return ServiceUtil
2009:                            .returnError("No valid email setting for store");
2010:                }
2011:
2012:                OrderReadHelper orh = new OrderReadHelper(orderHeader);
2013:                String emailString = orh.getOrderEmailString();
2014:
2015:                // prepare the parsed subject
2016:                Map orderEmailData = prepareOrderEmailData(ctx, UtilMisc.toMap(
2017:                        "orderId", orderId));
2018:                String subjectString = productStoreEmail.getString("subject");
2019:                subjectString = FlexibleStringExpander.expandString(
2020:                        subjectString, orderEmailData);
2021:
2022:                result.put("templateName", ofbizHome
2023:                        + productStoreEmail.get("templatePath"));
2024:                result.put("emailType", emailType);
2025:                result.put("subject", subjectString);
2026:                result.put("contentType", productStoreEmail.get("contentType"));
2027:                result.put("sendFrom", productStoreEmail.get("fromAddress"));
2028:                result.put("sendCc", productStoreEmail.get("ccAddress"));
2029:                result.put("sendBcc", productStoreEmail.get("bccAddress"));
2030:                result.put("sendTo", emailString);
2031:                result.put(ModelService.RESPONSE_MESSAGE,
2032:                        ModelService.RESPOND_SUCCESS);
2033:
2034:                return result;
2035:            }
2036:
2037:            /** Service to email order notifications for pending actions */
2038:            public static Map sendProcessNotification(DispatchContext ctx,
2039:                    Map context) {
2040:                //appears to not be used: Map result = new HashMap();
2041:                GenericDelegator delegator = ctx.getDelegator();
2042:                LocalDispatcher dispatcher = ctx.getDispatcher();
2043:                String adminEmailList = (String) context.get("adminEmailList");
2044:                String assignedToUser = (String) context.get("assignedPartyId");
2045:                //appears to not be used: String assignedToRole = (String) context.get("assignedRoleTypeId");
2046:                String workEffortId = (String) context.get("workEffortId");
2047:
2048:                GenericValue workEffort = null;
2049:                GenericValue orderHeader = null;
2050:                //appears to not be used: String assignedEmail = null;
2051:
2052:                // get the order/workflow info
2053:                try {
2054:                    workEffort = delegator.findByPrimaryKey("WorkEffort",
2055:                            UtilMisc.toMap("workEffortId", workEffortId));
2056:                    String sourceReferenceId = workEffort
2057:                            .getString("sourceReferenceId");
2058:                    if (sourceReferenceId != null)
2059:                        orderHeader = delegator.findByPrimaryKey("OrderHeader",
2060:                                UtilMisc.toMap("orderId", sourceReferenceId));
2061:                } catch (GenericEntityException e) {
2062:                    ServiceUtil.returnError("Problem with entity lookup");
2063:                }
2064:
2065:                // find the assigned user's email address(s)
2066:                GenericValue party = null;
2067:                Collection assignedToEmails = null;
2068:                try {
2069:                    party = delegator.findByPrimaryKey("Party", UtilMisc.toMap(
2070:                            "partyId", assignedToUser));
2071:                } catch (GenericEntityException e) {
2072:                    ServiceUtil.returnError("Problem with entity lookup");
2073:                }
2074:                if (party != null)
2075:                    assignedToEmails = ContactHelper.getContactMechByPurpose(
2076:                            party, "PRIMARY_EMAIL", false);
2077:
2078:                Map templateData = new HashMap(context);
2079:                String omgStatusId = WfUtil.getOMGStatus(workEffort
2080:                        .getString("currentStatusId"));
2081:                templateData.putAll(orderHeader);
2082:                templateData.putAll(workEffort);
2083:                templateData.put("omgStatusId", omgStatusId);
2084:
2085:                // get the assignments
2086:                List assignments = null;
2087:                if (workEffort != null) {
2088:                    try {
2089:                        assignments = workEffort
2090:                                .getRelated("WorkEffortPartyAssignment");
2091:                    } catch (GenericEntityException e1) {
2092:                        Debug.logError(e1, "Problems getting assignements",
2093:                                module);
2094:                    }
2095:                }
2096:                templateData.put("assignments", assignments);
2097:
2098:                StringBuffer emailList = new StringBuffer();
2099:                if (assignedToEmails != null) {
2100:                    Iterator aei = assignedToEmails.iterator();
2101:                    while (aei.hasNext()) {
2102:                        GenericValue ct = (GenericValue) aei.next();
2103:                        if (ct != null && ct.get("infoString") != null) {
2104:                            if (emailList.length() > 1)
2105:                                emailList.append(",");
2106:                            emailList.append(ct.getString("infoString"));
2107:                        }
2108:                    }
2109:                }
2110:                if (adminEmailList != null) {
2111:                    if (emailList.length() > 1)
2112:                        emailList.append(",");
2113:                    emailList.append(adminEmailList);
2114:                }
2115:
2116:                // prepare the mail info
2117:                String ofbizHome = System.getProperty("ofbiz.home");
2118:                String templateName = ofbizHome
2119:                        + "/components/order/email/default/emailprocessnotify.ftl";
2120:
2121:                Map sendMailContext = new HashMap();
2122:                sendMailContext.put("sendTo", emailList.toString());
2123:                sendMailContext.put("sendFrom", "workflow@ofbiz.org"); // fixme
2124:                sendMailContext.put("subject", "Workflow Notification");
2125:                sendMailContext.put("templateName", templateName);
2126:                sendMailContext.put("templateData", templateData);
2127:
2128:                try {
2129:                    dispatcher.runAsync("sendGenericNotificationEmail",
2130:                            sendMailContext);
2131:                } catch (GenericServiceException e) {
2132:                    ServiceUtil.returnError("SendMail service failed: "
2133:                            + e.getMessage());
2134:                }
2135:                return ServiceUtil.returnSuccess();
2136:            }
2137:
2138:            /** Service to create an order payment preference */
2139:            public static Map createPaymentPreference(DispatchContext ctx,
2140:                    Map context) {
2141:                Map result = new HashMap();
2142:                GenericDelegator delegator = ctx.getDelegator();
2143:                String orderId = (String) context.get("orderId");
2144:                String paymentMethodTypeId = (String) context
2145:                        .get("paymentMethodTypeId");
2146:                String paymentMethodId = (String) context
2147:                        .get("paymentMethodId");
2148:                Double maxAmount = (Double) context.get("maxAmount");
2149:
2150:                String prefId = null;
2151:                Long newId = delegator.getNextSeqId("OrderPaymentPreference");
2152:
2153:                if (newId == null) {
2154:                    return ServiceUtil
2155:                            .returnError("ERROR: Could not create OrderPaymentPreference (id generation failure)");
2156:                } else {
2157:                    prefId = newId.toString();
2158:                }
2159:
2160:                Map fields = UtilMisc.toMap("orderPaymentPreferenceId", prefId,
2161:                        "orderId", orderId, "paymentMethodTypeId",
2162:                        paymentMethodTypeId, "paymentMethodId",
2163:                        paymentMethodId, "maxAmount", maxAmount);
2164:
2165:                try {
2166:                    GenericValue v = delegator.makeValue(
2167:                            "OrderPaymentPreference", fields);
2168:
2169:                    delegator.create(v);
2170:                } catch (GenericEntityException e) {
2171:                    result.put(ModelService.RESPONSE_MESSAGE,
2172:                            ModelService.RESPOND_ERROR);
2173:                    result.put(ModelService.ERROR_MESSAGE,
2174:                            "ERROR: Could not create OrderPaymentPreference ("
2175:                                    + e.getMessage() + ").");
2176:                    return result;
2177:                }
2178:                result.put("orderPaymentPreferenceId", prefId);
2179:                result.put(ModelService.RESPONSE_MESSAGE,
2180:                        ModelService.RESPOND_SUCCESS);
2181:                return result;
2182:            }
2183:
2184:            /** Service to get order header information as standard results. */
2185:            public static Map getOrderHeaderInformation(DispatchContext dctx,
2186:                    Map context) {
2187:                GenericDelegator delegator = dctx.getDelegator();
2188:                String orderId = (String) context.get("orderId");
2189:
2190:                GenericValue orderHeader = null;
2191:                try {
2192:                    orderHeader = delegator.findByPrimaryKey("OrderHeader",
2193:                            UtilMisc.toMap("orderId", orderId));
2194:                } catch (GenericEntityException e) {
2195:                    Debug.logError(e, "Problem getting order header detial",
2196:                            module);
2197:                    return ServiceUtil.returnError("Cannot get order header : "
2198:                            + e.getMessage());
2199:                }
2200:                if (orderHeader != null) {
2201:                    Map result = ServiceUtil.returnSuccess();
2202:                    result.putAll(orderHeader);
2203:                    return result;
2204:                }
2205:                return ServiceUtil
2206:                        .returnError("Error getting order header information; null");
2207:            }
2208:
2209:            /** Service to get basic order information. */
2210:            public static Map getOrderInformation(DispatchContext dctx,
2211:                    Map context) {
2212:                Map result = new HashMap();
2213:                GenericDelegator delegator = dctx.getDelegator();
2214:                String orderId = (String) context.get("orderId");
2215:
2216:                try {
2217:                    GenericValue orderHeader = delegator.findByPrimaryKeyCache(
2218:                            "OrderHeader", UtilMisc.toMap("orderId", orderId));
2219:                    Collection orderItems = orderHeader
2220:                            .getRelatedCache("OrderItem");
2221:                    OrderReadHelper orh = new OrderReadHelper(orderHeader);
2222:                    String statusString = orh.getStatusString();
2223:                    Double totalItems = new Double(orh
2224:                            .getTotalOrderItemsQuantity());
2225:                    Double totalPrice = new Double(orh.getOrderGrandTotal());
2226:                    GenericValue shipAddress = orh.getShippingAddress();
2227:                    GenericValue billAddress = orh.getBillingAddress();
2228:                    GenericValue billTo = orh.getBillToPerson();
2229:                    String affilId = orh.getAffiliateId();
2230:                    String distId = orh.getDistributorId();
2231:
2232:                    result.put("orderId", orderId);
2233:                    result.put("orderHeader", orderHeader);
2234:                    result.put("orderItems", orderItems);
2235:                    result.put("totalItems", totalItems);
2236:                    result.put("totalPrice", totalPrice);
2237:                    result.put("shippingAddress", shipAddress);
2238:                    result.put("billingAddress", billAddress);
2239:                    result.put("billToPerson", billTo);
2240:                    result.put("affiliateId", affilId);
2241:                    result.put("distributorId", distId);
2242:                    result.put("statusString", statusString);
2243:                } catch (GenericEntityException e) {
2244:                    result.put(ModelService.RESPONSE_MESSAGE,
2245:                            ModelService.RESPOND_ERROR);
2246:                    result.put(ModelService.ERROR_MESSAGE,
2247:                            "ERROR: Could not get order information ("
2248:                                    + e.getMessage() + ").");
2249:                }
2250:                return result;
2251:            }
2252:
2253:            /** Service to get the total shipping for an order. */
2254:            public static Map getOrderShippingAmount(DispatchContext dctx,
2255:                    Map context) {
2256:                GenericDelegator delegator = dctx.getDelegator();
2257:                String orderId = (String) context.get("orderId");
2258:
2259:                GenericValue orderHeader = null;
2260:                try {
2261:                    orderHeader = delegator.findByPrimaryKey("OrderHeader",
2262:                            UtilMisc.toMap("orderId", orderId));
2263:                } catch (GenericEntityException e) {
2264:                    Debug.logError(e, module);
2265:                    return ServiceUtil
2266:                            .returnError("ERROR: Could not get order information ("
2267:                                    + e.getMessage() + ").");
2268:                }
2269:
2270:                Map result = null;
2271:                if (orderHeader != null) {
2272:                    OrderReadHelper orh = new OrderReadHelper(orderHeader);
2273:                    List orderItems = orh.getValidOrderItems();
2274:                    List orderAdjustments = orh.getAdjustments();
2275:                    List orderHeaderAdjustments = orh
2276:                            .getOrderHeaderAdjustments();
2277:                    double orderSubTotal = orh.getOrderItemsSubTotal();
2278:
2279:                    double shippingAmount = OrderReadHelper
2280:                            .getAllOrderItemsAdjustmentsTotal(orderItems,
2281:                                    orderAdjustments, false, false, true);
2282:                    shippingAmount += OrderReadHelper.calcOrderAdjustments(
2283:                            orderHeaderAdjustments, orderSubTotal, false,
2284:                            false, true);
2285:
2286:                    result = ServiceUtil.returnSuccess();
2287:                    result.put("shippingAmount", new Double(shippingAmount));
2288:                } else {
2289:                    result = ServiceUtil
2290:                            .returnError("Unable to find OrderHeader; cannot get shipping amount");
2291:                }
2292:                return result;
2293:            }
2294:
2295:            /** Service to get an order contact mech. */
2296:            public static Map getOrderAddress(DispatchContext dctx, Map context) {
2297:                Map result = new HashMap();
2298:                GenericDelegator delegator = dctx.getDelegator();
2299:                String orderId = (String) context.get("orderId");
2300:                //appears to not be used: GenericValue v = null;
2301:                String purpose[] = { "BILLING_LOCATION", "SHIPPING_LOCATION" };
2302:                String outKey[] = { "billingAddress", "shippingAddress" };
2303:                GenericValue orderHeader = null;
2304:
2305:                try {
2306:                    orderHeader = delegator.findByPrimaryKeyCache(
2307:                            "OrderHeader", UtilMisc.toMap("orderId", orderId));
2308:                    if (orderHeader != null)
2309:                        result.put("orderHeader", orderHeader);
2310:                } catch (GenericEntityException e) {
2311:                    result.put(ModelService.RESPONSE_MESSAGE,
2312:                            ModelService.RESPOND_ERROR);
2313:                    result.put(ModelService.ERROR_MESSAGE,
2314:                            "ERROR: Could not get OrderHeader ("
2315:                                    + e.getMessage() + ").");
2316:                    return result;
2317:                }
2318:                if (orderHeader == null) {
2319:                    result.put(ModelService.RESPONSE_MESSAGE,
2320:                            ModelService.RESPOND_ERROR);
2321:                    result.put(ModelService.ERROR_MESSAGE,
2322:                            "ERROR: Could get the OrderHeader.");
2323:                    return result;
2324:                }
2325:                for (int i = 0; i < purpose.length; i++) {
2326:                    try {
2327:                        GenericValue orderContactMech = EntityUtil
2328:                                .getFirst(orderHeader.getRelatedByAnd(
2329:                                        "OrderContactMech", UtilMisc.toMap(
2330:                                                "contactMechPurposeTypeId",
2331:                                                purpose[i])));
2332:                        GenericValue contactMech = orderContactMech
2333:                                .getRelatedOne("ContactMech");
2334:
2335:                        if (contactMech != null) {
2336:                            result.put(outKey[i], contactMech
2337:                                    .getRelatedOne("PostalAddress"));
2338:                        }
2339:                    } catch (GenericEntityException e) {
2340:                        result.put(ModelService.RESPONSE_MESSAGE,
2341:                                ModelService.RESPOND_ERROR);
2342:                        result.put(ModelService.ERROR_MESSAGE,
2343:                                "ERROR: Problems getting contact mech ("
2344:                                        + e.getMessage() + ").");
2345:                        return result;
2346:                    }
2347:                }
2348:
2349:                result.put("orderId", orderId);
2350:                return result;
2351:            }
2352:
2353:            /** Service to create a order header note. */
2354:            public static Map createOrderNote(DispatchContext dctx, Map context) {
2355:                Map result = new HashMap();
2356:                GenericDelegator delegator = dctx.getDelegator();
2357:                GenericValue userLogin = (GenericValue) context
2358:                        .get("userLogin");
2359:                String noteString = (String) context.get("note");
2360:                String orderId = (String) context.get("orderId");
2361:                Map noteCtx = UtilMisc.toMap("note", noteString, "userLogin",
2362:                        userLogin);
2363:
2364:                // Store the note.
2365:                Map noteRes = org.ofbiz.common.CommonServices.createNote(dctx,
2366:                        noteCtx);
2367:
2368:                if (noteRes.get(ModelService.RESPONSE_MESSAGE).equals(
2369:                        ModelService.RESPOND_ERROR))
2370:                    return noteRes;
2371:
2372:                String noteId = (String) noteRes.get("noteId");
2373:
2374:                if (noteId == null || noteId.length() == 0) {
2375:                    return ServiceUtil
2376:                            .returnError("Problem creating the note, no noteId returned.");
2377:                }
2378:
2379:                // Set the order info
2380:                try {
2381:                    Map fields = UtilMisc.toMap("orderId", orderId, "noteId",
2382:                            noteId);
2383:                    GenericValue v = delegator.makeValue("OrderHeaderNote",
2384:                            fields);
2385:
2386:                    delegator.create(v);
2387:                } catch (GenericEntityException ee) {
2388:                    Debug.logError(ee, module);
2389:                    result.put(ModelService.RESPONSE_MESSAGE,
2390:                            ModelService.RESPOND_ERROR);
2391:                    result.put(ModelService.ERROR_MESSAGE,
2392:                            "Problem associating note with order ("
2393:                                    + ee.getMessage() + ").");
2394:                }
2395:
2396:                return result;
2397:            }
2398:
2399:            /** Null tax calc service. */
2400:            public static Map nullTaxCalc(DispatchContext dctx, Map context) {
2401:                return UtilMisc.toMap("orderAdjustments",
2402:                        UtilMisc.toList(null), "itemAdjustments", UtilMisc
2403:                                .toList(null));
2404:            }
2405:
2406:            /** Simple tax calc service. */
2407:            public static Map simpleTaxCalc(DispatchContext dctx, Map context) {
2408:                GenericDelegator delegator = dctx.getDelegator();
2409:                String productStoreId = (String) context.get("productStoreId");
2410:                List itemProductList = (List) context.get("itemProductList");
2411:                List itemAmountList = (List) context.get("itemAmountList");
2412:                List itemShippingList = (List) context.get("itemShippingList");
2413:                Double orderShippingAmount = (Double) context
2414:                        .get("orderShippingAmount");
2415:                GenericValue shippingAddress = (GenericValue) context
2416:                        .get("shippingAddress");
2417:
2418:                // Simple Tax Calc only uses the state from the address and the SalesTaxLookup entity.
2419:                String countryCode = shippingAddress.getString("countryGeoId");
2420:                String stateCode = shippingAddress
2421:                        .getString("stateProvinceGeoId");
2422:
2423:                // Setup the return lists.
2424:                List orderAdjustments = new ArrayList();
2425:                List itemAdjustments = new ArrayList();
2426:
2427:                // Loop through the products; get the taxCategory; and lookup each in the cache.
2428:                for (int i = 0; i < itemProductList.size(); i++) {
2429:                    GenericValue product = (GenericValue) itemProductList
2430:                            .get(i);
2431:                    Double itemAmount = (Double) itemAmountList.get(i);
2432:                    Double shippingAmount = (Double) itemShippingList.get(i);
2433:                    List taxList = getTaxAmount(delegator, product,
2434:                            productStoreId, countryCode, stateCode, itemAmount
2435:                                    .doubleValue(), shippingAmount
2436:                                    .doubleValue());
2437:                    itemAdjustments.add(taxList);
2438:                }
2439:                if (orderShippingAmount.doubleValue() > 0) {
2440:                    List taxList = getTaxAmount(delegator, null,
2441:                            productStoreId, countryCode, stateCode, 0.00,
2442:                            orderShippingAmount.doubleValue());
2443:                    orderAdjustments.addAll(taxList);
2444:                }
2445:
2446:                Map result = UtilMisc.toMap("orderAdjustments",
2447:                        orderAdjustments, "itemAdjustments", itemAdjustments);
2448:
2449:                return result;
2450:
2451:            }
2452:
2453:            private static List getTaxAmount(GenericDelegator delegator,
2454:                    GenericValue item, String productStoreId,
2455:                    String countryCode, String stateCode, double itemAmount,
2456:                    double shippingAmount) {
2457:                List adjustments = new ArrayList();
2458:
2459:                // store expr
2460:                EntityCondition storeCond = new EntityExpr("productStoreId",
2461:                        EntityOperator.EQUALS, productStoreId);
2462:
2463:                // build the country expressions
2464:                List countryExprs = UtilMisc.toList(new EntityExpr(
2465:                        "countryGeoId", EntityOperator.EQUALS, countryCode),
2466:                        new EntityExpr("countryGeoId", EntityOperator.EQUALS,
2467:                                "_NA_"));
2468:                EntityCondition countryCond = new EntityConditionList(
2469:                        countryExprs, EntityOperator.OR);
2470:
2471:                // build the state expression
2472:                List stateExprs = UtilMisc.toList(
2473:                        new EntityExpr("stateProvinceGeoId",
2474:                                EntityOperator.EQUALS, stateCode),
2475:                        new EntityExpr("stateProvinceGeoId",
2476:                                EntityOperator.EQUALS, "_NA_"));
2477:                EntityCondition stateCond = new EntityConditionList(stateExprs,
2478:                        EntityOperator.OR);
2479:
2480:                // build the tax cat expression
2481:                List taxCatExprs = UtilMisc.toList(new EntityExpr(
2482:                        "taxCategory", EntityOperator.EQUALS, "_NA_"));
2483:                if (item != null && item.get("taxCategory") != null) {
2484:                    taxCatExprs.add(new EntityExpr("taxCategory",
2485:                            EntityOperator.EQUALS, item
2486:                                    .getString("taxCategory")));
2487:                }
2488:                EntityCondition taxCatCond = new EntityConditionList(
2489:                        taxCatExprs, EntityOperator.OR);
2490:
2491:                // build the main condition clause
2492:                List mainExprs = UtilMisc.toList(storeCond, countryCond,
2493:                        stateCond);
2494:                if (taxCatExprs.size() > 1) {
2495:                    mainExprs.add(taxCatCond);
2496:                } else {
2497:                    mainExprs.add(taxCatExprs.get(0));
2498:                }
2499:                EntityCondition mainCondition = new EntityConditionList(
2500:                        mainExprs, EntityOperator.AND);
2501:
2502:                // create the orderby clause
2503:                List orderList = UtilMisc.toList("minPurchase", "fromDate");
2504:
2505:                try {
2506:                    List lookupList = delegator.findByCondition(
2507:                            "SimpleSalesTaxLookup", mainCondition, null,
2508:                            orderList);
2509:                    List filteredList = EntityUtil.filterByDate(lookupList);
2510:
2511:                    if (filteredList.size() == 0) {
2512:                        Debug
2513:                                .logWarning(
2514:                                        "SimpleTaxCalc: No State/TaxCategory pair found (with or without taxCat).",
2515:                                        module);
2516:                        return adjustments;
2517:                    }
2518:
2519:                    // find the right entry(s) based on purchase amount
2520:                    Iterator flIt = filteredList.iterator();
2521:                    while (flIt.hasNext()) {
2522:                        GenericValue taxLookup = (GenericValue) flIt.next();
2523:                        //Debug.logInfo("Testing " + itemAmount + " with : " + taxLookup, module);
2524:                        if (itemAmount >= taxLookup.getDouble("minPurchase")
2525:                                .doubleValue()) {
2526:                            //Debug.logInfo("TaxLookup: " + taxLookup, module);
2527:
2528:                            double taxRate = taxLookup
2529:                                    .get("salesTaxPercentage") != null ? taxLookup
2530:                                    .getDouble("salesTaxPercentage")
2531:                                    .doubleValue()
2532:                                    : 0;
2533:                            double taxable = 0.00;
2534:
2535:                            if (item != null
2536:                                    && (item.get("taxable") == null || (item
2537:                                            .get("taxable") != null && item
2538:                                            .getBoolean("taxable")
2539:                                            .booleanValue()))) {
2540:                                taxable += itemAmount;
2541:                            }
2542:                            if (taxLookup != null
2543:                                    && (taxLookup.get("taxShipping") == null || (taxLookup
2544:                                            .get("taxShipping") != null && taxLookup
2545:                                            .getBoolean("taxShipping")
2546:                                            .booleanValue()))) {
2547:                                taxable += shippingAmount;
2548:                            }
2549:
2550:                            String currencyFormat = UtilProperties
2551:                                    .getPropertyValue("general.properties",
2552:                                            "currency.decimal.format", "##0.00");
2553:                            DecimalFormat formatter = new DecimalFormat(
2554:                                    currencyFormat);
2555:                            double taxTotal = taxable * taxRate;
2556:                            String amountStr = formatter.format(taxTotal);
2557:                            Double taxAmount = null;
2558:                            try {
2559:                                taxAmount = new Double(formatter.parse(
2560:                                        amountStr).doubleValue());
2561:                            } catch (ParseException e) {
2562:                                throw new GeneralException(
2563:                                        "Problem getting parsed amount from string",
2564:                                        e);
2565:                            }
2566:
2567:                            adjustments
2568:                                    .add(delegator
2569:                                            .makeValue(
2570:                                                    "OrderAdjustment",
2571:                                                    UtilMisc
2572:                                                            .toMap(
2573:                                                                    "amount",
2574:                                                                    taxAmount,
2575:                                                                    "orderAdjustmentTypeId",
2576:                                                                    "SALES_TAX",
2577:                                                                    "comments",
2578:                                                                    taxLookup
2579:                                                                            .getString("description"))));
2580:                        }
2581:                    }
2582:                } catch (GenericEntityException e) {
2583:                    Debug.logError(e, "Problems looking up tax rates", module);
2584:                    return new ArrayList();
2585:                } catch (GeneralException e) {
2586:                    Debug.logError(e, "Problems looking up tax rates", module);
2587:                    return new ArrayList();
2588:                }
2589:
2590:                return adjustments;
2591:            }
2592:
2593:            // return / refund services
2594:
2595:            // helper method for sending return notifications
2596:            private static Map sendReturnNotification(DispatchContext ctx,
2597:                    Map context, String emailType) {
2598:                GenericDelegator delegator = ctx.getDelegator();
2599:                LocalDispatcher dispatcher = ctx.getDispatcher();
2600:                GenericValue userLogin = (GenericValue) context
2601:                        .get("userLogin");
2602:                String returnId = (String) context.get("returnId");
2603:
2604:                // get the return header
2605:                GenericValue returnHeader = null;
2606:                try {
2607:                    returnHeader = delegator.findByPrimaryKey("ReturnHeader",
2608:                            UtilMisc.toMap("returnId", returnId));
2609:                } catch (GenericEntityException e) {
2610:                    Debug.logError(e, module);
2611:                    return ServiceUtil
2612:                            .returnError("ERROR: Unable to get ReturnHeader for ID: "
2613:                                    + returnId);
2614:                }
2615:
2616:                // get the return items
2617:                List returnItems = null;
2618:                try {
2619:                    returnItems = returnHeader.getRelated("ReturnItem");
2620:                } catch (GenericEntityException e) {
2621:                    Debug.logError(e, module);
2622:                    return ServiceUtil
2623:                            .returnError("ERROR: Unable to get ReturnItem records from ReturnHeader");
2624:                }
2625:
2626:                // set the email template context
2627:                Map templateContext = UtilMisc.toMap("returnHeader",
2628:                        returnHeader, "returnItems", returnItems);
2629:
2630:                // get the order header -- the first item will determine which product store to use from the order
2631:                String productStoreId = null;
2632:                String emailAddress = null;
2633:                if (returnItems != null) {
2634:                    GenericValue firstItem = EntityUtil.getFirst(returnItems);
2635:                    GenericValue orderHeader = null;
2636:                    try {
2637:                        orderHeader = firstItem.getRelatedOne("OrderHeader");
2638:                    } catch (GenericEntityException e) {
2639:                        Debug.logError(e, module);
2640:                        return ServiceUtil
2641:                                .returnError("ERROR: Unable to get OrderHeader from ReturnItem");
2642:                    }
2643:
2644:                    if (orderHeader != null
2645:                            && UtilValidate.isNotEmpty(orderHeader
2646:                                    .getString("productStoreId"))) {
2647:                        OrderReadHelper orh = new OrderReadHelper(orderHeader);
2648:                        productStoreId = orh.getProductStoreId();
2649:                        emailAddress = orh.getOrderEmailString();
2650:                    }
2651:                }
2652:
2653:                // get the email setting and send the mail
2654:                if (productStoreId != null && productStoreId.length() > 0) {
2655:                    GenericValue emailSetting = null;
2656:                    try {
2657:                        emailSetting = delegator.findByPrimaryKey(
2658:                                "ProductStoreEmailSetting", UtilMisc.toMap(
2659:                                        "productStoreId", productStoreId,
2660:                                        "emailType", emailType));
2661:                    } catch (GenericEntityException e) {
2662:                        Debug.logError(e, module);
2663:                        return ServiceUtil
2664:                                .returnError("ERROR: Unable to locate email setting : "
2665:                                        + productStoreId + " / " + emailType);
2666:                    }
2667:
2668:                    if (emailSetting != null && emailAddress != null) {
2669:                        String subjectString = emailSetting
2670:                                .getString("subject");
2671:                        subjectString = FlexibleStringExpander.expandString(
2672:                                subjectString, templateContext);
2673:
2674:                        Map emailCtx = new HashMap();
2675:                        emailCtx.put("templateName", emailSetting
2676:                                .get("templatePath"));
2677:                        emailCtx.put("templateData", templateContext);
2678:                        emailCtx.put("sendTo", emailAddress);
2679:                        emailCtx.put("contentType", emailSetting
2680:                                .get("contentType"));
2681:                        emailCtx.put("sendFrom", emailSetting
2682:                                .get("fromAddress"));
2683:                        emailCtx.put("sendCc", emailSetting.get("ccAddress"));
2684:                        emailCtx.put("sendBcc", emailSetting.get("bccAddress"));
2685:                        emailCtx.put("subject", subjectString);
2686:                        emailCtx.put("userLogin", userLogin);
2687:
2688:                        // send off the email async so we will retry on failed attempts
2689:                        try {
2690:                            dispatcher.runAsync("sendGenericNotificationEmail",
2691:                                    emailCtx);
2692:                        } catch (GenericServiceException e) {
2693:                            Debug.logError(e, "Problem sending mail", module);
2694:                            return ServiceUtil
2695:                                    .returnError("Problem sending email");
2696:                        }
2697:
2698:                        // all done
2699:                        return ServiceUtil.returnSuccess();
2700:                    }
2701:                }
2702:
2703:                return ServiceUtil
2704:                        .returnError("ERROR: Problem with Product Store email setting : "
2705:                                + productStoreId + " / " + emailType);
2706:            }
2707:
2708:            // return request notification
2709:            public static Map sendReturnAcceptNotification(DispatchContext ctx,
2710:                    Map context) {
2711:                return sendReturnNotification(ctx, context, "PRDS_RTN_ACCEPT");
2712:            }
2713:
2714:            // return complete notification
2715:            public static Map sendReturnCompleteNotification(
2716:                    DispatchContext ctx, Map context) {
2717:                return sendReturnNotification(ctx, context, "PRDS_RTN_COMPLETE");
2718:            }
2719:
2720:            // return cancel notification
2721:            public static Map sendReturnCancelNotification(DispatchContext ctx,
2722:                    Map context) {
2723:                return sendReturnNotification(ctx, context, "PRDS_RTN_CANCEL");
2724:            }
2725:
2726:            // get the returnable quantiy for an order item
2727:            public static Map getReturnableQuantity(DispatchContext ctx,
2728:                    Map context) {
2729:                GenericDelegator delegator = ctx.getDelegator();
2730:                GenericValue orderItem = (GenericValue) context
2731:                        .get("orderItem");
2732:                GenericValue product = null;
2733:                if (orderItem.get("productId") != null) {
2734:                    try {
2735:                        product = orderItem.getRelatedOne("Product");
2736:                    } catch (GenericEntityException e) {
2737:                        Debug.logError(e,
2738:                                "ERROR: Unable to get Product from OrderItem",
2739:                                module);
2740:                    }
2741:                }
2742:
2743:                // check returnable status
2744:                boolean returnable = true;
2745:
2746:                // first check returnable flag
2747:                if (product != null
2748:                        && product.get("returnable") != null
2749:                        && "N"
2750:                                .equalsIgnoreCase(product
2751:                                        .getString("returnable"))) {
2752:                    // the product is not returnable at all
2753:                    returnable = false;
2754:                }
2755:
2756:                // next check support discontinuation
2757:                if (product != null
2758:                        && product.get("supportDiscontinuationDate") != null
2759:                        && !UtilDateTime
2760:                                .nowTimestamp()
2761:                                .before(
2762:                                        product
2763:                                                .getTimestamp("supportDiscontinuationDate"))) {
2764:                    // support discontinued either now or in the past
2765:                    returnable = false;
2766:                }
2767:
2768:                String itemStatus = orderItem.getString("statusId");
2769:                double orderQty = orderItem.getDouble("quantity").doubleValue();
2770:
2771:                // get the returnable quantity
2772:                double returnableQuantity = 0.00;
2773:                if (returnable && itemStatus.equals("ITEM_COMPLETED")) {
2774:                    List returnedItems = null;
2775:                    try {
2776:                        returnedItems = orderItem.getRelated("ReturnItem");
2777:                    } catch (GenericEntityException e) {
2778:                        Debug.logError(e, module);
2779:                        return ServiceUtil
2780:                                .returnError("ERROR: Unable to get return item information");
2781:                    }
2782:                    if (returnedItems == null || returnedItems.size() == 0) {
2783:                        returnableQuantity = orderQty;
2784:                    } else {
2785:                        double returnedQty = 0.00;
2786:                        Iterator ri = returnedItems.iterator();
2787:                        while (ri.hasNext()) {
2788:                            GenericValue returnItem = (GenericValue) ri.next();
2789:                            GenericValue returnHeader = null;
2790:                            try {
2791:                                returnHeader = returnItem
2792:                                        .getRelatedOne("ReturnHeader");
2793:                            } catch (GenericEntityException e) {
2794:                                Debug.logError(e, module);
2795:                                return ServiceUtil
2796:                                        .returnError("ERROR: Unable to get return header from item");
2797:                            }
2798:                            String returnStatus = returnHeader
2799:                                    .getString("statusId");
2800:                            if (!returnStatus.equals("RETURN_CANCELLED")) {
2801:                                returnedQty += returnItem.getDouble(
2802:                                        "returnQuantity").doubleValue();
2803:                            }
2804:                        }
2805:                        if (returnedQty < orderQty) {
2806:                            returnableQuantity = orderQty - returnedQty;
2807:                        }
2808:                    }
2809:                }
2810:
2811:                // get the returnable price
2812:                double returnablePrice = 0.00;
2813:                if (returnableQuantity > 0) {
2814:                    // get all order adjustments
2815:                    List orderAdjustments = null;
2816:                    try {
2817:                        orderAdjustments = delegator.findByAnd(
2818:                                "OrderAdjustment", UtilMisc.toMap("orderId",
2819:                                        orderItem.get("orderId")));
2820:                    } catch (GenericEntityException e) {
2821:                        Debug.logError(e, module);
2822:                        return ServiceUtil
2823:                                .returnError("ERROR: Unable to get order adjustments from item");
2824:                    }
2825:                    returnablePrice = OrderReadHelper.getOrderItemTotal(
2826:                            orderItem, orderAdjustments);
2827:                    returnablePrice = (returnablePrice / orderQty);
2828:                }
2829:
2830:                Map result = ServiceUtil.returnSuccess();
2831:                result
2832:                        .put("returnableQuantity", new Double(
2833:                                returnableQuantity));
2834:                result.put("returnablePrice", new Double(returnablePrice));
2835:                return result;
2836:            }
2837:
2838:            // get a map of returnable items (items not already returned) and quantities
2839:            public static Map getReturnableItems(DispatchContext ctx,
2840:                    Map context) {
2841:                LocalDispatcher dispatcher = ctx.getDispatcher();
2842:                GenericDelegator delegator = ctx.getDelegator();
2843:                String orderId = (String) context.get("orderId");
2844:
2845:                GenericValue orderHeader = null;
2846:                try {
2847:                    orderHeader = delegator.findByPrimaryKey("OrderHeader",
2848:                            UtilMisc.toMap("orderId", orderId));
2849:                } catch (GenericEntityException e) {
2850:                    Debug.logError(e, module);
2851:                    return ServiceUtil
2852:                            .returnError("ERROR: Unable to get order information.");
2853:                }
2854:
2855:                Map returnable = new HashMap();
2856:                if (orderHeader != null) {
2857:                    List orderItems = null;
2858:                    try {
2859:                        orderItems = orderHeader.getRelatedByAnd("OrderItem",
2860:                                UtilMisc.toMap("statusId", "ITEM_COMPLETED"));
2861:                    } catch (GenericEntityException e) {
2862:                        Debug.logError(e, module);
2863:                        return ServiceUtil
2864:                                .returnError("ERROR: Unable to get order item information.");
2865:                    }
2866:                    if (orderItems != null) {
2867:                        Iterator i = orderItems.iterator();
2868:                        while (i.hasNext()) {
2869:                            GenericValue item = (GenericValue) i.next();
2870:                            Map serviceResult = null;
2871:                            try {
2872:                                serviceResult = dispatcher.runSync(
2873:                                        "getReturnableQuantity", UtilMisc
2874:                                                .toMap("orderItem", item));
2875:                            } catch (GenericServiceException e) {
2876:                                Debug.logError(e, module);
2877:                                return ServiceUtil
2878:                                        .returnError("ERROR: Unable to get the item returnable quantity.");
2879:                            }
2880:                            if (serviceResult
2881:                                    .containsKey(ModelService.ERROR_MESSAGE)) {
2882:                                return ServiceUtil
2883:                                        .returnError((String) serviceResult
2884:                                                .get(ModelService.ERROR_MESSAGE));
2885:                            } else {
2886:                                Map returnInfo = new HashMap();
2887:                                returnInfo
2888:                                        .put(
2889:                                                "returnableQuantity",
2890:                                                serviceResult
2891:                                                        .get("returnableQuantity"));
2892:                                returnInfo.put("returnablePrice", serviceResult
2893:                                        .get("returnablePrice"));
2894:                                returnable.put(item, returnInfo);
2895:                            }
2896:                        }
2897:                    } else {
2898:                        return ServiceUtil
2899:                                .returnError("ERROR: No order items found.");
2900:                    }
2901:                } else {
2902:                    return ServiceUtil
2903:                            .returnError("ERROR: Unable to find order header.");
2904:                }
2905:
2906:                Map result = ServiceUtil.returnSuccess();
2907:                result.put("returnableItems", returnable);
2908:                return result;
2909:            }
2910:
2911:            // check return items status and update return header status
2912:            public static Map checkReturnComplete(DispatchContext ctx,
2913:                    Map context) {
2914:                //appears to not be used: LocalDispatcher dispatcher = ctx.getDispatcher();
2915:                GenericDelegator delegator = ctx.getDelegator();
2916:                String returnId = (String) context.get("returnId");
2917:
2918:                GenericValue returnHeader = null;
2919:                List returnItems = null;
2920:                try {
2921:                    returnHeader = delegator.findByPrimaryKey("ReturnHeader",
2922:                            UtilMisc.toMap("returnId", returnId));
2923:                    if (returnHeader != null) {
2924:                        returnItems = returnHeader.getRelated("ReturnItem");
2925:                    }
2926:                } catch (GenericEntityException e) {
2927:                    Debug.logError(e, "Problems looking up return information",
2928:                            module);
2929:                    return ServiceUtil
2930:                            .returnError("Error getting ReturnHeader/Item information");
2931:                }
2932:
2933:                // if already completed just return
2934:                if (returnHeader != null
2935:                        && returnHeader.get("statusId") != null) {
2936:                    String currentStatus = returnHeader.getString("statusId");
2937:                    if ("RETURN_COMPLETED".equals(currentStatus)
2938:                            || "RETURN_CANCELLED".equals(currentStatus)) {
2939:                        return ServiceUtil.returnSuccess();
2940:                    }
2941:                }
2942:
2943:                // now; to be used for all timestamps
2944:                Timestamp now = UtilDateTime.nowTimestamp();
2945:
2946:                List completedItems = new ArrayList();
2947:                if (returnHeader != null && returnItems != null
2948:                        && returnItems.size() > 0) {
2949:                    Iterator itemsIter = returnItems.iterator();
2950:                    while (itemsIter.hasNext()) {
2951:                        GenericValue item = (GenericValue) itemsIter.next();
2952:                        String itemStatus = item != null ? item
2953:                                .getString("statusId") : null;
2954:                        if (itemStatus != null) {
2955:                            // both completed and cancelled items qualify for completed status change
2956:                            if ("RETURN_COMPLETED".equals(itemStatus)
2957:                                    || "RETURN_CANCELLED".equals(itemStatus)) {
2958:                                completedItems.add(item);
2959:                            }
2960:                        }
2961:                    }
2962:
2963:                    // if all items are completed/cancelled these should match
2964:                    if (completedItems.size() == returnItems.size()) {
2965:                        List toStore = new LinkedList();
2966:                        returnHeader.set("statusId", "RETURN_COMPLETED");
2967:                        toStore.add(returnHeader);
2968:
2969:                        // create the status change history and set it to be stored
2970:                        String returnStatusId = delegator.getNextSeqId(
2971:                                "ReturnStatus").toString();
2972:                        GenericValue returnStatus = delegator.makeValue(
2973:                                "ReturnStatus", UtilMisc.toMap(
2974:                                        "returnStatusId", returnStatusId));
2975:                        returnStatus.set("statusId", "RETURN_COMPLETED");
2976:                        returnStatus.set("returnId", returnId);
2977:                        returnStatus.set("statusDatetime", now);
2978:                        toStore.add(returnStatus);
2979:                        try {
2980:                            delegator.storeAll(toStore);
2981:                        } catch (GenericEntityException e) {
2982:                            Debug.logError(e, module);
2983:                            return ServiceUtil
2984:                                    .returnError("ERROR: Unable to create ReturnStatus history");
2985:                        }
2986:                    }
2987:
2988:                }
2989:
2990:                Map result = ServiceUtil.returnSuccess();
2991:                result.put("statusId", returnHeader.get("statusId"));
2992:                return result;
2993:            }
2994:
2995:            // credit (billingAccount) return
2996:            public static Map processCreditReturn(DispatchContext ctx,
2997:                    Map context) {
2998:                LocalDispatcher dispatcher = ctx.getDispatcher();
2999:                GenericDelegator delegator = ctx.getDelegator();
3000:                String returnId = (String) context.get("returnId");
3001:                GenericValue userLogin = (GenericValue) context
3002:                        .get("userLogin");
3003:
3004:                GenericValue returnHeader = null;
3005:                List returnItems = null;
3006:                try {
3007:                    returnHeader = delegator.findByPrimaryKey("ReturnHeader",
3008:                            UtilMisc.toMap("returnId", returnId));
3009:                    if (returnHeader != null) {
3010:                        returnItems = returnHeader.getRelatedByAnd(
3011:                                "ReturnItem", UtilMisc.toMap("returnTypeId",
3012:                                        "RTN_CREDIT"));
3013:                    }
3014:                } catch (GenericEntityException e) {
3015:                    Debug.logError(e, "Problems looking up return information",
3016:                            module);
3017:                    return ServiceUtil
3018:                            .returnError("Error getting ReturnHeader/Item information");
3019:                }
3020:
3021:                if (returnHeader != null && returnItems != null
3022:                        && returnItems.size() > 0) {
3023:                    String billingAccountId = returnHeader
3024:                            .getString("billingAccountId");
3025:                    String fromPartyId = returnHeader.getString("fromPartyId");
3026:                    if (billingAccountId == null) {
3027:                        // create new BillingAccount w/ 0 balance
3028:                        try {
3029:                            Map newBa = dispatcher.runSync(
3030:                                    "createBillingAccount", UtilMisc.toMap(
3031:                                            "accountLimit", new Double(0.00),
3032:                                            "description", "Credit Account",
3033:                                            "userLogin", userLogin));
3034:                            if (!newBa.get(ModelService.RESPONSE_MESSAGE)
3035:                                    .equals(ModelService.RESPOND_ERROR)) {
3036:                                billingAccountId = (String) newBa
3037:                                        .get("billingAccountId");
3038:                                if (billingAccountId != null) {
3039:                                    // set the role on the account
3040:                                    Map newBaR = dispatcher.runSync(
3041:                                            "createBillingAccountRole",
3042:                                            UtilMisc.toMap("billingAccountId",
3043:                                                    billingAccountId,
3044:                                                    "partyId", fromPartyId,
3045:                                                    "roleTypeId",
3046:                                                    "BILL_TO_CUSTOMER",
3047:                                                    "userLogin", userLogin));
3048:                                    if (newBaR.get(
3049:                                            ModelService.RESPONSE_MESSAGE)
3050:                                            .equals(ModelService.RESPOND_ERROR)) {
3051:                                        Debug
3052:                                                .logError(
3053:                                                        "Error with createBillingAccountRole: "
3054:                                                                + newBaR
3055:                                                                        .get(ModelService.ERROR_MESSAGE),
3056:                                                        module);
3057:                                        return ServiceUtil
3058:                                                .returnError("Error with createBillingAccountRole: "
3059:                                                        + newBaR
3060:                                                                .get(ModelService.ERROR_MESSAGE));
3061:                                    }
3062:                                }
3063:                            } else {
3064:                                Debug
3065:                                        .logError(
3066:                                                "Error with createBillingAccount: "
3067:                                                        + newBa
3068:                                                                .get(ModelService.ERROR_MESSAGE),
3069:                                                module);
3070:                                return ServiceUtil
3071:                                        .returnError("Error with createBillingAccount: "
3072:                                                + newBa
3073:                                                        .get(ModelService.ERROR_MESSAGE));
3074:                            }
3075:                        } catch (GenericServiceException e) {
3076:                            Debug.logError(e,
3077:                                    "Problems creating BillingAccount", module);
3078:                            return ServiceUtil
3079:                                    .returnError("Problems creating billing account");
3080:                        }
3081:                    }
3082:
3083:                    // double check; make sure we have a billingAccount
3084:                    if (billingAccountId == null) {
3085:                        Debug
3086:                                .logError(
3087:                                        "No available billing account, none was created",
3088:                                        module);
3089:                        return ServiceUtil
3090:                                .returnError("No available billing account");
3091:                    }
3092:
3093:                    // now; to be used for all timestamps
3094:                    Timestamp now = UtilDateTime.nowTimestamp();
3095:
3096:                    // start the response creation
3097:                    String itemResponseId = delegator.getNextSeqId(
3098:                            "ReturnItemResponse").toString();
3099:                    GenericValue itemResponse = delegator.makeValue(
3100:                            "ReturnItemResponse", UtilMisc.toMap(
3101:                                    "returnItemResponseId", itemResponseId));
3102:
3103:                    // need a total for the credit
3104:                    List toBeStored = new ArrayList();
3105:                    double creditTotal = 0.00;
3106:                    Iterator itemsIter = returnItems.iterator();
3107:                    while (itemsIter.hasNext()) {
3108:                        GenericValue item = (GenericValue) itemsIter.next();
3109:                        Double quantity = item.getDouble("returnQuantity");
3110:                        Double price = item.getDouble("returnPrice");
3111:                        if (quantity == null)
3112:                            quantity = new Double(0);
3113:                        if (price == null)
3114:                            price = new Double(0);
3115:                        creditTotal += price.doubleValue()
3116:                                * quantity.doubleValue();
3117:
3118:                        // set the response on the item and flag the item to be stored
3119:                        item.set("returnItemResponseId", itemResponseId);
3120:                        item.set("statusId", "RETURN_COMPLETED");
3121:                        toBeStored.add(item);
3122:
3123:                        // create the status change history and set it to be stored
3124:                        String returnStatusId = delegator.getNextSeqId(
3125:                                "ReturnStatus").toString();
3126:                        GenericValue returnStatus = delegator.makeValue(
3127:                                "ReturnStatus", UtilMisc.toMap(
3128:                                        "returnStatusId", returnStatusId));
3129:                        returnStatus.set("statusId", item.get("statusId"));
3130:                        returnStatus.set("returnId", item.get("returnId"));
3131:                        returnStatus.set("returnItemSeqId", item
3132:                                .get("returnItemSeqId"));
3133:                        returnStatus.set("statusDatetime", now);
3134:                        toBeStored.add(returnStatus);
3135:                    }
3136:
3137:                    // create a Double object for the amount
3138:                    Double creditAmount = new Double(creditTotal);
3139:
3140:                    // create a Payment record for this credit; will look just like a normal payment
3141:                    String paymentId = delegator.getNextSeqId("Payment")
3142:                            .toString();
3143:                    GenericValue payment = delegator.makeValue("Payment",
3144:                            UtilMisc.toMap("paymentId", paymentId));
3145:                    payment.set("paymentTypeId", "RECEIPT");
3146:                    payment.set("paymentMethodTypeId", "EXT_BILLACT");
3147:                    payment.set("partyIdFrom", fromPartyId);
3148:                    payment.set("partyIdTo", "Company"); // TODO: need to fix this and find a partyId to use
3149:                    payment.set("effectiveDate", now);
3150:                    payment.set("amount", creditAmount);
3151:                    payment.set("comments", "Return Credit");
3152:                    try {
3153:                        delegator.create(payment);
3154:                    } catch (GenericEntityException e) {
3155:                        Debug.logError(e, "Problem creating Payment record",
3156:                                module);
3157:                        return ServiceUtil
3158:                                .returnError("Problem creating Payment record");
3159:                    }
3160:
3161:                    // create the PaymentApplication
3162:                    String paId = delegator.getNextSeqId("PaymentApplication")
3163:                            .toString();
3164:                    GenericValue pa = delegator.makeValue("PaymentApplication",
3165:                            UtilMisc.toMap("paymentApplicationId", paId));
3166:                    pa.set("paymentId", paymentId);
3167:                    pa.set("billingAccountId", billingAccountId);
3168:                    pa.set("amountApplied", creditAmount);
3169:                    try {
3170:                        delegator.create(pa);
3171:                    } catch (GenericEntityException e) {
3172:                        Debug.logError(e,
3173:                                "Problem creating PaymentApplication record",
3174:                                module);
3175:                        return ServiceUtil
3176:                                .returnError("Problem creating PaymentApplication record");
3177:                    }
3178:
3179:                    // fill in the response fields
3180:                    itemResponse.set("paymentId", paymentId);
3181:                    itemResponse.set("billingAccountId", billingAccountId);
3182:                    itemResponse.set("responseAmount", creditAmount);
3183:                    itemResponse.set("responseDate", now);
3184:                    try {
3185:                        delegator.create(itemResponse);
3186:                    } catch (GenericEntityException e) {
3187:                        Debug.logError(e,
3188:                                "Problem creating ReturnItemResponse record",
3189:                                module);
3190:                        return ServiceUtil
3191:                                .returnError("Problem creating ReturnItemResponse record");
3192:                    }
3193:
3194:                    // store the item changes (attached responseId)
3195:                    try {
3196:                        delegator.storeAll(toBeStored);
3197:                    } catch (GenericEntityException e) {
3198:                        Debug.logError(e, "Problem storing ReturnItem updates",
3199:                                module);
3200:                        return ServiceUtil
3201:                                .returnError("Problem storing ReturnItem updates");
3202:                    }
3203:                }
3204:
3205:                return ServiceUtil.returnSuccess();
3206:            }
3207:
3208:            // refund (cash/charge) return
3209:            public static Map processRefundReturn(DispatchContext ctx,
3210:                    Map context) {
3211:                LocalDispatcher dispatcher = ctx.getDispatcher();
3212:                GenericDelegator delegator = ctx.getDelegator();
3213:                String returnId = (String) context.get("returnId");
3214:                GenericValue userLogin = (GenericValue) context
3215:                        .get("userLogin");
3216:
3217:                GenericValue returnHeader = null;
3218:                List returnItems = null;
3219:                try {
3220:                    returnHeader = delegator.findByPrimaryKey("ReturnHeader",
3221:                            UtilMisc.toMap("returnId", returnId));
3222:                    if (returnHeader != null) {
3223:                        returnItems = returnHeader.getRelatedByAnd(
3224:                                "ReturnItem", UtilMisc.toMap("returnTypeId",
3225:                                        "RTN_REFUND"));
3226:                    }
3227:                } catch (GenericEntityException e) {
3228:                    Debug.logError(e, "Problems looking up return information",
3229:                            module);
3230:                    return ServiceUtil
3231:                            .returnError("Error getting ReturnHeader/Item information");
3232:                }
3233:
3234:                if (returnHeader != null && returnItems != null
3235:                        && returnItems.size() > 0) {
3236:                    Map itemsByOrder = new HashMap();
3237:                    Map totalByOrder = new HashMap();
3238:                    groupReturnItemsByOrder(returnItems, itemsByOrder,
3239:                            totalByOrder);
3240:
3241:                    // process each one by order
3242:                    Set itemSet = itemsByOrder.entrySet();
3243:                    Iterator itemByOrderIt = itemSet.iterator();
3244:                    while (itemByOrderIt.hasNext()) {
3245:                        Map.Entry entry = (Map.Entry) itemByOrderIt.next();
3246:                        String orderId = (String) entry.getKey();
3247:                        List items = (List) entry.getValue();
3248:                        Double orderTotal = (Double) totalByOrder.get(orderId);
3249:
3250:                        // get order header & payment prefs
3251:                        GenericValue orderHeader = null;
3252:                        List orderPayPrefs = null;
3253:                        try {
3254:                            orderHeader = delegator.findByPrimaryKey(
3255:                                    "OrderHeader", UtilMisc.toMap("orderId",
3256:                                            orderId));
3257:                            // sort these desending by maxAmount
3258:                            orderPayPrefs = orderHeader.getRelated(
3259:                                    "OrderPaymentPreference", null, UtilMisc
3260:                                            .toList("-maxAmount"));
3261:                        } catch (GenericEntityException e) {
3262:                            Debug.logError(e, "Cannot get Order details for #"
3263:                                    + orderId, module);
3264:                            continue;
3265:                        }
3266:
3267:                        // get the payment prefs to use (will use them in order of amount charged)
3268:                        List prefsToUse = new ArrayList();
3269:                        Map prefsAmount = new HashMap();
3270:                        double neededAmount = orderTotal.doubleValue();
3271:                        if (orderPayPrefs != null && orderPayPrefs.size() > 0) {
3272:                            Iterator payPrefIter = orderPayPrefs.iterator();
3273:                            do {
3274:                                GenericValue pref = (GenericValue) payPrefIter
3275:                                        .next();
3276:                                Double maxAmount = pref.getDouble("maxAmount");
3277:                                if (maxAmount == null
3278:                                        || maxAmount.doubleValue() == 0.00) {
3279:                                    prefsToUse.add(pref);
3280:                                    prefsAmount.put(pref, orderTotal);
3281:                                    neededAmount = 0.00;
3282:                                } else if (maxAmount.doubleValue() > orderTotal
3283:                                        .doubleValue()) {
3284:                                    prefsToUse.add(pref);
3285:                                    prefsAmount.put(pref, orderTotal);
3286:                                    neededAmount = 0.00;
3287:                                } else {
3288:                                    prefsToUse.add(pref);
3289:                                    if (maxAmount.doubleValue() > neededAmount) {
3290:                                        prefsAmount.put(pref, new Double(
3291:                                                maxAmount.doubleValue()
3292:                                                        - neededAmount));
3293:                                    } else {
3294:                                        prefsAmount.put(pref, maxAmount);
3295:                                    }
3296:                                    neededAmount -= maxAmount.doubleValue();
3297:                                }
3298:                            } while (neededAmount > 0 && payPrefIter.hasNext());
3299:                        }
3300:
3301:                        if (neededAmount != 0) {
3302:                            Debug.logError(
3303:                                    "Was not able to find needed payment preferences for the order RTN: "
3304:                                            + returnId + " ORD: " + orderId,
3305:                                    module);
3306:                            continue;
3307:                        }
3308:
3309:                        Map prefSplitMap = new HashMap();
3310:                        if (prefsToUse == null || prefsToUse.size() == 0) {
3311:                            Debug.logError(
3312:                                    "We didn't find any possible payment prefs to use for RTN: "
3313:                                            + returnId + " ORD: " + orderId,
3314:                                    module);
3315:                            continue;
3316:                        } else if (prefsToUse.size() > 1) {
3317:                            // we need to spit the items up to log which pref it was refunded to
3318:                            // TODO: add the split of items for multiple payment prefs
3319:                        } else {
3320:                            // single payment / single refund
3321:                            prefSplitMap.put(prefsToUse.get(0), items);
3322:                        }
3323:
3324:                        // now process all items for each preference
3325:                        Set prefItemSet = prefSplitMap.entrySet();
3326:                        Iterator prefItemIt = prefItemSet.iterator();
3327:                        while (prefItemIt.hasNext()) {
3328:                            Map.Entry prefItemEntry = (Map.Entry) prefItemIt
3329:                                    .next();
3330:                            GenericValue orderPayPref = (GenericValue) prefItemEntry
3331:                                    .getKey();
3332:                            List itemList = (List) prefItemEntry.getValue();
3333:
3334:                            Double this RefundAmount = (Double) prefsAmount
3335:                                    .get(orderPayPref);
3336:                            String paymentId = null;
3337:
3338:                            // this can be extended to support additional electronic types
3339:                            List electronicTypes = UtilMisc.toList(
3340:                                    "CREDIT_CARD", "EFT_ACCOUNT", "GIFT_CARD");
3341:                            //List electronicTypes = new ArrayList();
3342:
3343:                            if (electronicTypes.contains(orderPayPref
3344:                                    .getString("paymentMethodTypeId"))) {
3345:                                // call the refund service to refund the payment
3346:                                try {
3347:                                    Map serviceResult = dispatcher.runSync(
3348:                                            "refundPayment", UtilMisc.toMap(
3349:                                                    "orderPaymentPreference",
3350:                                                    orderPayPref,
3351:                                                    "refundAmount",
3352:                                                    this RefundAmount,
3353:                                                    "userLogin", userLogin));
3354:                                    paymentId = (String) serviceResult
3355:                                            .get("paymentId");
3356:                                } catch (GenericServiceException e) {
3357:                                    Debug
3358:                                            .logError(
3359:                                                    e,
3360:                                                    "Problem running the refundPayment service",
3361:                                                    module);
3362:                                    return ServiceUtil
3363:                                            .returnError("Problems with the refund; see logs");
3364:                                }
3365:                            } else {
3366:                                // TODO: handle manual refunds (accounts payable)
3367:                            }
3368:
3369:                            //Debug.log("Finished handing refund payments", module);
3370:
3371:                            // now; for all timestamps
3372:                            Timestamp now = UtilDateTime.nowTimestamp();
3373:
3374:                            // create a new response entry
3375:                            String responseId = delegator.getNextSeqId(
3376:                                    "ReturnItemResponse").toString();
3377:                            GenericValue response = delegator
3378:                                    .makeValue("ReturnItemResponse", UtilMisc
3379:                                            .toMap("returnItemResponseId",
3380:                                                    responseId));
3381:                            response
3382:                                    .set(
3383:                                            "orderPaymentPreferenceId",
3384:                                            orderPayPref
3385:                                                    .getString("orderPaymentPreferenceId"));
3386:                            response.set("responseAmount", this RefundAmount);
3387:                            response.set("responseDate", now);
3388:                            if (paymentId != null) {
3389:                                // a null payment ID means no electronic refund was available; manual refund needed
3390:                                response.set("paymentId", paymentId);
3391:                            }
3392:
3393:                            //Debug.log("About to create return response", module);
3394:
3395:                            try {
3396:                                delegator.create(response);
3397:                            } catch (GenericEntityException e) {
3398:                                Debug
3399:                                        .logError(
3400:                                                e,
3401:                                                "Problems creating new ReturnItemResponse entity",
3402:                                                module);
3403:                                return ServiceUtil
3404:                                        .returnError("Problems creating ReturnItemResponse entity");
3405:                            }
3406:
3407:                            //Debug.log("Return response created", module);
3408:
3409:                            // set the response on each item
3410:                            Iterator itemsIter = itemList.iterator();
3411:                            while (itemsIter.hasNext()) {
3412:                                GenericValue item = (GenericValue) itemsIter
3413:                                        .next();
3414:                                item.set("returnItemResponseId", responseId);
3415:                                item.set("statusId", "RETURN_COMPLETED");
3416:
3417:                                // create the status history
3418:                                String returnStatusId = delegator.getNextSeqId(
3419:                                        "ReturnStatus").toString();
3420:                                GenericValue returnStatus = delegator
3421:                                        .makeValue("ReturnStatus", UtilMisc
3422:                                                .toMap("returnStatusId",
3423:                                                        returnStatusId));
3424:                                returnStatus.set("statusId", item
3425:                                        .get("statusId"));
3426:                                returnStatus.set("returnId", item
3427:                                        .get("returnId"));
3428:                                returnStatus.set("returnItemSeqId", item
3429:                                        .get("returnItemSeqId"));
3430:                                returnStatus.set("statusDatetime", now);
3431:
3432:                                //Debug.log("Updating item status", module);
3433:                                try {
3434:                                    item.store();
3435:                                    delegator.create(returnStatus);
3436:                                } catch (GenericEntityException e) {
3437:                                    Debug
3438:                                            .logError(
3439:                                                    "Problem updating the ReturnItem entity",
3440:                                                    module);
3441:                                    return ServiceUtil
3442:                                            .returnError("Problem updating ReturnItem (returnItemResponseId)");
3443:                                }
3444:
3445:                                //Debug.log("Item status and return status history created", module);
3446:                            }
3447:                        }
3448:                    }
3449:                }
3450:
3451:                //Debug.log("Finished refund process");
3452:                return ServiceUtil.returnSuccess();
3453:            }
3454:
3455:            public static Map processReplacementReturn(DispatchContext ctx,
3456:                    Map context) {
3457:                LocalDispatcher dispatcher = ctx.getDispatcher();
3458:                GenericDelegator delegator = ctx.getDelegator();
3459:                String returnId = (String) context.get("returnId");
3460:                GenericValue userLogin = (GenericValue) context
3461:                        .get("userLogin");
3462:
3463:                GenericValue returnHeader = null;
3464:                List returnItems = null;
3465:                try {
3466:                    returnHeader = delegator.findByPrimaryKey("ReturnHeader",
3467:                            UtilMisc.toMap("returnId", returnId));
3468:                    if (returnHeader != null) {
3469:                        returnItems = returnHeader.getRelatedByAnd(
3470:                                "ReturnItem", UtilMisc.toMap("returnTypeId",
3471:                                        "RTN_REPLACE"));
3472:                    }
3473:                } catch (GenericEntityException e) {
3474:                    Debug.logError(e, "Problems looking up return information",
3475:                            module);
3476:                    return ServiceUtil
3477:                            .returnError("Error getting ReturnHeader/Item information");
3478:                }
3479:
3480:                List createdOrderIds = new ArrayList();
3481:                if (returnHeader != null && returnItems != null
3482:                        && returnItems.size() > 0) {
3483:                    Map itemsByOrder = new HashMap();
3484:                    Map totalByOrder = new HashMap();
3485:                    groupReturnItemsByOrder(returnItems, itemsByOrder,
3486:                            totalByOrder);
3487:
3488:                    // process each one by order
3489:                    Set itemSet = itemsByOrder.entrySet();
3490:                    Iterator itemByOrderIt = itemSet.iterator();
3491:                    while (itemByOrderIt.hasNext()) {
3492:                        Map.Entry entry = (Map.Entry) itemByOrderIt.next();
3493:                        String orderId = (String) entry.getKey();
3494:                        List items = (List) entry.getValue();
3495:
3496:                        // get order header & payment prefs
3497:                        GenericValue orderHeader = null;
3498:                        try {
3499:                            orderHeader = delegator.findByPrimaryKey(
3500:                                    "OrderHeader", UtilMisc.toMap("orderId",
3501:                                            orderId));
3502:                        } catch (GenericEntityException e) {
3503:                            Debug.logError(e, "Cannot get Order details for #"
3504:                                    + orderId, module);
3505:                            continue;
3506:                        }
3507:
3508:                        OrderReadHelper orh = new OrderReadHelper(orderHeader);
3509:
3510:                        // create the replacement order
3511:                        Map orderMap = UtilMisc.toMap("userLogin", userLogin);
3512:                        GenericValue placingParty = orh.getPlacingParty();
3513:                        String placingPartyId = null;
3514:                        if (placingParty != null) {
3515:                            placingPartyId = placingParty.getString("partyId");
3516:                        }
3517:
3518:                        orderMap.put("orderTypeId", "SALES_ORDER");
3519:                        orderMap.put("partyId", placingPartyId);
3520:                        orderMap.put("productStoreId", orderHeader
3521:                                .get("productStoreId"));
3522:                        orderMap.put("webSiteId", orderHeader.get("webSiteId"));
3523:                        orderMap.put("visitId", orderHeader.get("visitId"));
3524:                        orderMap.put("currencyUom", orderHeader
3525:                                .get("currencyUom"));
3526:                        orderMap.put("grandTotal", new Double(0.00));
3527:
3528:                        // make the contact mechs
3529:                        List contactMechs = new ArrayList();
3530:                        List orderCm = null;
3531:                        try {
3532:                            orderCm = orderHeader
3533:                                    .getRelated("OrderContactMech");
3534:                        } catch (GenericEntityException e) {
3535:                            Debug.logError(e, module);
3536:                        }
3537:                        if (orderCm != null) {
3538:                            Iterator orderCmi = orderCm.iterator();
3539:                            while (orderCmi.hasNext()) {
3540:                                GenericValue v = (GenericValue) orderCmi.next();
3541:                                contactMechs.add(new GenericValue(v));
3542:                            }
3543:                            orderMap.put("orderContactMechs", contactMechs);
3544:                        }
3545:
3546:                        // make the shipment prefs
3547:                        List shipmentPrefs = new ArrayList();
3548:                        List orderSp = null;
3549:                        try {
3550:                            orderSp = orderHeader
3551:                                    .getRelated("OrderShipmentPreference");
3552:                        } catch (GenericEntityException e) {
3553:                            Debug.logError(e, module);
3554:                        }
3555:                        if (orderSp != null) {
3556:                            Iterator orderSpi = orderSp.iterator();
3557:                            while (orderSpi.hasNext()) {
3558:                                GenericValue v = (GenericValue) orderSpi.next();
3559:                                shipmentPrefs.add(new GenericValue(v));
3560:                            }
3561:                            orderMap.put("orderShipmentPreferences",
3562:                                    shipmentPrefs);
3563:                        }
3564:
3565:                        // make the order items
3566:                        double itemTotal = 0.00;
3567:                        List orderItems = new ArrayList();
3568:                        if (items != null) {
3569:                            Iterator ri = items.iterator();
3570:                            int itemCount = 1;
3571:                            while (ri.hasNext()) {
3572:                                GenericValue returnItem = (GenericValue) ri
3573:                                        .next();
3574:                                GenericValue orderItem = null;
3575:                                try {
3576:                                    orderItem = returnItem
3577:                                            .getRelatedOne("OrderItem");
3578:                                } catch (GenericEntityException e) {
3579:                                    Debug.logError(e, module);
3580:                                    continue;
3581:                                }
3582:                                if (orderItem != null) {
3583:                                    Double quantity = returnItem
3584:                                            .getDouble("returnQuantity");
3585:                                    Double unitPrice = returnItem
3586:                                            .getDouble("returnPrice");
3587:                                    if (quantity != null && unitPrice != null) {
3588:                                        itemTotal = (quantity.doubleValue() * unitPrice
3589:                                                .doubleValue());
3590:                                        GenericValue newItem = delegator
3591:                                                .makeValue(
3592:                                                        "OrderItem",
3593:                                                        UtilMisc
3594:                                                                .toMap(
3595:                                                                        "orderItemSeqId",
3596:                                                                        new Integer(
3597:                                                                                itemCount)
3598:                                                                                .toString()));
3599:
3600:                                        newItem.set("orderItemTypeId",
3601:                                                "PRODUCT_ORDER_ITEM");
3602:                                        newItem.set("productId", orderItem
3603:                                                .get("productId"));
3604:                                        newItem
3605:                                                .set(
3606:                                                        "productFeatureId",
3607:                                                        orderItem
3608:                                                                .get("productFeatureId"));
3609:                                        newItem.set("prodCatalogId", orderItem
3610:                                                .get("prodCatalogId"));
3611:                                        newItem
3612:                                                .set(
3613:                                                        "productCategoryId",
3614:                                                        orderItem
3615:                                                                .get("productCategoryId"));
3616:                                        newItem.set("quantity", quantity);
3617:                                        newItem.set("unitPrice", unitPrice);
3618:                                        newItem.set("unitListPrice", orderItem
3619:                                                .get("unitListPrice"));
3620:                                        newItem
3621:                                                .set(
3622:                                                        "itemDescription",
3623:                                                        orderItem
3624:                                                                .get("itemDescription"));
3625:                                        newItem.set("comments", orderItem
3626:                                                .get("comments"));
3627:                                        newItem
3628:                                                .set(
3629:                                                        "correspondingPoId",
3630:                                                        orderItem
3631:                                                                .get("correspondingPoId"));
3632:                                        newItem.set("statusId", "ITEM_CREATED");
3633:                                        orderItems.add(newItem);
3634:                                    }
3635:                                }
3636:                            }
3637:                            orderMap.put("orderItems", orderItems);
3638:                        } else {
3639:                            Debug.logError("No return items found??", module);
3640:                            continue;
3641:                        }
3642:
3643:                        // create the replacement adjustment
3644:                        GenericValue adj = delegator.makeValue(
3645:                                "OrderAdjustment", new HashMap());
3646:                        adj.set("orderAdjustmentTypeId", "REPLACE_ADJUSTMENT");
3647:                        adj.set("amount", new Double(itemTotal * -1));
3648:                        adj.set("comments", "Replacement Item Return #"
3649:                                + returnId);
3650:                        orderMap.put("orderAdjustments", UtilMisc.toList(adj));
3651:
3652:                        // create the order
3653:                        String createdOrderId = null;
3654:                        Map orderResult = null;
3655:                        try {
3656:                            orderResult = dispatcher.runSync("storeOrder",
3657:                                    orderMap);
3658:                        } catch (GenericServiceException e) {
3659:                            Debug.logInfo(e, "Problem creating the order!",
3660:                                    module);
3661:                        }
3662:                        if (orderResult != null) {
3663:                            createdOrderId = (String) orderResult
3664:                                    .get("orderId");
3665:                            createdOrderIds.add(createdOrderId);
3666:                        }
3667:
3668:                        // since there is no payments required; order is ready for processing/shipment
3669:                        if (createdOrderId != null) {
3670:                            boolean ok = OrderChangeHelper.approveOrder(
3671:                                    dispatcher, userLogin, createdOrderId);
3672:                        }
3673:                    }
3674:                }
3675:
3676:                StringBuffer successMessage = new StringBuffer();
3677:                if (createdOrderIds.size() > 0) {
3678:                    successMessage
3679:                            .append("The following new orders have been created : ");
3680:                    Iterator i = createdOrderIds.iterator();
3681:                    while (i.hasNext()) {
3682:                        successMessage.append(i.next());
3683:                        if (i.hasNext()) {
3684:                            successMessage.append(", ");
3685:                        }
3686:                    }
3687:                } else {
3688:                    successMessage.append("No orders were created.");
3689:                }
3690:
3691:                return ServiceUtil.returnSuccess(successMessage.toString());
3692:            }
3693:
3694:            public static void groupReturnItemsByOrder(List returnItems,
3695:                    Map itemsByOrder, Map totalByOrder) {
3696:                Iterator itemIt = returnItems.iterator();
3697:                while (itemIt.hasNext()) {
3698:                    GenericValue item = (GenericValue) itemIt.next();
3699:                    String orderId = item.getString("orderId");
3700:                    if (orderId != null) {
3701:                        if (itemsByOrder != null) {
3702:                            List orderList = (List) itemsByOrder.get(orderId);
3703:                            Double totalForOrder = null;
3704:                            if (totalByOrder != null) {
3705:                                totalForOrder = (Double) totalByOrder
3706:                                        .get(orderId);
3707:                            }
3708:                            if (orderList == null) {
3709:                                orderList = new ArrayList();
3710:                            }
3711:                            if (totalForOrder == null) {
3712:                                totalForOrder = new Double(0.00);
3713:                            }
3714:
3715:                            // add to the items list
3716:                            orderList.add(item);
3717:                            itemsByOrder.put(orderId, orderList);
3718:
3719:                            if (totalByOrder != null) {
3720:                                // add on the total for this line
3721:                                Double quantity = item
3722:                                        .getDouble("returnQuantity");
3723:                                Double amount = item.getDouble("returnPrice");
3724:                                if (quantity == null) {
3725:                                    quantity = new Double(0);
3726:                                }
3727:                                if (amount == null) {
3728:                                    amount = new Double(0.00);
3729:                                }
3730:                                double this Total = amount.doubleValue()
3731:                                        * quantity.doubleValue();
3732:                                double existingTotal = totalForOrder
3733:                                        .doubleValue();
3734:                                Double newTotal = new Double(existingTotal
3735:                                        + this Total);
3736:                                totalByOrder.put(orderId, newTotal);
3737:                            }
3738:                        }
3739:                    }
3740:                }
3741:            }
3742:
3743:            public static Map allowOrderSplit(DispatchContext ctx, Map context) {
3744:                GenericDelegator delegator = ctx.getDelegator();
3745:                GenericValue userLogin = (GenericValue) context
3746:                        .get("userLogin");
3747:                String orderId = (String) context.get("orderId");
3748:                String orderItemSeqId = (String) context.get("orderItemSeqId");
3749:                if (orderItemSeqId == null) {
3750:                    orderItemSeqId = "_NA_";
3751:                }
3752:
3753:                // check and make sure we have permission to change the order
3754:                Security security = ctx.getSecurity();
3755:                if (!security.hasEntityPermission("ORDERMGR", "_UPDATE",
3756:                        userLogin)) {
3757:                    GenericValue placingCustomer = null;
3758:                    try {
3759:                        Map placingCustomerFields = UtilMisc.toMap("orderId",
3760:                                orderId, "partyId", userLogin
3761:                                        .getString("partyId"), "roleTypeId",
3762:                                "PLACING_CUSTOMER");
3763:                        placingCustomer = delegator.findByPrimaryKey(
3764:                                "OrderRole", placingCustomerFields);
3765:                    } catch (GenericEntityException e) {
3766:                        return ServiceUtil
3767:                                .returnError("ERROR: Cannot get OrderRole entity: "
3768:                                        + e.getMessage());
3769:                    }
3770:                    if (placingCustomer == null)
3771:                        return ServiceUtil
3772:                                .returnError("You do not have permission to change this order's status.");
3773:                }
3774:
3775:                GenericValue shipPref = null;
3776:                try {
3777:                    Map fields = UtilMisc.toMap("orderId", orderId,
3778:                            "orderItemSeqId", orderItemSeqId);
3779:                    shipPref = delegator.findByPrimaryKey(
3780:                            "OrderShipmentPreference", fields);
3781:                    if (shipPref == null) {
3782:                        fields.put("orderItemSeqId", "_NA_");
3783:                        shipPref = delegator.findByPrimaryKey(
3784:                                "OrderShipmentPreference", fields);
3785:                    }
3786:                } catch (GenericEntityException e) {
3787:                    Debug.logError(e,
3788:                            "Problems getting OrderShipmentPreference for : "
3789:                                    + orderId + " / " + orderItemSeqId, module);
3790:                    return ServiceUtil
3791:                            .returnError("Cannot update; Problem getting OrderShipmentPreference");
3792:                }
3793:
3794:                if (shipPref != null) {
3795:                    shipPref.set("maySplit", "Y");
3796:                    try {
3797:                        shipPref.store();
3798:                    } catch (GenericEntityException e) {
3799:                        Debug.logError(
3800:                                "Problem saving OrdeShipmentPreference for : "
3801:                                        + orderId + " / " + orderItemSeqId,
3802:                                module);
3803:                        return ServiceUtil
3804:                                .returnError("Cannot update; Problem setting OrderShipmentPreference");
3805:                    }
3806:                } else {
3807:                    Debug.logError("ERROR: Got a NULL OrderShipmentPreference",
3808:                            module);
3809:                    return ServiceUtil
3810:                            .returnError("Cannot update; No available preference to change");
3811:                }
3812:                return ServiceUtil.returnSuccess();
3813:            }
3814:
3815:            public static Map cancelFlaggedSalesOrders(DispatchContext dctx,
3816:                    Map context) {
3817:                GenericDelegator delegator = dctx.getDelegator();
3818:                LocalDispatcher dispatcher = dctx.getDispatcher();
3819:                GenericValue userLogin = (GenericValue) context
3820:                        .get("userLogin");
3821:
3822:                List ordersToCheck = null;
3823:                List exprs = new ArrayList();
3824:
3825:                // create the query expressions
3826:                exprs.add(new EntityExpr("orderTypeId", EntityOperator.EQUALS,
3827:                        "SALES_ORDER"));
3828:                exprs.add(new EntityExpr("statusId", EntityOperator.NOT_EQUAL,
3829:                        "ORDER_COMPLETED"));
3830:                exprs.add(new EntityExpr("statusId", EntityOperator.NOT_EQUAL,
3831:                        "ORDER_CANCELLED"));
3832:                exprs.add(new EntityExpr("statusId", EntityOperator.NOT_EQUAL,
3833:                        "ORDER_REJECTED"));
3834:
3835:                // get the orders
3836:                try {
3837:                    ordersToCheck = delegator.findByAnd("OrderHeader", exprs,
3838:                            UtilMisc.toList("orderDate"));
3839:                } catch (GenericEntityException e) {
3840:                    Debug.logError(e, "Problem getting order headers", module);
3841:                }
3842:
3843:                if (ordersToCheck == null || ordersToCheck.size() == 0) {
3844:                    Debug.logInfo("No orders to check, finished", module);
3845:                    return ServiceUtil.returnSuccess();
3846:                }
3847:
3848:                Iterator i = ordersToCheck.iterator();
3849:                while (i.hasNext()) {
3850:                    GenericValue orderHeader = (GenericValue) i.next();
3851:                    String orderId = orderHeader.getString("orderId");
3852:                    String orderStatus = orderHeader.getString("statusId");
3853:
3854:                    if (orderStatus.equals("ORDER_CREATED")) {
3855:                        // first check for un-paid orders
3856:                        Timestamp orderDate = orderHeader
3857:                                .getTimestamp("entryDate");
3858:                        //appears to not be used: String webSiteId = orderHeader.getString("webSiteId");
3859:
3860:                        // name of the payment.properties file to use
3861:                        String propsFile = null;
3862:
3863:                        // need the payment.properties file for the website
3864:                        Map lookupFields = UtilMisc.toMap("productStoreId",
3865:                                orderHeader.getString("productStoreId"),
3866:                                "paymentMethodTypeId", "EXT_OFFLINE",
3867:                                "paymentServiceTypeEnumId", "_NA_");
3868:                        GenericValue paymentSettings = null;
3869:                        try {
3870:                            paymentSettings = delegator.findByPrimaryKey(
3871:                                    "ProductStorePaymentSetting", lookupFields);
3872:                        } catch (GenericEntityException e) {
3873:                            Debug
3874:                                    .logError(e,
3875:                                            "Cannot get product store payment setting record");
3876:                        }
3877:                        if (paymentSettings == null
3878:                                || paymentSettings.get("paymentPropertiesPath") == null) {
3879:                            propsFile = "payment.properties";
3880:                        } else {
3881:                            propsFile = paymentSettings
3882:                                    .getString("paymentPropertiesPath");
3883:                        }
3884:
3885:                        // need the store for the order
3886:                        GenericValue productStore = null;
3887:                        try {
3888:                            productStore = orderHeader
3889:                                    .getRelatedOne("ProductStore");
3890:                        } catch (GenericEntityException e) {
3891:                            Debug
3892:                                    .logError(
3893:                                            e,
3894:                                            "Unable to get ProductStore from OrderHeader",
3895:                                            module);
3896:                        }
3897:
3898:                        // default days to cancel
3899:                        int daysTillCancel = 30;
3900:
3901:                        // get the value from the store
3902:                        if (productStore != null
3903:                                && productStore.get("daysToCancelNonPay") != null) {
3904:                            daysTillCancel = productStore.getLong(
3905:                                    "daysToCancelNonPay").intValue();
3906:                        }
3907:
3908:                        if (daysTillCancel > 0) {
3909:                            // 0 days means do not auto-cancel
3910:                            Calendar cal = Calendar.getInstance();
3911:                            cal.setTimeInMillis(orderDate.getTime());
3912:                            cal.add(Calendar.DAY_OF_YEAR, daysTillCancel);
3913:                            Date cancelDate = cal.getTime();
3914:                            Date nowDate = new Date();
3915:                            //Debug.log("Cancel Date : " + cancelDate, module);
3916:                            //Debug.log("Current Date : " + nowDate, module);
3917:                            if (cancelDate.equals(nowDate)
3918:                                    || nowDate.after(cancelDate)) {
3919:                                // cancel the order item(s)
3920:                                Map svcCtx = UtilMisc.toMap("orderId", orderId,
3921:                                        "statusId", "ITEM_CANCELLED",
3922:                                        "userLogin", userLogin);
3923:                                try {
3924:                                    Map ores = dispatcher.runSync(
3925:                                            "changeOrderItemStatus", svcCtx);
3926:                                } catch (GenericServiceException e) {
3927:                                    Debug.logError(e,
3928:                                            "Problem calling change item status service : "
3929:                                                    + svcCtx, module);
3930:                                }
3931:                            }
3932:                        }
3933:                    } else {
3934:                        // check for auto-cancel items
3935:                        List orderItems = null;
3936:                        try {
3937:                            orderItems = orderHeader.getRelated("OrderItem");
3938:                        } catch (GenericEntityException e) {
3939:                            Debug.logError(e,
3940:                                    "Problem getting order item records",
3941:                                    module);
3942:                        }
3943:                        if (orderItems != null && orderItems.size() > 0) {
3944:                            Iterator oii = orderItems.iterator();
3945:                            while (oii.hasNext()) {
3946:                                GenericValue orderItem = (GenericValue) oii
3947:                                        .next();
3948:                                String orderItemSeqId = orderItem
3949:                                        .getString("orderItemSeqId");
3950:                                Timestamp nowTimestamp = UtilDateTime
3951:                                        .nowTimestamp();
3952:                                Timestamp autoCancelDate = orderItem
3953:                                        .getTimestamp("autoCancelDate");
3954:                                Timestamp dontCancelDate = orderItem
3955:                                        .getTimestamp("dontCancelSetDate");
3956:                                String dontCancelUserLogin = orderItem
3957:                                        .getString("dontCancelSetUserLogin");
3958:
3959:                                if (dontCancelUserLogin == null
3960:                                        && dontCancelDate == null
3961:                                        && autoCancelDate != null) {
3962:                                    if (autoCancelDate.equals(nowTimestamp)
3963:                                            || autoCancelDate
3964:                                                    .after(nowTimestamp)) {
3965:                                        // cancel the order item
3966:                                        Map svcCtx = UtilMisc.toMap("orderId",
3967:                                                orderId, "orderItemSeqId",
3968:                                                orderItemSeqId, "statusId",
3969:                                                "ITEM_CANCELLED", "userLogin",
3970:                                                userLogin);
3971:                                        try {
3972:                                            Map res = dispatcher.runSync(
3973:                                                    "changeOrderItemStatus",
3974:                                                    svcCtx);
3975:                                        } catch (GenericServiceException e) {
3976:                                            Debug.logError(e,
3977:                                                    "Problem calling change item status service : "
3978:                                                            + svcCtx, module);
3979:                                        }
3980:                                    }
3981:                                }
3982:                            }
3983:                        }
3984:                    }
3985:                }
3986:                return ServiceUtil.returnSuccess();
3987:            }
3988:
3989:            public static Map checkDigitalItemFulfillment(DispatchContext dctx,
3990:                    Map context) {
3991:                GenericDelegator delegator = dctx.getDelegator();
3992:                LocalDispatcher dispatcher = dctx.getDispatcher();
3993:                GenericValue userLogin = (GenericValue) context
3994:                        .get("userLogin");
3995:                String orderId = (String) context.get("orderId");
3996:
3997:                // need the order header
3998:                GenericValue orderHeader = null;
3999:                try {
4000:                    orderHeader = delegator.findByPrimaryKey("OrderHeader",
4001:                            UtilMisc.toMap("orderId", orderId));
4002:                } catch (GenericEntityException e) {
4003:                    Debug.logError(e,
4004:                            "ERROR: Unable to get OrderHeader for orderId : "
4005:                                    + orderId, module);
4006:                    return ServiceUtil
4007:                            .returnError("ERROR: Unable to get OrderHeader for orderId : "
4008:                                    + orderId);
4009:                }
4010:
4011:                // get all the items for the order
4012:                List orderItems = null;
4013:                if (orderHeader != null) {
4014:                    try {
4015:                        orderItems = orderHeader.getRelated("OrderItem");
4016:                    } catch (GenericEntityException e) {
4017:                        Debug.logError(e,
4018:                                "ERROR: Unable to get OrderItem list for orderId : "
4019:                                        + orderId, module);
4020:                        return ServiceUtil
4021:                                .returnError("ERROR: Unable to get OrderItem list for orderId : "
4022:                                        + orderId);
4023:                    }
4024:                }
4025:
4026:                // find any digital goods
4027:                Map digitalProducts = new HashMap();
4028:                List digitalItems = new ArrayList();
4029:                if (orderItems != null && orderItems.size() > 0) {
4030:                    Iterator i = orderItems.iterator();
4031:                    while (i.hasNext()) {
4032:                        GenericValue item = (GenericValue) i.next();
4033:                        GenericValue product = null;
4034:                        try {
4035:                            product = item.getRelatedOne("Product");
4036:                        } catch (GenericEntityException e) {
4037:                            Debug
4038:                                    .logError(
4039:                                            e,
4040:                                            "ERROR: Unable to get Product from OrderItem",
4041:                                            module);
4042:                        }
4043:                        if (product != null) {
4044:                            String productType = product
4045:                                    .getString("productTypeId");
4046:                            // check for digital and finished/digital goods
4047:                            if ("DIGITAL_GOOD".equals(productType)
4048:                                    || "FINDIG_GOOD".equals(productType)) {
4049:                                // we only invoice APPROVED items
4050:                                if ("ITEM_APPROVED".equals(item
4051:                                        .getString("statusId"))) {
4052:                                    digitalItems.add(item);
4053:                                }
4054:                                if ("DIGITAL_GOOD".equals(productType)) {
4055:                                    // 100% digital goods need status change
4056:                                    digitalProducts.put(item, product);
4057:                                }
4058:                            }
4059:                        }
4060:                    }
4061:                }
4062:
4063:                // now process the digital items
4064:                if (digitalItems.size() > 0) {
4065:                    // invoice all APPROVED digital goods
4066:                    Map invoiceContext = UtilMisc.toMap("orderId", orderId,
4067:                            "billItems", digitalItems, "userLogin", userLogin);
4068:                    Map invoiceResult = null;
4069:                    try {
4070:                        invoiceResult = dispatcher.runSync(
4071:                                "createInvoiceForOrder", invoiceContext);
4072:                    } catch (GenericServiceException e) {
4073:                        Debug.logError(e,
4074:                                "ERROR: Unable to invoice digital items",
4075:                                module);
4076:                        return ServiceUtil
4077:                                .returnError("Problem with invoice creation; digital items not fulfilled.");
4078:                    }
4079:                    if (ModelService.RESPOND_ERROR.equals(invoiceResult
4080:                            .get(ModelService.RESPONSE_MESSAGE))) {
4081:                        return ServiceUtil.returnError((String) invoiceResult
4082:                                .get(ModelService.ERROR_MESSAGE));
4083:                    }
4084:
4085:                    // update the status of DIGITAL_GOOD to COMPLETED; leave FINDIG as APPROVED for pick/ship
4086:                    Iterator dii = digitalItems.iterator();
4087:                    while (dii.hasNext()) {
4088:                        GenericValue item = (GenericValue) dii.next();
4089:                        GenericValue product = (GenericValue) digitalProducts
4090:                                .get(item);
4091:                        if (product != null) {
4092:                            // we were set as a digital good; one more check and change status
4093:                            if ("DIGITAL_GOOD".equals(product
4094:                                    .getString("productTypeId"))) {
4095:                                Map statusCtx = new HashMap();
4096:                                statusCtx.put("orderId", item
4097:                                        .getString("orderId"));
4098:                                statusCtx.put("orderItemSeqId", item
4099:                                        .getString("orderItemSeqId"));
4100:                                statusCtx.put("statusId", "ITEM_COMPLETED");
4101:                                statusCtx.put("userLogin", userLogin);
4102:                                try {
4103:                                    dispatcher.runSyncIgnore(
4104:                                            "changeOrderItemStatus", statusCtx);
4105:                                } catch (GenericServiceException e) {
4106:                                    Debug.logError(e,
4107:                                            "ERROR: Problem setting the status to COMPLETED : "
4108:                                                    + item, module);
4109:                                }
4110:                            }
4111:                        }
4112:                    }
4113:
4114:                    // fulfill the digital goods
4115:                    Map fulfillContext = UtilMisc.toMap("orderId", orderId,
4116:                            "orderItems", digitalItems, "userLogin", userLogin);
4117:                    Map fulfillResult = null;
4118:                    try {
4119:                        // will be running in an isolated transaction to prevent rollbacks
4120:                        fulfillResult = dispatcher.runSync(
4121:                                "fulfillDigitalItems", fulfillContext, 300,
4122:                                true);
4123:                    } catch (GenericServiceException e) {
4124:                        Debug.logError(e,
4125:                                "ERROR: Unable to fulfill digital items",
4126:                                module);
4127:                    }
4128:                    if (ModelService.RESPOND_ERROR.equals(fulfillResult
4129:                            .get(ModelService.RESPONSE_MESSAGE))) {
4130:                        // this service cannot return error at this point or we will roll back the invoice
4131:                        // since payments are already captured; errors should have been logged already.
4132:                        // the response message here will be passed as an error to the user.
4133:                        return ServiceUtil.returnSuccess((String) fulfillResult
4134:                                .get(ModelService.ERROR_MESSAGE));
4135:                    }
4136:                }
4137:
4138:                return ServiceUtil.returnSuccess();
4139:            }
4140:
4141:            public static Map fulfillDigitalItems(DispatchContext ctx,
4142:                    Map context) {
4143:                //appears to not be used: GenericDelegator delegator = ctx.getDelegator();
4144:                LocalDispatcher dispatcher = ctx.getDispatcher();
4145:                //appears to not be used: String orderId = (String) context.get("orderId");
4146:                List orderItems = (List) context.get("orderItems");
4147:                GenericValue userLogin = (GenericValue) context
4148:                        .get("userLogin");
4149:
4150:                if (orderItems != null && orderItems.size() > 0) {
4151:                    // loop through the digital items to fulfill
4152:                    Iterator itemsIterator = orderItems.iterator();
4153:                    while (itemsIterator.hasNext()) {
4154:                        GenericValue orderItem = (GenericValue) itemsIterator
4155:                                .next();
4156:
4157:                        // make sure we have a valid item
4158:                        if (orderItem == null) {
4159:                            ServiceUtil
4160:                                    .returnError("ERROR: Cannot check for fulfillment; item not found.");
4161:                        }
4162:
4163:                        // locate the Product & ProductContent records
4164:                        GenericValue product = null;
4165:                        List productContent = null;
4166:                        try {
4167:                            product = orderItem.getRelatedOne("Product");
4168:                            if (product == null) {
4169:                                ServiceUtil
4170:                                        .returnError("ERROR: Cannot check for fulfillment; product not found.");
4171:                            }
4172:
4173:                            List allProductContent = product
4174:                                    .getRelated("ProductContent");
4175:                            if (allProductContent != null
4176:                                    && allProductContent.size() > 0) {
4177:                                // only keep ones with valid dates
4178:                                productContent = EntityUtil.filterByDate(
4179:                                        allProductContent, UtilDateTime
4180:                                                .nowTimestamp(), "fromDate",
4181:                                        "thruDate", true);
4182:                                Debug.logInfo("Product has "
4183:                                        + allProductContent.size()
4184:                                        + " associations, "
4185:                                        + (productContent == null ? "0" : ""
4186:                                                + productContent.size())
4187:                                        + " has valid from/thru dates", module);
4188:                            }
4189:                        } catch (GenericEntityException e) {
4190:                            return ServiceUtil
4191:                                    .returnError("ERROR: Cannot get Product entity: "
4192:                                            + e.getMessage());
4193:                        }
4194:
4195:                        // now use the ProductContent to fulfill the item
4196:                        if (productContent != null && productContent.size() > 0) {
4197:                            Iterator prodcontentIterator = productContent
4198:                                    .iterator();
4199:                            while (prodcontentIterator.hasNext()) {
4200:                                GenericValue productContentItem = (GenericValue) prodcontentIterator
4201:                                        .next();
4202:                                GenericValue content = null;
4203:                                try {
4204:                                    content = productContentItem
4205:                                            .getRelatedOne("Content");
4206:                                } catch (GenericEntityException e) {
4207:                                    Debug.logError(e,
4208:                                            "ERROR: Cannot get Content entity: "
4209:                                                    + e.getMessage(), module);
4210:                                    continue;
4211:                                }
4212:
4213:                                String fulfillmentType = productContentItem
4214:                                        .getString("productContentTypeId");
4215:                                if ("FULFILLMENT_EXTASYNC"
4216:                                        .equals(fulfillmentType)
4217:                                        || "FULFILLMENT_EXTSYNC"
4218:                                                .equals(fulfillmentType)) {
4219:                                    // enternal service fulfillment
4220:                                    String fulfillmentService = (String) content
4221:                                            .get("serviceName");
4222:                                    if (fulfillmentService == null) {
4223:                                        Debug
4224:                                                .logError(
4225:                                                        "ProductContent of type FULFILLMENT_EXTERNAL had Content with empty serviceName, can not run fulfillment",
4226:                                                        module);
4227:                                    }
4228:                                    Map serviceCtx = UtilMisc.toMap(
4229:                                            "userLogin", userLogin,
4230:                                            "orderItem", orderItem);
4231:                                    serviceCtx.putAll(productContentItem
4232:                                            .getPrimaryKey());
4233:                                    try {
4234:                                        Debug.logInfo(
4235:                                                "Running external fulfillment '"
4236:                                                        + fulfillmentService
4237:                                                        + "'", module);
4238:                                        if ("FULFILLMENT_EXTASYNC"
4239:                                                .equals(fulfillmentType)) {
4240:                                            dispatcher.runAsync(
4241:                                                    fulfillmentService,
4242:                                                    serviceCtx, true);
4243:                                        } else if ("FULFILLMENT_EXTSYNC"
4244:                                                .equals(fulfillmentType)) {
4245:                                            Map resp = dispatcher.runSync(
4246:                                                    fulfillmentService,
4247:                                                    serviceCtx);
4248:                                            if (ServiceUtil.isError(resp)) {
4249:                                                return ServiceUtil
4250:                                                        .returnError(ServiceUtil
4251:                                                                .getErrorMessage(resp));
4252:                                            }
4253:                                        }
4254:                                    } catch (GenericServiceException e) {
4255:                                        Debug.logError(e,
4256:                                                "ERROR: Could not run external fulfillment service '"
4257:                                                        + fulfillmentService
4258:                                                        + "'; "
4259:                                                        + e.getMessage(),
4260:                                                module);
4261:                                    }
4262:                                } else if ("FULFILLMENT_EMAIL"
4263:                                        .equals(fulfillmentType)) {
4264:                                    // digital email fulfillment
4265:                                    // TODO: Add support for fulfillment email
4266:                                    return ServiceUtil
4267:                                            .returnError("Email Fulfillment type not yet implemented");
4268:                                } else if ("DIGITAL_DOWNLOAD"
4269:                                        .equals(fulfillmentType)) {
4270:                                    // digital download fulfillment
4271:
4272:                                    // Nothing to do for here. Downloads are made available to the user
4273:                                    // though a query of OrderItems with related ProductContent.
4274:                                } else {
4275:                                    Debug
4276:                                            .logError(
4277:                                                    "Invalid fulfillment type : "
4278:                                                            + fulfillmentType
4279:                                                            + " not supported.",
4280:                                                    module);
4281:                                }
4282:                            }
4283:                        }
4284:                    }
4285:                }
4286:                return ServiceUtil.returnSuccess();
4287:            }
4288:
4289:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.