Source Code Cross Referenced for InventoryServices.java in  » ERP-CRM-Financial » ofbiz » org » ofbiz » product » inventory » 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 » ofbiz » org.ofbiz.product.inventory 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Licensed to the Apache Software Foundation (ASF) under one
0003:         * or more contributor license agreements.  See the NOTICE file
0004:         * distributed with this work for additional information
0005:         * regarding copyright ownership.  The ASF licenses this file
0006:         * to you under the Apache License, Version 2.0 (the
0007:         * "License"); you may not use this file except in compliance
0008:         * with the License.  You may obtain a copy of the License at
0009:         * 
0010:         * http://www.apache.org/licenses/LICENSE-2.0
0011:         * 
0012:         * Unless required by applicable law or agreed to in writing,
0013:         * software distributed under the License is distributed on an
0014:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0015:         * KIND, either express or implied.  See the License for the
0016:         * specific language governing permissions and limitations
0017:         * under the License.
0018:         *******************************************************************************/package org.ofbiz.product.inventory;
0019:
0020:        import java.sql.Timestamp;
0021:        import java.util.ArrayList;
0022:        import java.util.Calendar;
0023:        import java.util.HashMap;
0024:        import java.util.Iterator;
0025:        import java.util.List;
0026:        import java.util.Map;
0027:        import java.util.Set;
0028:
0029:        import org.ofbiz.base.util.Debug;
0030:        import org.ofbiz.base.util.UtilDateTime;
0031:        import org.ofbiz.base.util.UtilMisc;
0032:        import org.ofbiz.base.util.UtilValidate;
0033:        import org.ofbiz.entity.GenericDelegator;
0034:        import org.ofbiz.entity.GenericEntityException;
0035:        import org.ofbiz.entity.GenericValue;
0036:        import org.ofbiz.entity.condition.EntityConditionList;
0037:        import org.ofbiz.entity.condition.EntityExpr;
0038:        import org.ofbiz.entity.condition.EntityOperator;
0039:        import org.ofbiz.entity.model.DynamicViewEntity;
0040:        import org.ofbiz.entity.model.ModelKeyMap;
0041:        import org.ofbiz.entity.util.EntityListIterator;
0042:        import org.ofbiz.service.DispatchContext;
0043:        import org.ofbiz.service.GenericServiceException;
0044:        import org.ofbiz.service.LocalDispatcher;
0045:        import org.ofbiz.service.ServiceUtil;
0046:
0047:        /**
0048:         * Inventory Services 
0049:         */
0050:        public class InventoryServices {
0051:
0052:            public final static String module = InventoryServices.class
0053:                    .getName();
0054:
0055:            public static Map prepareInventoryTransfer(DispatchContext dctx,
0056:                    Map context) {
0057:                GenericDelegator delegator = dctx.getDelegator();
0058:                String inventoryItemId = (String) context
0059:                        .get("inventoryItemId");
0060:                Double xferQty = (Double) context.get("xferQty");
0061:                GenericValue inventoryItem = null;
0062:                GenericValue newItem = null;
0063:                GenericValue userLogin = (GenericValue) context
0064:                        .get("userLogin");
0065:
0066:                try {
0067:                    inventoryItem = delegator.findByPrimaryKey("InventoryItem",
0068:                            UtilMisc.toMap("inventoryItemId", inventoryItemId));
0069:                } catch (GenericEntityException e) {
0070:                    return ServiceUtil
0071:                            .returnError("Inventory item lookup problem ["
0072:                                    + e.getMessage() + "]");
0073:                }
0074:
0075:                if (inventoryItem == null) {
0076:                    return ServiceUtil
0077:                            .returnError("Cannot locate inventory item.");
0078:                }
0079:
0080:                try {
0081:                    Map results = ServiceUtil.returnSuccess();
0082:
0083:                    String inventoryType = inventoryItem
0084:                            .getString("inventoryItemTypeId");
0085:                    if (inventoryType.equals("NON_SERIAL_INV_ITEM")) {
0086:                        Double atp = inventoryItem
0087:                                .getDouble("availableToPromiseTotal");
0088:                        Double qoh = inventoryItem
0089:                                .getDouble("quantityOnHandTotal");
0090:
0091:                        if (atp == null) {
0092:                            return ServiceUtil
0093:                                    .returnError("The request transfer amount is not available, there is no available to promise on the Inventory Item with ID "
0094:                                            + inventoryItem
0095:                                                    .getString("inventoryItemId"));
0096:                        }
0097:                        if (qoh == null) {
0098:                            qoh = atp;
0099:                        }
0100:
0101:                        // first make sure we have enough to cover the request transfer amount
0102:                        if (xferQty.doubleValue() > atp.doubleValue()) {
0103:                            return ServiceUtil
0104:                                    .returnError("The request transfer amount is not available, the available to promise ["
0105:                                            + atp
0106:                                            + "] is not sufficient for the desired transfer quantity ["
0107:                                            + xferQty
0108:                                            + "] on the Inventory Item with ID "
0109:                                            + inventoryItem
0110:                                                    .getString("inventoryItemId"));
0111:                        }
0112:
0113:                        /*
0114:                         * atp < qoh - split and save the qoh - atp
0115:                         * xferQty < atp - split and save atp - xferQty
0116:                         * atp < qoh && xferQty < atp - split and save qoh - atp + atp - xferQty
0117:                         */
0118:
0119:                        // at this point we have already made sure that the xferQty is less than or equals to the atp, so if less that just create a new inventory record for the quantity to be moved
0120:                        // NOTE: atp should always be <= qoh, so if xfer < atp, then xfer < qoh, so no need to check/handle that
0121:                        // however, if atp < qoh && atp == xferQty, then we still need to split; oh, but no need to check atp == xferQty in the second part because if it isn't greater and isn't less, then it is equal
0122:                        if (xferQty.doubleValue() < atp.doubleValue()
0123:                                || atp.doubleValue() < qoh.doubleValue()) {
0124:                            Double negXferQty = new Double(-xferQty
0125:                                    .doubleValue());
0126:                            // NOTE: new inventory items should always be created calling the
0127:                            //       createInventoryItem service because in this way we are sure
0128:                            //       that all the relevant fields are filled with default values.
0129:                            //       However, the code here should work fine because all the values
0130:                            //       for the new inventory item are inerited from the existing item.
0131:                            newItem = GenericValue.create(inventoryItem);
0132:                            newItem.set("availableToPromiseTotal",
0133:                                    new Double(0));
0134:                            newItem.set("quantityOnHandTotal", new Double(0));
0135:
0136:                            String newSeqId = null;
0137:                            try {
0138:                                newSeqId = delegator
0139:                                        .getNextSeqId("InventoryItem");
0140:                            } catch (IllegalArgumentException e) {
0141:                                return ServiceUtil
0142:                                        .returnError("ERROR: Could not get next sequence id for InventoryItem, cannot create item.");
0143:                            }
0144:
0145:                            newItem.set("inventoryItemId", newSeqId);
0146:                            newItem.create();
0147:
0148:                            results.put("inventoryItemId", newItem
0149:                                    .get("inventoryItemId"));
0150:
0151:                            // TODO: how do we get this here: "inventoryTransferId", inventoryTransferId
0152:                            Map createNewDetailMap = UtilMisc.toMap(
0153:                                    "availableToPromiseDiff", xferQty,
0154:                                    "quantityOnHandDiff", xferQty,
0155:                                    "inventoryItemId", newItem
0156:                                            .get("inventoryItemId"),
0157:                                    "userLogin", userLogin);
0158:                            Map createUpdateDetailMap = UtilMisc.toMap(
0159:                                    "availableToPromiseDiff", negXferQty,
0160:                                    "quantityOnHandDiff", negXferQty,
0161:                                    "inventoryItemId", inventoryItem
0162:                                            .get("inventoryItemId"),
0163:                                    "userLogin", userLogin);
0164:
0165:                            try {
0166:                                Map resultNew = dctx.getDispatcher().runSync(
0167:                                        "createInventoryItemDetail",
0168:                                        createNewDetailMap);
0169:                                if (ServiceUtil.isError(resultNew)) {
0170:                                    return ServiceUtil
0171:                                            .returnError(
0172:                                                    "Inventory Item Detail create problem in prepare inventory transfer",
0173:                                                    null, null, resultNew);
0174:                                }
0175:                                Map resultUpdate = dctx.getDispatcher()
0176:                                        .runSync("createInventoryItemDetail",
0177:                                                createUpdateDetailMap);
0178:                                if (ServiceUtil.isError(resultNew)) {
0179:                                    return ServiceUtil
0180:                                            .returnError(
0181:                                                    "Inventory Item Detail create problem in prepare inventory transfer",
0182:                                                    null, null, resultUpdate);
0183:                                }
0184:                            } catch (GenericServiceException e1) {
0185:                                return ServiceUtil
0186:                                        .returnError("Inventory Item Detail create problem in prepare inventory transfer: ["
0187:                                                + e1.getMessage() + "]");
0188:                            }
0189:                        } else {
0190:                            results.put("inventoryItemId", inventoryItem
0191:                                    .get("inventoryItemId"));
0192:                        }
0193:                    } else if (inventoryType.equals("SERIALIZED_INV_ITEM")) {
0194:                        if (!"INV_AVAILABLE".equals(inventoryItem
0195:                                .getString("statusId"))) {
0196:                            return ServiceUtil
0197:                                    .returnError("Serialized inventory is not available for transfer.");
0198:                        }
0199:                    }
0200:
0201:                    // setup values so that no one will grab the inventory during the move
0202:                    // if newItem is not null, it is the item to be moved, otherwise the original inventoryItem is the one to be moved
0203:                    if (inventoryType.equals("NON_SERIAL_INV_ITEM")) {
0204:                        // set the transfered inventory item's atp to 0 and the qoh to the xferQty; at this point atp and qoh will always be the same, so we can safely zero the atp for now
0205:                        GenericValue inventoryItemToClear = newItem == null ? inventoryItem
0206:                                : newItem;
0207:
0208:                        inventoryItemToClear.refresh();
0209:                        double atp = inventoryItemToClear
0210:                                .get("availableToPromiseTotal") == null ? 0
0211:                                : inventoryItemToClear.getDouble(
0212:                                        "availableToPromiseTotal")
0213:                                        .doubleValue();
0214:                        if (atp != 0) {
0215:                            Map createDetailMap = UtilMisc.toMap(
0216:                                    "availableToPromiseDiff", new Double(-atp),
0217:                                    "inventoryItemId", inventoryItemToClear
0218:                                            .get("inventoryItemId"),
0219:                                    "userLogin", userLogin);
0220:                            try {
0221:                                Map result = dctx.getDispatcher().runSync(
0222:                                        "createInventoryItemDetail",
0223:                                        createDetailMap);
0224:                                if (ServiceUtil.isError(result)) {
0225:                                    return ServiceUtil
0226:                                            .returnError(
0227:                                                    "Inventory Item Detail create problem in complete inventory transfer",
0228:                                                    null, null, result);
0229:                                }
0230:                            } catch (GenericServiceException e1) {
0231:                                return ServiceUtil
0232:                                        .returnError("Inventory Item Detail create problem in complete inventory transfer: ["
0233:                                                + e1.getMessage() + "]");
0234:                            }
0235:                        }
0236:                    } else if (inventoryType.equals("SERIALIZED_INV_ITEM")) {
0237:                        // set the status to avoid re-moving or something
0238:                        if (newItem != null) {
0239:                            newItem.refresh();
0240:                            newItem.set("statusId", "INV_BEING_TRANSFERED");
0241:                            newItem.store();
0242:                            results.put("inventoryItemId", newItem
0243:                                    .get("inventoryItemId"));
0244:                        } else {
0245:                            inventoryItem.refresh();
0246:                            inventoryItem.set("statusId",
0247:                                    "INV_BEING_TRANSFERED");
0248:                            inventoryItem.store();
0249:                            results.put("inventoryItemId", inventoryItem
0250:                                    .get("inventoryItemId"));
0251:                        }
0252:                    }
0253:
0254:                    return results;
0255:                } catch (GenericEntityException e) {
0256:                    return ServiceUtil
0257:                            .returnError("Inventory store/create problem ["
0258:                                    + e.getMessage() + "]");
0259:                }
0260:            }
0261:
0262:            public static Map completeInventoryTransfer(DispatchContext dctx,
0263:                    Map context) {
0264:                GenericDelegator delegator = dctx.getDelegator();
0265:                String inventoryTransferId = (String) context
0266:                        .get("inventoryTransferId");
0267:                GenericValue inventoryTransfer = null;
0268:                GenericValue inventoryItem = null;
0269:                GenericValue destinationFacility = null;
0270:                GenericValue userLogin = (GenericValue) context
0271:                        .get("userLogin");
0272:
0273:                try {
0274:                    inventoryTransfer = delegator
0275:                            .findByPrimaryKey("InventoryTransfer", UtilMisc
0276:                                    .toMap("inventoryTransferId",
0277:                                            inventoryTransferId));
0278:                    inventoryItem = inventoryTransfer
0279:                            .getRelatedOne("InventoryItem");
0280:                    destinationFacility = inventoryTransfer
0281:                            .getRelatedOne("ToFacility");
0282:                } catch (GenericEntityException e) {
0283:                    return ServiceUtil
0284:                            .returnError("Inventory Item/Transfer lookup problem ["
0285:                                    + e.getMessage() + "]");
0286:                }
0287:
0288:                if (inventoryTransfer == null || inventoryItem == null) {
0289:                    return ServiceUtil
0290:                            .returnError("ERROR: Lookup of InventoryTransfer and/or InventoryItem failed!");
0291:                }
0292:
0293:                String inventoryType = inventoryItem
0294:                        .getString("inventoryItemTypeId");
0295:
0296:                // set the fields on the transfer record            
0297:                if (inventoryTransfer.get("receiveDate") == null) {
0298:                    inventoryTransfer.set("receiveDate", UtilDateTime
0299:                            .nowTimestamp());
0300:                }
0301:
0302:                if (inventoryType.equals("NON_SERIAL_INV_ITEM")) {
0303:                    // add an adjusting InventoryItemDetail so set ATP back to QOH: ATP = ATP + (QOH - ATP), diff = QOH - ATP
0304:                    double atp = inventoryItem.get("availableToPromiseTotal") == null ? 0
0305:                            : inventoryItem
0306:                                    .getDouble("availableToPromiseTotal")
0307:                                    .doubleValue();
0308:                    double qoh = inventoryItem.get("quantityOnHandTotal") == null ? 0
0309:                            : inventoryItem.getDouble("quantityOnHandTotal")
0310:                                    .doubleValue();
0311:                    Map createDetailMap = UtilMisc.toMap(
0312:                            "availableToPromiseDiff", new Double(qoh - atp),
0313:                            "inventoryItemId", inventoryItem
0314:                                    .get("inventoryItemId"), "userLogin",
0315:                            userLogin);
0316:                    try {
0317:                        Map result = dctx.getDispatcher().runSync(
0318:                                "createInventoryItemDetail", createDetailMap);
0319:                        if (ServiceUtil.isError(result)) {
0320:                            return ServiceUtil
0321:                                    .returnError(
0322:                                            "Inventory Item Detail create problem in complete inventory transfer",
0323:                                            null, null, result);
0324:                        }
0325:                    } catch (GenericServiceException e1) {
0326:                        return ServiceUtil
0327:                                .returnError("Inventory Item Detail create problem in complete inventory transfer: ["
0328:                                        + e1.getMessage() + "]");
0329:                    }
0330:                    try {
0331:                        inventoryItem.refresh();
0332:                    } catch (GenericEntityException e) {
0333:                        return ServiceUtil
0334:                                .returnError("Inventory refresh problem ["
0335:                                        + e.getMessage() + "]");
0336:                    }
0337:                }
0338:
0339:                // set the fields on the item
0340:                Map updateInventoryItemMap = UtilMisc
0341:                        .toMap("inventoryItemId", inventoryItem
0342:                                .getString("inventoryItemId"), "facilityId",
0343:                                inventoryTransfer.get("facilityIdTo"),
0344:                                "containerId", inventoryTransfer
0345:                                        .get("containerIdTo"), "locationSeqId",
0346:                                inventoryTransfer.get("locationSeqIdTo"),
0347:                                "userLogin", userLogin);
0348:
0349:                // for serialized items, automatically make them available
0350:                if (inventoryType.equals("SERIALIZED_INV_ITEM")) {
0351:                    updateInventoryItemMap.put("statusId", "INV_AVAILABLE");
0352:                }
0353:
0354:                // if the destination facility's owner is different 
0355:                // from the inventory item's ownwer, 
0356:                // the inventory item is assigned to the new owner.
0357:                if (destinationFacility != null
0358:                        && destinationFacility.get("ownerPartyId") != null) {
0359:                    String fromPartyId = inventoryItem
0360:                            .getString("ownerPartyId");
0361:                    String toPartyId = destinationFacility
0362:                            .getString("ownerPartyId");
0363:                    if (fromPartyId == null || !fromPartyId.equals(toPartyId)) {
0364:                        updateInventoryItemMap.put("ownerPartyId", toPartyId);
0365:                    }
0366:                }
0367:                try {
0368:                    Map result = dctx.getDispatcher().runSync(
0369:                            "updateInventoryItem", updateInventoryItemMap);
0370:                    if (ServiceUtil.isError(result)) {
0371:                        return ServiceUtil.returnError(
0372:                                "Inventory item store problem", null, null,
0373:                                result);
0374:                    }
0375:                } catch (GenericServiceException exc) {
0376:                    return ServiceUtil
0377:                            .returnError("Inventory item store problem ["
0378:                                    + exc.getMessage() + "]");
0379:                }
0380:
0381:                // set the inventory transfer record to complete
0382:                inventoryTransfer.set("statusId", "IXF_COMPLETE");
0383:
0384:                // store the entities
0385:                try {
0386:                    inventoryTransfer.store();
0387:                } catch (GenericEntityException e) {
0388:                    return ServiceUtil.returnError("Inventory store problem ["
0389:                            + e.getMessage() + "]");
0390:                }
0391:
0392:                return ServiceUtil.returnSuccess();
0393:            }
0394:
0395:            public static Map cancelInventoryTransfer(DispatchContext dctx,
0396:                    Map context) {
0397:                GenericDelegator delegator = dctx.getDelegator();
0398:                String inventoryTransferId = (String) context
0399:                        .get("inventoryTransferId");
0400:                GenericValue inventoryTransfer = null;
0401:                GenericValue inventoryItem = null;
0402:                GenericValue userLogin = (GenericValue) context
0403:                        .get("userLogin");
0404:
0405:                try {
0406:                    inventoryTransfer = delegator
0407:                            .findByPrimaryKey("InventoryTransfer", UtilMisc
0408:                                    .toMap("inventoryTransferId",
0409:                                            inventoryTransferId));
0410:                    if (UtilValidate.isEmpty(inventoryTransfer)) {
0411:                        return ServiceUtil.returnError("Inventory transfer ["
0412:                                + inventoryTransferId + "] not found");
0413:                    }
0414:                    inventoryItem = inventoryTransfer
0415:                            .getRelatedOne("InventoryItem");
0416:                } catch (GenericEntityException e) {
0417:                    return ServiceUtil
0418:                            .returnError("Inventory Item/Transfer lookup problem ["
0419:                                    + e.getMessage() + "]");
0420:                }
0421:
0422:                if (inventoryTransfer == null || inventoryItem == null) {
0423:                    return ServiceUtil
0424:                            .returnError("ERROR: Lookup of InventoryTransfer and/or InventoryItem failed!");
0425:                }
0426:
0427:                String inventoryType = inventoryItem
0428:                        .getString("inventoryItemTypeId");
0429:
0430:                // re-set the fields on the item
0431:                if (inventoryType.equals("NON_SERIAL_INV_ITEM")) {
0432:                    // add an adjusting InventoryItemDetail so set ATP back to QOH: ATP = ATP + (QOH - ATP), diff = QOH - ATP
0433:                    double atp = inventoryItem.get("availableToPromiseTotal") == null ? 0
0434:                            : inventoryItem
0435:                                    .getDouble("availableToPromiseTotal")
0436:                                    .doubleValue();
0437:                    double qoh = inventoryItem.get("quantityOnHandTotal") == null ? 0
0438:                            : inventoryItem.getDouble("quantityOnHandTotal")
0439:                                    .doubleValue();
0440:                    Map createDetailMap = UtilMisc.toMap(
0441:                            "availableToPromiseDiff", new Double(qoh - atp),
0442:                            "inventoryItemId", inventoryItem
0443:                                    .get("inventoryItemId"), "userLogin",
0444:                            userLogin);
0445:                    try {
0446:                        Map result = dctx.getDispatcher().runSync(
0447:                                "createInventoryItemDetail", createDetailMap);
0448:                        if (ServiceUtil.isError(result)) {
0449:                            return ServiceUtil
0450:                                    .returnError(
0451:                                            "Inventory Item Detail create problem in cancel inventory transfer",
0452:                                            null, null, result);
0453:                        }
0454:                    } catch (GenericServiceException e1) {
0455:                        return ServiceUtil
0456:                                .returnError("Inventory Item Detail create problem in cancel inventory transfer: ["
0457:                                        + e1.getMessage() + "]");
0458:                    }
0459:                } else if (inventoryType.equals("SERIALIZED_INV_ITEM")) {
0460:                    inventoryItem.set("statusId", "INV_AVAILABLE");
0461:                    // store the entity
0462:                    try {
0463:                        inventoryItem.store();
0464:                    } catch (GenericEntityException e) {
0465:                        return ServiceUtil
0466:                                .returnError("Inventory item store problem in cancel inventory transfer: ["
0467:                                        + e.getMessage() + "]");
0468:                    }
0469:                }
0470:
0471:                // set the inventory transfer record to complete
0472:                inventoryTransfer.set("statusId", "IXF_CANCELLED");
0473:
0474:                // store the entities
0475:                try {
0476:                    inventoryTransfer.store();
0477:                } catch (GenericEntityException e) {
0478:                    return ServiceUtil.returnError("Inventory store problem ["
0479:                            + e.getMessage() + "]");
0480:                }
0481:
0482:                return ServiceUtil.returnSuccess();
0483:            }
0484:
0485:            /** In spite of the generic name this does the very specific task of checking availability of all back-ordered items and sends notices, etc */
0486:            public static Map checkInventoryAvailability(DispatchContext dctx,
0487:                    Map context) {
0488:                GenericDelegator delegator = dctx.getDelegator();
0489:                LocalDispatcher dispatcher = dctx.getDispatcher();
0490:                GenericValue userLogin = (GenericValue) context
0491:                        .get("userLogin");
0492:
0493:                /* TODO: NOTE: This method has been updated, but testing requires many eyes. See http://jira.undersunconsulting.com/browse/OFBIZ-662
0494:                boolean skipThisNeedsUpdating = true;
0495:                if (skipThisNeedsUpdating) {
0496:                    Debug.logWarning("NOT Running the checkInventoryAvailability service, no backorders or such will be automatically created; the reason is that this serice needs to be updated to use OrderItemShipGroup instead of OrderShipmentPreference which it currently does.", module);
0497:                    return ServiceUtil.returnSuccess();
0498:                }
0499:                 */
0500:
0501:                Map ordersToUpdate = new HashMap();
0502:                Map ordersToCancel = new HashMap();
0503:
0504:                // find all inventory items w/ a negative ATP
0505:                List inventoryItems = null;
0506:                try {
0507:                    List exprs = UtilMisc.toList(new EntityExpr(
0508:                            "availableToPromiseTotal",
0509:                            EntityOperator.LESS_THAN, new Double(0)));
0510:                    inventoryItems = delegator
0511:                            .findByAnd("InventoryItem", exprs);
0512:                } catch (GenericEntityException e) {
0513:                    Debug
0514:                            .logError(e, "Trouble getting inventory items",
0515:                                    module);
0516:                    return ServiceUtil
0517:                            .returnError("Problem getting InventoryItem records");
0518:                }
0519:
0520:                if (inventoryItems == null) {
0521:                    Debug
0522:                            .logInfo(
0523:                                    "No items out of stock; no backorders to worry about",
0524:                                    module);
0525:                    return ServiceUtil.returnSuccess();
0526:                }
0527:
0528:                Debug.log("OOS Inventory Items: " + inventoryItems.size(),
0529:                        module);
0530:
0531:                Iterator itemsIter = inventoryItems.iterator();
0532:                while (itemsIter.hasNext()) {
0533:                    GenericValue inventoryItem = (GenericValue) itemsIter
0534:                            .next();
0535:
0536:                    // get the incomming shipment information for the item
0537:                    List shipmentAndItems = null;
0538:                    try {
0539:                        List exprs = new ArrayList();
0540:                        exprs.add(new EntityExpr("productId",
0541:                                EntityOperator.EQUALS, inventoryItem
0542:                                        .get("productId")));
0543:                        exprs.add(new EntityExpr("destinationFacilityId",
0544:                                EntityOperator.EQUALS, inventoryItem
0545:                                        .get("facilityId")));
0546:                        exprs
0547:                                .add(new EntityExpr("statusId",
0548:                                        EntityOperator.NOT_EQUAL,
0549:                                        "SHIPMENT_DELIVERED"));
0550:                        exprs
0551:                                .add(new EntityExpr("statusId",
0552:                                        EntityOperator.NOT_EQUAL,
0553:                                        "SHIPMENT_CANCELLED"));
0554:                        shipmentAndItems = delegator.findByAnd(
0555:                                "ShipmentAndItem", exprs, UtilMisc
0556:                                        .toList("estimatedArrivalDate"));
0557:                    } catch (GenericEntityException e) {
0558:                        Debug.logError(e,
0559:                                "Problem getting ShipmentAndItem records",
0560:                                module);
0561:                        return ServiceUtil
0562:                                .returnError("Problem getting ShipmentAndItem records");
0563:                    }
0564:
0565:                    // get the reservations in order of newest first
0566:                    List reservations = null;
0567:                    try {
0568:                        reservations = inventoryItem.getRelated(
0569:                                "OrderItemShipGrpInvRes", null, UtilMisc
0570:                                        .toList("-reservedDatetime"));
0571:                    } catch (GenericEntityException e) {
0572:                        Debug.logError(e,
0573:                                "Problem getting related reservations", module);
0574:                        return ServiceUtil
0575:                                .returnError("Problem getting related reservations");
0576:                    }
0577:
0578:                    if (reservations == null) {
0579:                        Debug
0580:                                .logWarning(
0581:                                        "No outstanding reservations for this inventory item, why is it negative then?",
0582:                                        module);
0583:                        continue;
0584:                    }
0585:
0586:                    Debug.log("Reservations for item: " + reservations.size(),
0587:                            module);
0588:
0589:                    // available at the time of order
0590:                    double availableBeforeReserved = inventoryItem.getDouble(
0591:                            "availableToPromiseTotal").doubleValue();
0592:
0593:                    // go through all the reservations in order
0594:                    Iterator ri = reservations.iterator();
0595:                    while (ri.hasNext()) {
0596:                        GenericValue reservation = (GenericValue) ri.next();
0597:                        String orderId = reservation.getString("orderId");
0598:                        String orderItemSeqId = reservation
0599:                                .getString("orderItemSeqId");
0600:                        Timestamp promisedDate = reservation
0601:                                .getTimestamp("promisedDatetime");
0602:                        Timestamp currentPromiseDate = reservation
0603:                                .getTimestamp("currentPromisedDate");
0604:                        Timestamp actualPromiseDate = currentPromiseDate;
0605:                        if (actualPromiseDate == null) {
0606:                            if (promisedDate != null) {
0607:                                actualPromiseDate = promisedDate;
0608:                            } else {
0609:                                // fall back if there is no promised date stored
0610:                                actualPromiseDate = reservation
0611:                                        .getTimestamp("reservedDatetime");
0612:                            }
0613:                        }
0614:
0615:                        Debug
0616:                                .log("Promised Date: " + actualPromiseDate,
0617:                                        module);
0618:
0619:                        // find the next possible ship date
0620:                        Timestamp nextShipDate = null;
0621:                        double availableAtTime = 0.00;
0622:                        Iterator si = shipmentAndItems.iterator();
0623:                        while (si.hasNext()) {
0624:                            GenericValue shipmentItem = (GenericValue) si
0625:                                    .next();
0626:                            availableAtTime += shipmentItem.getDouble(
0627:                                    "quantity").doubleValue();
0628:                            if (availableAtTime >= availableBeforeReserved) {
0629:                                nextShipDate = shipmentItem
0630:                                        .getTimestamp("estimatedArrivalDate");
0631:                                break;
0632:                            }
0633:                        }
0634:
0635:                        Debug.log("Next Ship Date: " + nextShipDate, module);
0636:
0637:                        // create a modified promise date (promise date - 1 day)
0638:                        Calendar pCal = Calendar.getInstance();
0639:                        pCal.setTimeInMillis(actualPromiseDate.getTime());
0640:                        pCal.add(Calendar.DAY_OF_YEAR, -1);
0641:                        Timestamp modifiedPromisedDate = new Timestamp(pCal
0642:                                .getTimeInMillis());
0643:                        Timestamp now = UtilDateTime.nowTimestamp();
0644:
0645:                        Debug.log("Promised Date + 1: " + modifiedPromisedDate,
0646:                                module);
0647:                        Debug.log("Now: " + now, module);
0648:
0649:                        // check the promised date vs the next ship date
0650:                        if (nextShipDate == null
0651:                                || nextShipDate.after(actualPromiseDate)) {
0652:                            if (nextShipDate == null
0653:                                    && modifiedPromisedDate.after(now)) {
0654:                                // do nothing; we are okay to assume it will be shipped on time
0655:                                Debug
0656:                                        .log(
0657:                                                "No ship date known yet, but promised date hasn't approached, assuming it will be here on time",
0658:                                                module);
0659:                            } else {
0660:                                // we cannot ship by the promised date; need to notify the customer
0661:                                Debug
0662:                                        .log(
0663:                                                "We won't ship on time, getting notification info",
0664:                                                module);
0665:                                Map notifyItems = (Map) ordersToUpdate
0666:                                        .get(orderId);
0667:                                if (notifyItems == null) {
0668:                                    notifyItems = new HashMap();
0669:                                }
0670:                                notifyItems.put(orderItemSeqId, nextShipDate);
0671:                                ordersToUpdate.put(orderId, notifyItems);
0672:
0673:                                // need to know if nextShipDate is more then 30 days after promised
0674:                                Calendar sCal = Calendar.getInstance();
0675:                                sCal.setTimeInMillis(actualPromiseDate
0676:                                        .getTime());
0677:                                sCal.add(Calendar.DAY_OF_YEAR, 30);
0678:                                Timestamp farPastPromised = new Timestamp(sCal
0679:                                        .getTimeInMillis());
0680:
0681:                                // check to see if this is >30 days or second run, if so flag to cancel
0682:                                boolean needToCancel = false;
0683:                                if (nextShipDate == null
0684:                                        || nextShipDate.after(farPastPromised)) {
0685:                                    // we cannot ship until >30 days after promised; using cancel rule
0686:                                    Debug
0687:                                            .log(
0688:                                                    "Ship date is >30 past the promised date",
0689:                                                    module);
0690:                                    needToCancel = true;
0691:                                } else if (currentPromiseDate != null
0692:                                        && actualPromiseDate
0693:                                                .equals(currentPromiseDate)) {
0694:                                    // this is the second notification; using cancel rule
0695:                                    needToCancel = true;
0696:                                }
0697:
0698:                                // add the info to the cancel map if we need to schedule a cancel
0699:                                if (needToCancel) {
0700:                                    // queue the item to be cancelled
0701:                                    Debug.log(
0702:                                            "Flagging the item to auto-cancel",
0703:                                            module);
0704:                                    Map cancelItems = (Map) ordersToCancel
0705:                                            .get(orderId);
0706:                                    if (cancelItems == null) {
0707:                                        cancelItems = new HashMap();
0708:                                    }
0709:                                    cancelItems.put(orderItemSeqId,
0710:                                            farPastPromised);
0711:                                    ordersToCancel.put(orderId, cancelItems);
0712:                                }
0713:
0714:                                // store the updated promiseDate as the nextShipDate
0715:                                try {
0716:                                    reservation.set("currentPromisedDate",
0717:                                            nextShipDate);
0718:                                    reservation.store();
0719:                                } catch (GenericEntityException e) {
0720:                                    Debug.logError(e,
0721:                                            "Problem storing reservation : "
0722:                                                    + reservation, module);
0723:                                }
0724:                            }
0725:                        }
0726:
0727:                        // subtract our qty from reserved to get the next value
0728:                        availableBeforeReserved -= reservation.getDouble(
0729:                                "quantity").doubleValue();
0730:                    }
0731:                }
0732:
0733:                // all items to cancel will also be in the notify list so start with that
0734:                List ordersToNotify = new ArrayList();
0735:                Set orderSet = ordersToUpdate.keySet();
0736:                Iterator orderIter = orderSet.iterator();
0737:                while (orderIter.hasNext()) {
0738:                    String orderId = (String) orderIter.next();
0739:                    Map backOrderedItems = (Map) ordersToUpdate.get(orderId);
0740:                    Map cancelItems = (Map) ordersToCancel.get(orderId);
0741:                    boolean cancelAll = false;
0742:                    Timestamp cancelAllTime = null;
0743:
0744:                    List orderItemShipGroups = null;
0745:                    try {
0746:                        orderItemShipGroups = delegator.findByAnd(
0747:                                "OrderItemShipGroup", UtilMisc.toMap("orderId",
0748:                                        orderId));
0749:                    } catch (GenericEntityException e) {
0750:                        Debug.logError(e,
0751:                                "Cannot get OrderItemShipGroups from orderId"
0752:                                        + orderId, module);
0753:                    }
0754:
0755:                    Iterator orderItemShipGroupsIter = orderItemShipGroups
0756:                            .iterator();
0757:                    while (orderItemShipGroupsIter.hasNext()) {
0758:                        GenericValue orderItemShipGroup = (GenericValue) orderItemShipGroupsIter
0759:                                .next();
0760:                        List orderItems = new java.util.Vector();
0761:                        List orderItemShipGroupAssoc = null;
0762:                        try {
0763:                            orderItemShipGroupAssoc = delegator.findByAnd(
0764:                                    "OrderItemShipGroupAssoc", UtilMisc.toMap(
0765:                                            "shipGroupSeqId",
0766:                                            orderItemShipGroup
0767:                                                    .get("shipGroupSeqId"),
0768:                                            "orderId", orderId));
0769:
0770:                            Iterator assocIter = orderItemShipGroupAssoc
0771:                                    .iterator();
0772:                            while (assocIter.hasNext()) {
0773:                                GenericValue assoc = (GenericValue) assocIter
0774:                                        .next();
0775:                                GenericValue orderItem = assoc
0776:                                        .getRelatedOne("OrderItem");
0777:                                if (orderItem != null) {
0778:                                    orderItems.add(orderItem);
0779:                                }
0780:                            }
0781:                        } catch (GenericEntityException e) {
0782:                            Debug.logError(e,
0783:                                    "Problem fetching OrderItemShipGroupAssoc",
0784:                                    module);
0785:                        }
0786:
0787:                        /* Check the split preference. */
0788:                        boolean maySplit = false;
0789:                        if (orderItemShipGroup != null
0790:                                && orderItemShipGroup.get("maySplit") != null) {
0791:                            maySplit = orderItemShipGroup
0792:                                    .getBoolean("maySplit").booleanValue();
0793:                        }
0794:
0795:                        /* Figure out if we must cancel all items. */
0796:                        if (!maySplit && cancelItems != null) {
0797:                            cancelAll = true;
0798:                            Set cancelSet = cancelItems.keySet();
0799:                            cancelAllTime = (Timestamp) cancelItems
0800:                                    .get(cancelSet.iterator().next());
0801:                        }
0802:
0803:                        // if there are none to cancel just create an empty map
0804:                        if (cancelItems == null) {
0805:                            cancelItems = new HashMap();
0806:                        }
0807:
0808:                        if (orderItems != null) {
0809:                            List toBeStored = new ArrayList();
0810:                            Iterator orderItemsIter = orderItems.iterator();
0811:                            while (orderItemsIter.hasNext()) {
0812:                                GenericValue orderItem = (GenericValue) orderItemsIter
0813:                                        .next();
0814:                                String orderItemSeqId = orderItem
0815:                                        .getString("orderItemSeqId");
0816:                                Timestamp shipDate = (Timestamp) backOrderedItems
0817:                                        .get(orderItemSeqId);
0818:                                Timestamp cancelDate = (Timestamp) cancelItems
0819:                                        .get(orderItemSeqId);
0820:                                Timestamp currentCancelDate = orderItem
0821:                                        .getTimestamp("autoCancelDate");
0822:
0823:                                Debug.logError("OI: " + orderId + " SEQID: "
0824:                                        + orderItemSeqId + " cancelAll: "
0825:                                        + cancelAll + " cancelDate: "
0826:                                        + cancelDate, module);
0827:                                if (backOrderedItems
0828:                                        .containsKey(orderItemSeqId)) {
0829:                                    orderItem
0830:                                            .set("estimatedShipDate", shipDate);
0831:
0832:                                    if (currentCancelDate == null) {
0833:                                        if (cancelAll || cancelDate != null) {
0834:                                            if (orderItem
0835:                                                    .get("dontCancelSetUserLogin") == null
0836:                                                    && orderItem
0837:                                                            .get("dontCancelSetDate") == null) {
0838:                                                if (cancelAllTime != null) {
0839:                                                    orderItem.set(
0840:                                                            "autoCancelDate",
0841:                                                            cancelAllTime);
0842:                                                } else {
0843:                                                    orderItem.set(
0844:                                                            "autoCancelDate",
0845:                                                            cancelDate);
0846:                                                }
0847:                                            }
0848:                                        }
0849:                                        // only notify orders which have not already sent the final notice
0850:                                        ordersToNotify.add(orderId);
0851:                                    }
0852:                                    toBeStored.add(orderItem);
0853:                                }
0854:                            }
0855:                            if (toBeStored.size() > 0) {
0856:                                try {
0857:                                    delegator.storeAll(toBeStored);
0858:                                } catch (GenericEntityException e) {
0859:                                    Debug.logError(e,
0860:                                            "Problem storing order items",
0861:                                            module);
0862:                                }
0863:                            }
0864:                        }
0865:
0866:                    }
0867:                }
0868:
0869:                // send off a notification for each order        
0870:                Iterator orderNotifyIter = ordersToNotify.iterator();
0871:                while (orderNotifyIter.hasNext()) {
0872:                    String orderId = (String) orderNotifyIter.next();
0873:
0874:                    try {
0875:                        dispatcher.runAsync("sendOrderBackorderNotification",
0876:                                UtilMisc.toMap("orderId", orderId, "userLogin",
0877:                                        userLogin));
0878:                    } catch (GenericServiceException e) {
0879:                        Debug
0880:                                .logError(
0881:                                        e,
0882:                                        "Problems sending off the notification",
0883:                                        module);
0884:                        continue;
0885:                    }
0886:                }
0887:
0888:                return ServiceUtil.returnSuccess();
0889:            }
0890:
0891:            /**
0892:             * Get Inventory Available for a Product based on the list of associated products.  The final ATP and QOH will
0893:             * be the minimum of all the associated products' inventory divided by their ProductAssoc.quantity 
0894:             * */
0895:            public static Map getProductInventoryAvailableFromAssocProducts(
0896:                    DispatchContext dctx, Map context) {
0897:                LocalDispatcher dispatcher = dctx.getDispatcher();
0898:                List productAssocList = (List) context.get("assocProducts");
0899:                String facilityId = (String) context.get("facilityId");
0900:
0901:                Double availableToPromiseTotal = new Double(0);
0902:                Double quantityOnHandTotal = new Double(0);
0903:
0904:                if (productAssocList != null && productAssocList.size() > 0) {
0905:                    // minimum QOH and ATP encountered
0906:                    double minQuantityOnHandTotal = Double.MAX_VALUE;
0907:                    double minAvailableToPromiseTotal = Double.MAX_VALUE;
0908:
0909:                    // loop through each associated product.  
0910:                    for (int i = 0; productAssocList.size() > i; i++) {
0911:                        GenericValue productAssoc = (GenericValue) productAssocList
0912:                                .get(i);
0913:                        String productIdTo = productAssoc
0914:                                .getString("productIdTo");
0915:                        Double assocQuantity = productAssoc
0916:                                .getDouble("quantity");
0917:
0918:                        // if there is no quantity for the associated product in ProductAssoc entity, default it to 1.0
0919:                        if (assocQuantity == null) {
0920:                            Debug
0921:                                    .logWarning(
0922:                                            "ProductAssoc from ["
0923:                                                    + productAssoc
0924:                                                            .getString("productId")
0925:                                                    + "] to ["
0926:                                                    + productAssoc
0927:                                                            .getString("productIdTo")
0928:                                                    + "] has no quantity, assuming 1.0",
0929:                                            module);
0930:                            assocQuantity = new Double(1.0);
0931:                        }
0932:
0933:                        // figure out the inventory available for this associated product
0934:                        Map resultOutput = null;
0935:                        try {
0936:                            Map inputMap = UtilMisc.toMap("productId",
0937:                                    productIdTo);
0938:                            if (facilityId != null) {
0939:                                inputMap.put("facilityId", facilityId);
0940:                                resultOutput = dispatcher.runSync(
0941:                                        "getInventoryAvailableByFacility",
0942:                                        inputMap);
0943:                            } else {
0944:                                resultOutput = dispatcher.runSync(
0945:                                        "getProductInventoryAvailable",
0946:                                        inputMap);
0947:                            }
0948:                        } catch (GenericServiceException e) {
0949:                            Debug
0950:                                    .logError(
0951:                                            e,
0952:                                            "Problems getting inventory available by facility",
0953:                                            module);
0954:                            return ServiceUtil.returnError(e.getMessage());
0955:                        }
0956:
0957:                        // Figure out what the QOH and ATP inventory would be with this associated product
0958:                        Double currentQuantityOnHandTotal = (Double) resultOutput
0959:                                .get("quantityOnHandTotal");
0960:                        Double currentAvailableToPromiseTotal = (Double) resultOutput
0961:                                .get("availableToPromiseTotal");
0962:                        double tmpQuantityOnHandTotal = currentQuantityOnHandTotal
0963:                                .doubleValue()
0964:                                / assocQuantity.doubleValue();
0965:                        double tmpAvailableToPromiseTotal = currentAvailableToPromiseTotal
0966:                                .doubleValue()
0967:                                / assocQuantity.doubleValue();
0968:
0969:                        // reset the minimum QOH and ATP quantities if those quantities for this product are less 
0970:                        if (tmpQuantityOnHandTotal < minQuantityOnHandTotal) {
0971:                            minQuantityOnHandTotal = tmpQuantityOnHandTotal;
0972:                        }
0973:                        if (tmpAvailableToPromiseTotal < minAvailableToPromiseTotal) {
0974:                            minAvailableToPromiseTotal = tmpAvailableToPromiseTotal;
0975:                        }
0976:
0977:                        if (Debug.verboseOn()) {
0978:                            Debug.logVerbose(
0979:                                    "productIdTo = " + productIdTo
0980:                                            + " assocQuantity = "
0981:                                            + assocQuantity + "current QOH "
0982:                                            + currentQuantityOnHandTotal
0983:                                            + "currentATP = "
0984:                                            + currentAvailableToPromiseTotal
0985:                                            + " minQOH = "
0986:                                            + minQuantityOnHandTotal
0987:                                            + " minATP = "
0988:                                            + minAvailableToPromiseTotal,
0989:                                    module);
0990:                        }
0991:                    }
0992:                    // the final QOH and ATP quantities are the minimum of all the products 
0993:                    quantityOnHandTotal = new Double(minQuantityOnHandTotal);
0994:                    availableToPromiseTotal = new Double(
0995:                            minAvailableToPromiseTotal);
0996:                }
0997:
0998:                Map result = ServiceUtil.returnSuccess();
0999:                result.put("availableToPromiseTotal", availableToPromiseTotal);
1000:                result.put("quantityOnHandTotal", quantityOnHandTotal);
1001:                return result;
1002:            }
1003:
1004:            public static Map getProductInventorySummaryForItems(
1005:                    DispatchContext dctx, Map context) {
1006:                GenericDelegator delegator = dctx.getDelegator();
1007:                LocalDispatcher dispatcher = dctx.getDispatcher();
1008:                List orderItems = (List) context.get("orderItems");
1009:                Map atpMap = new HashMap();
1010:                Map qohMap = new HashMap();
1011:                Map mktgPkgAtpMap = new HashMap();
1012:                Map mktgPkgQohMap = new HashMap();
1013:                Map results = ServiceUtil.returnSuccess();
1014:
1015:                // get a list of all available facilities for looping
1016:                List facilities = null;
1017:                try {
1018:                    facilities = delegator.findAll("Facility");
1019:                } catch (GenericEntityException e) {
1020:                    Debug.logError(e, "Couldn't get list of facilities.",
1021:                            module);
1022:                    return ServiceUtil
1023:                            .returnError("Unable to locate facilities.");
1024:                }
1025:
1026:                // loop through all the order items
1027:                Iterator iter = orderItems.iterator();
1028:                while (iter.hasNext()) {
1029:                    GenericValue orderItem = (GenericValue) iter.next();
1030:                    String productId = orderItem.getString("productId");
1031:
1032:                    if ((productId == null) || productId.equals(""))
1033:                        continue;
1034:
1035:                    GenericValue product = null;
1036:                    try {
1037:                        product = orderItem.getRelatedOneCache("Product");
1038:                    } catch (GenericEntityException e) {
1039:                        Debug.logError(e, "Couldn't get product.", module);
1040:                        return ServiceUtil
1041:                                .returnError("Unable to retrive product with id ["
1042:                                        + productId + "]");
1043:                    }
1044:
1045:                    double atp = 0.0;
1046:                    double qoh = 0.0;
1047:                    double mktgPkgAtp = 0.0;
1048:                    double mktgPkgQoh = 0.0;
1049:                    Iterator facilityIter = facilities.iterator();
1050:
1051:                    // loop through all the facilities
1052:                    while (facilityIter.hasNext()) {
1053:                        GenericValue facility = (GenericValue) facilityIter
1054:                                .next();
1055:                        Map invResult = null;
1056:                        Map mktgPkgInvResult = null;
1057:
1058:                        // get both the real ATP/QOH available and the quantities available from marketing packages
1059:                        try {
1060:                            if ("MARKETING_PKG_AUTO".equals(product
1061:                                    .getString("productTypeId"))) {
1062:                                mktgPkgInvResult = dispatcher
1063:                                        .runSync(
1064:                                                "getMktgPackagesAvailable",
1065:                                                UtilMisc
1066:                                                        .toMap(
1067:                                                                "productId",
1068:                                                                productId,
1069:                                                                "facilityId",
1070:                                                                facility
1071:                                                                        .getString("facilityId")));
1072:                            }
1073:                            invResult = dispatcher.runSync(
1074:                                    "getInventoryAvailableByFacility",
1075:                                    UtilMisc.toMap("productId", productId,
1076:                                            "facilityId", facility
1077:                                                    .getString("facilityId")));
1078:                        } catch (GenericServiceException e) {
1079:                            String msg = "Could not find inventory for facility ["
1080:                                    + facility.getString("facilityId") + "]";
1081:                            Debug.logError(e, msg, module);
1082:                            return ServiceUtil.returnError(msg);
1083:                        }
1084:
1085:                        // add the results for this facility to the ATP/QOH counter for all facilities
1086:                        if (!ServiceUtil.isError(invResult)) {
1087:                            Double fatp = (Double) invResult
1088:                                    .get("availableToPromiseTotal");
1089:                            Double fqoh = (Double) invResult
1090:                                    .get("quantityOnHandTotal");
1091:                            if (fatp != null)
1092:                                atp += fatp.doubleValue();
1093:                            if (fqoh != null)
1094:                                qoh += fqoh.doubleValue();
1095:                        }
1096:                        if (("MARKETING_PKG_AUTO".equals(product
1097:                                .getString("productTypeId")))
1098:                                && (!ServiceUtil.isError(mktgPkgInvResult))) {
1099:                            Double fatp = (Double) mktgPkgInvResult
1100:                                    .get("availableToPromiseTotal");
1101:                            Double fqoh = (Double) mktgPkgInvResult
1102:                                    .get("quantityOnHandTotal");
1103:                            if (fatp != null)
1104:                                mktgPkgAtp += fatp.doubleValue();
1105:                            if (fqoh != null)
1106:                                mktgPkgQoh += fqoh.doubleValue();
1107:                        }
1108:                    }
1109:
1110:                    atpMap.put(productId, new Double(atp));
1111:                    qohMap.put(productId, new Double(qoh));
1112:                    mktgPkgAtpMap.put(productId, new Double(mktgPkgAtp));
1113:                    mktgPkgQohMap.put(productId, new Double(mktgPkgQoh));
1114:                }
1115:
1116:                results.put("availableToPromiseMap", atpMap);
1117:                results.put("quantityOnHandMap", qohMap);
1118:                results.put("mktgPkgATPMap", mktgPkgAtpMap);
1119:                results.put("mktgPkgQOHMap", mktgPkgQohMap);
1120:                return results;
1121:            }
1122:
1123:            public static Map getProductInventoryAndFacilitySummary(
1124:                    DispatchContext dctx, Map context) {
1125:                GenericDelegator delegator = dctx.getDelegator();
1126:                LocalDispatcher dispatcher = dctx.getDispatcher();
1127:                Timestamp checkTime = (Timestamp) context.get("checkTime");
1128:                String facilityId = (String) context.get("facilityId");
1129:                String productId = (String) context.get("productId");
1130:                String minimumStock = (String) context.get("minimumStock");
1131:
1132:                Map result = new HashMap();
1133:                Map resultOutput = new HashMap();
1134:
1135:                Map contextInput = UtilMisc.toMap("productId", productId,
1136:                        "facilityId", facilityId);
1137:                GenericValue product = null;
1138:                try {
1139:                    product = delegator.findByPrimaryKey("Product", UtilMisc
1140:                            .toMap("productId", productId));
1141:                } catch (GenericEntityException e) {
1142:                    // TODO Auto-generated catch block
1143:                    e.printStackTrace();
1144:                }
1145:                if ("MARKETING_PKG_AUTO".equals(product
1146:                        .getString("productTypeId"))) {
1147:                    try {
1148:                        resultOutput = dispatcher.runSync(
1149:                                "getMktgPackagesAvailable", contextInput);
1150:                    } catch (GenericServiceException e) {
1151:                        // TODO Auto-generated catch block
1152:                        e.printStackTrace();
1153:                    }
1154:                } else {
1155:                    try {
1156:                        resultOutput = dispatcher
1157:                                .runSync("getInventoryAvailableByFacility",
1158:                                        contextInput);
1159:                    } catch (GenericServiceException e) {
1160:                        // TODO Auto-generated catch block
1161:                        e.printStackTrace();
1162:                    }
1163:                }
1164:                // filter for quantities
1165:                int minimumStockInt = 0;
1166:                if (minimumStock != null) {
1167:                    minimumStockInt = new Double(minimumStock).intValue();
1168:                }
1169:
1170:                int quantityOnHandTotalInt = 0;
1171:                if (resultOutput.get("quantityOnHandTotal") != null) {
1172:                    quantityOnHandTotalInt = ((Double) resultOutput
1173:                            .get("quantityOnHandTotal")).intValue();
1174:                }
1175:                int offsetQOHQtyAvailable = quantityOnHandTotalInt
1176:                        - minimumStockInt;
1177:
1178:                int availableToPromiseTotalInt = 0;
1179:                if (resultOutput.get("availableToPromiseTotal") != null) {
1180:                    availableToPromiseTotalInt = ((Double) resultOutput
1181:                            .get("availableToPromiseTotal")).intValue();
1182:                }
1183:                int offsetATPQtyAvailable = availableToPromiseTotalInt
1184:                        - minimumStockInt;
1185:
1186:                double quantityOnOrder = InventoryWorker
1187:                        .getOutstandingPurchasedQuantity(productId, delegator);
1188:                result.put("totalQuantityOnHand", resultOutput.get(
1189:                        "quantityOnHandTotal").toString());
1190:                result.put("totalAvailableToPromise", resultOutput.get(
1191:                        "availableToPromiseTotal").toString());
1192:                result.put("quantityOnOrder", new Double(quantityOnOrder));
1193:
1194:                result.put("offsetQOHQtyAvailable", new Integer(
1195:                        offsetQOHQtyAvailable));
1196:                result.put("offsetATPQtyAvailable", new Integer(
1197:                        offsetATPQtyAvailable));
1198:
1199:                List productPrices = null;
1200:                try {
1201:                    productPrices = (List) delegator.findByAndCache(
1202:                            "ProductPrice", UtilMisc.toMap("productId",
1203:                                    productId), UtilMisc.toList("-fromDate"));
1204:                } catch (GenericEntityException e) {
1205:                    // TODO Auto-generated catch block
1206:                    e.printStackTrace();
1207:                }
1208:                Iterator pricesIt = productPrices.iterator();
1209:                //change this for product price
1210:                while (pricesIt.hasNext()) {
1211:                    GenericValue onePrice = (GenericValue) pricesIt.next();
1212:                    if (onePrice.getString("productPriceTypeId").equals(
1213:                            "DEFAULT_PRICE")) { //defaultPrice
1214:                        result.put("defultPrice", onePrice.getDouble("price"));
1215:                    } else if (onePrice.getString("productPriceTypeId").equals(
1216:                            "WHOLESALE_PRICE")) {//
1217:                        result.put("wholeSalePrice", onePrice
1218:                                .getDouble("price"));
1219:                    } else if (onePrice.getString("productPriceTypeId").equals(
1220:                            "LIST_PRICE")) {//listPrice
1221:                        result.put("listPrice", onePrice.getDouble("price"));
1222:                    } else {
1223:                        result.put("defultPrice", onePrice.getDouble("price"));
1224:                        result.put("listPrice", onePrice.getDouble("price"));
1225:                        result.put("wholeSalePrice", onePrice
1226:                                .getDouble("price"));
1227:                    }
1228:                }
1229:
1230:                DynamicViewEntity salesUsageViewEntity = new DynamicViewEntity();
1231:                DynamicViewEntity productionUsageViewEntity = new DynamicViewEntity();
1232:                if (!UtilValidate.isEmpty(checkTime)) {
1233:
1234:                    // Construct a dynamic view entity to search against for sales usage quantities
1235:                    salesUsageViewEntity.addMemberEntity("OI", "OrderItem");
1236:                    salesUsageViewEntity.addMemberEntity("OH", "OrderHeader");
1237:                    salesUsageViewEntity.addMemberEntity("ItIss",
1238:                            "ItemIssuance");
1239:                    salesUsageViewEntity.addMemberEntity("InvIt",
1240:                            "InventoryItem");
1241:                    salesUsageViewEntity.addViewLink("OI", "OH", new Boolean(
1242:                            false), ModelKeyMap.makeKeyMapList("orderId"));
1243:                    salesUsageViewEntity.addViewLink("OI", "ItIss",
1244:                            new Boolean(false), ModelKeyMap.makeKeyMapList(
1245:                                    "orderId", "orderId", "orderItemSeqId",
1246:                                    "orderItemSeqId"));
1247:                    salesUsageViewEntity.addViewLink("ItIss", "InvIt",
1248:                            new Boolean(false), ModelKeyMap
1249:                                    .makeKeyMapList("inventoryItemId"));
1250:                    salesUsageViewEntity.addAlias("OI", "productId");
1251:                    salesUsageViewEntity.addAlias("OH", "statusId");
1252:                    salesUsageViewEntity.addAlias("OH", "orderTypeId");
1253:                    salesUsageViewEntity.addAlias("OH", "orderDate");
1254:                    salesUsageViewEntity.addAlias("ItIss", "inventoryItemId");
1255:                    salesUsageViewEntity.addAlias("ItIss", "quantity");
1256:                    salesUsageViewEntity.addAlias("InvIt", "facilityId");
1257:
1258:                    // Construct a dynamic view entity to search against for production usage quantities
1259:                    productionUsageViewEntity.addMemberEntity("WEIA",
1260:                            "WorkEffortInventoryAssign");
1261:                    productionUsageViewEntity.addMemberEntity("WE",
1262:                            "WorkEffort");
1263:                    productionUsageViewEntity.addMemberEntity("II",
1264:                            "InventoryItem");
1265:                    productionUsageViewEntity.addViewLink("WEIA", "WE",
1266:                            new Boolean(false), ModelKeyMap
1267:                                    .makeKeyMapList("workEffortId"));
1268:                    productionUsageViewEntity.addViewLink("WEIA", "II",
1269:                            new Boolean(false), ModelKeyMap
1270:                                    .makeKeyMapList("inventoryItemId"));
1271:                    productionUsageViewEntity.addAlias("WEIA", "quantity");
1272:                    productionUsageViewEntity.addAlias("WE",
1273:                            "actualCompletionDate");
1274:                    productionUsageViewEntity
1275:                            .addAlias("WE", "workEffortTypeId");
1276:                    productionUsageViewEntity.addAlias("II", "facilityId");
1277:                    productionUsageViewEntity.addAlias("II", "productId");
1278:
1279:                }
1280:                if (!UtilValidate.isEmpty(checkTime)) {
1281:
1282:                    // Make a query against the sales usage view entity
1283:                    EntityListIterator salesUsageIt = null;
1284:                    try {
1285:                        salesUsageIt = delegator
1286:                                .findListIteratorByCondition(
1287:                                        salesUsageViewEntity,
1288:                                        new EntityConditionList(
1289:                                                UtilMisc
1290:                                                        .toList(
1291:                                                                new EntityExpr(
1292:                                                                        "facilityId",
1293:                                                                        EntityOperator.EQUALS,
1294:                                                                        facilityId),
1295:                                                                new EntityExpr(
1296:                                                                        "productId",
1297:                                                                        EntityOperator.EQUALS,
1298:                                                                        productId),
1299:                                                                new EntityExpr(
1300:                                                                        "statusId",
1301:                                                                        EntityOperator.IN,
1302:                                                                        UtilMisc
1303:                                                                                .toList(
1304:                                                                                        "ORDER_COMPLETED",
1305:                                                                                        "ORDER_APPROVED",
1306:                                                                                        "ORDER_HELD")),
1307:                                                                new EntityExpr(
1308:                                                                        "orderTypeId",
1309:                                                                        EntityOperator.EQUALS,
1310:                                                                        "SALES_ORDER"),
1311:                                                                new EntityExpr(
1312:                                                                        "orderDate",
1313:                                                                        EntityOperator.GREATER_THAN_EQUAL_TO,
1314:                                                                        checkTime)),
1315:                                                EntityOperator.AND), null,
1316:                                        null, null, null);
1317:                    } catch (GenericEntityException e2) {
1318:                        // TODO Auto-generated catch block
1319:                        e2.printStackTrace();
1320:                    }
1321:
1322:                    // Sum the sales usage quantities found
1323:                    double salesUsageQuantity = 0;
1324:                    GenericValue salesUsageItem = null;
1325:                    while ((salesUsageItem = (GenericValue) salesUsageIt.next()) != null) {
1326:                        if (salesUsageItem.get("quantity") != null) {
1327:                            try {
1328:                                salesUsageQuantity += salesUsageItem.getDouble(
1329:                                        "quantity").doubleValue();
1330:                            } catch (Exception e) {
1331:                                // Ignore
1332:                            }
1333:                        }
1334:                    }
1335:                    try {
1336:                        salesUsageIt.close();
1337:                    } catch (GenericEntityException e2) {
1338:                        // TODO Auto-generated catch block
1339:                        e2.printStackTrace();
1340:                    }
1341:
1342:                    // Make a query against the production usage view entity
1343:                    EntityListIterator productionUsageIt = null;
1344:                    try {
1345:                        productionUsageIt = delegator
1346:                                .findListIteratorByCondition(
1347:                                        productionUsageViewEntity,
1348:                                        new EntityConditionList(
1349:                                                UtilMisc
1350:                                                        .toList(
1351:                                                                new EntityExpr(
1352:                                                                        "facilityId",
1353:                                                                        EntityOperator.EQUALS,
1354:                                                                        facilityId),
1355:                                                                new EntityExpr(
1356:                                                                        "productId",
1357:                                                                        EntityOperator.EQUALS,
1358:                                                                        productId),
1359:                                                                new EntityExpr(
1360:                                                                        "workEffortTypeId",
1361:                                                                        EntityOperator.EQUALS,
1362:                                                                        "PROD_ORDER_TASK"),
1363:                                                                new EntityExpr(
1364:                                                                        "actualCompletionDate",
1365:                                                                        EntityOperator.GREATER_THAN_EQUAL_TO,
1366:                                                                        checkTime)),
1367:                                                EntityOperator.AND), null,
1368:                                        null, null, null);
1369:                    } catch (GenericEntityException e1) {
1370:                        // TODO Auto-generated catch block
1371:                        e1.printStackTrace();
1372:                    }
1373:
1374:                    // Sum the production usage quantities found
1375:                    double productionUsageQuantity = 0;
1376:                    GenericValue productionUsageItem = null;
1377:                    while ((productionUsageItem = (GenericValue) productionUsageIt
1378:                            .next()) != null) {
1379:                        if (productionUsageItem.get("quantity") != null) {
1380:                            try {
1381:                                productionUsageQuantity += productionUsageItem
1382:                                        .getDouble("quantity").doubleValue();
1383:                            } catch (Exception e) {
1384:                                // Ignore
1385:                            }
1386:                        }
1387:                    }
1388:                    try {
1389:                        productionUsageIt.close();
1390:                    } catch (GenericEntityException e) {
1391:                        // TODO Auto-generated catch block
1392:                        e.printStackTrace();
1393:                    }
1394:
1395:                    result.put("usageQuantity", new Double(
1396:                            (salesUsageQuantity + productionUsageQuantity)));
1397:
1398:                }
1399:                return result;
1400:            }
1401:
1402:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.