svn commit: r1695126 [3/22] - in /ofbiz/trunk: applications/accounting/src/org/ofbiz/accounting/thirdparty/authorizedotnet/ applications/accounting/src/org/ofbiz/accounting/thirdparty/securepay/ applications/content/src/org/ofbiz/content/webapp/ftl/ ap...

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r1695126 [3/22] - in /ofbiz/trunk: applications/accounting/src/org/ofbiz/accounting/thirdparty/authorizedotnet/ applications/accounting/src/org/ofbiz/accounting/thirdparty/securepay/ applications/content/src/org/ofbiz/content/webapp/ftl/ ap...

jleroux@apache.org
Modified: ofbiz/trunk/applications/order/src/org/ofbiz/order/requirement/RequirementServices.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/src/org/ofbiz/order/requirement/RequirementServices.java?rev=1695126&r1=1695125&r2=1695126&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/src/org/ofbiz/order/requirement/RequirementServices.java (original)
+++ ofbiz/trunk/applications/order/src/org/ofbiz/order/requirement/RequirementServices.java Mon Aug 10 16:15:37 2015
@@ -1,332 +1,332 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.ofbiz.order.requirement;
-
-import java.util.*;
-import java.math.BigDecimal;
-import java.sql.Timestamp;
-
-import org.ofbiz.base.util.*;
-import org.ofbiz.entity.condition.*;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.GenericEntityException;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.entity.util.EntityQuery;
-import org.ofbiz.entity.util.EntityUtil;
-import org.ofbiz.service.DispatchContext;
-import org.ofbiz.service.GenericServiceException;
-import org.ofbiz.service.LocalDispatcher;
-import org.ofbiz.service.ServiceUtil;
-
-/**
- * Requirement Services
- */
-
-public class RequirementServices {
-
-    public static final String module = RequirementServices.class.getName();
-    public static final String resource_error = "OrderErrorUiLabels";
-
-    public static Map<String, Object> getRequirementsForSupplier(DispatchContext ctx, Map<String, ? extends Object> context) {
-        Delegator delegator = ctx.getDelegator();
-        LocalDispatcher dispatcher = ctx.getDispatcher();
-        Locale locale = (Locale) context.get("locale");
-
-        EntityCondition requirementConditions = (EntityCondition) context.get("requirementConditions");
-        String partyId = (String) context.get("partyId");
-        String unassignedRequirements = (String) context.get("unassignedRequirements");
-        List<String> statusIds = UtilGenerics.checkList(context.get("statusIds"));
-        //TODO currencyUomId still not used
-        //String currencyUomId = (String) context.get("currencyUomId");
-        try {
-            List<EntityCondition> conditions = UtilMisc.toList(
-                    EntityCondition.makeCondition("requirementTypeId", EntityOperator.EQUALS, "PRODUCT_REQUIREMENT"),
-                    EntityUtil.getFilterByDateExpr()
-                   );
-            if (UtilValidate.isNotEmpty(statusIds)) {
-                conditions.add(EntityCondition.makeCondition("statusId", EntityOperator.IN, statusIds));
-            } else {
-                conditions.add(EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "REQ_APPROVED"));
-            }
-            if (requirementConditions != null) conditions.add(requirementConditions);
-
-            // we're either getting the requirements for a given supplier, unassigned requirements, or requirements for all suppliers
-            if (UtilValidate.isNotEmpty(partyId)) {
-                conditions.add(EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, partyId));
-                conditions.add(EntityCondition.makeCondition("roleTypeId", EntityOperator.EQUALS, "SUPPLIER"));
-            } else if (UtilValidate.isNotEmpty(unassignedRequirements)) {
-                conditions.add(EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, null));
-            } else {
-                conditions.add(EntityCondition.makeCondition("roleTypeId", EntityOperator.EQUALS, "SUPPLIER"));
-            }
-
-            List<GenericValue> requirementAndRoles = EntityQuery.use(delegator).from("RequirementAndRole")
-                    .where(conditions)
-                    .orderBy("partyId", "requirementId")
-                    .queryList();
-
-            // maps to cache the associated suppliers and products data, so we don't do redundant DB and service requests
-            Map<String, GenericValue> suppliers = new HashMap<String, GenericValue>();
-            Map<String, GenericValue> gids = new HashMap<String, GenericValue>();
-            Map<String, Map<String, Object>> inventories = new HashMap<String, Map<String,Object>>();
-            Map<String, BigDecimal> productsSold = new HashMap<String, BigDecimal>();
-
-            // to count quantity, running total, and distinct products in list
-            BigDecimal quantity = BigDecimal.ZERO;
-            BigDecimal amountTotal = BigDecimal.ZERO;
-            Set<String> products = new HashSet<String>();
-
-            // time period to count products ordered from, six months ago and the 1st of that month
-            Timestamp timePeriodStart = UtilDateTime.getMonthStart(UtilDateTime.nowTimestamp(), 0, -6);
-
-            // join in fields with extra data about the suppliers and products
-            List<Map<String, Object>> requirements = new LinkedList<Map<String,Object>>();
-            for (GenericValue requirement : requirementAndRoles) {
-                Map<String, Object> union = new HashMap<String, Object>();
-                String productId = requirement.getString("productId");
-                partyId = requirement.getString("partyId");
-                String facilityId = requirement.getString("facilityId");
-                BigDecimal requiredQuantity = requirement.getBigDecimal("quantity");
-
-                // get an available supplier product, preferably the one with the smallest minimum quantity to order, followed by price
-                String supplierKey =  partyId + "^" + productId;
-                GenericValue supplierProduct = suppliers.get(supplierKey);
-                if (supplierProduct == null) {
-                    // TODO: it is possible to restrict to quantity > minimumOrderQuantity, but then the entire requirement must be skipped
-                    supplierProduct = EntityQuery.use(delegator).from("SupplierProduct")
-                            .where("partyId", partyId, "productId", productId)
-                            .orderBy("minimumOrderQuantity", "lastPrice")
-                            .filterByDate("availableFromDate", "availableThruDate")
-                            .queryFirst();
-                    suppliers.put(supplierKey, supplierProduct);
-                }
-
-                // add our supplier product and cost of this line to the data
-                if (supplierProduct != null) {
-                    union.putAll(supplierProduct.getAllFields());
-                    BigDecimal lastPrice = supplierProduct.getBigDecimal("lastPrice");
-                    amountTotal = amountTotal.add(lastPrice.multiply(requiredQuantity));
-                }
-
-                // for good identification, get the UPCA type (UPC code)
-                GenericValue gid = gids.get(productId);
-                if (gid == null) {
-                    gid = EntityQuery.use(delegator).from("GoodIdentification").where("goodIdentificationTypeId", "UPCA", "productId", requirement.get("productId")).queryOne();
-                    gids.put(productId, gid);
-                }
-                if (gid != null) union.put("idValue", gid.get("idValue"));
-
-                // the ATP and QOH quantities
-                if (UtilValidate.isNotEmpty(facilityId)) {
-                    String inventoryKey = facilityId + "^" + productId;
-                    Map<String, Object> inventory = inventories.get(inventoryKey);
-                    if (inventory == null) {
-                        inventory = dispatcher.runSync("getInventoryAvailableByFacility", UtilMisc.toMap("productId", productId, "facilityId", facilityId));
-                        if (ServiceUtil.isError(inventory)) {
-                            return inventory;
-                        }
-                        inventories.put(inventoryKey, inventory);
-                    }
-                    if (inventory != null) {
-                        union.put("qoh", inventory.get("quantityOnHandTotal"));
-                        union.put("atp", inventory.get("availableToPromiseTotal"));
-                    }
-                }
-
-                // how many of the products were sold (note this is for a fixed time period across all product stores)
-                BigDecimal sold = productsSold.get(productId);
-                if (sold == null) {
-                    EntityCondition prodConditions = EntityCondition.makeCondition(UtilMisc.toList(
-                                EntityCondition.makeCondition("productId", EntityOperator.EQUALS, productId),
-                                EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "SALES_ORDER"),
-                                EntityCondition.makeCondition("orderStatusId", EntityOperator.NOT_IN, UtilMisc.toList("ORDER_REJECTED", "ORDER_CANCELLED")),
-                                EntityCondition.makeCondition("orderItemStatusId", EntityOperator.NOT_IN, UtilMisc.toList("ITEM_REJECTED", "ITEM_CANCELLED")),
-                                EntityCondition.makeCondition("orderDate", EntityOperator.GREATER_THAN_EQUAL_TO, timePeriodStart)
-                               ), EntityOperator.AND);
-                    GenericValue count = EntityQuery.use(delegator).select("quantityOrdered").from("OrderItemQuantityReportGroupByProduct").where(prodConditions).queryFirst();
-                    if (count != null) {
-                        sold = count.getBigDecimal("quantityOrdered");
-                        if (sold != null) productsSold.put(productId, sold);
-                    }
-                }
-                if (sold != null) {
-                    union.put("qtySold", sold);
-                }
-
-                // keep a running total of distinct products and quantity to order
-                if (requirement.getBigDecimal("quantity") == null) requirement.put("quantity", BigDecimal.ONE); // default quantity = 1
-                quantity = quantity.add(requiredQuantity);
-                products.add(productId);
-
-                // add all the requirement fields last, to overwrite any conflicting fields
-                union.putAll(requirement.getAllFields());
-                requirements.add(union);
-            }
-
-            Map<String, Object> results = ServiceUtil.returnSuccess();
-            results.put("requirementsForSupplier", requirements);
-            results.put("distinctProductCount", Integer.valueOf(products.size()));
-            results.put("quantityTotal", quantity);
-            results.put("amountTotal", amountTotal);
-            return results;
-        } catch (GenericServiceException e) {
-            Debug.logError(e, module);
-            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderServiceExceptionSeeLogs", locale));
-        } catch (GenericEntityException e) {
-            Debug.logError(e, module);
-            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderEntityExceptionSeeLogs", locale));
-        }
-    }
-
-    // note that this service is designed to work only when a sales order status changes from CREATED -> APPROVED because HOLD -> APPROVED is too complex
-    public static Map<String, Object> createAutoRequirementsForOrder(DispatchContext ctx, Map<String, ? extends Object> context) {
-        Delegator delegator = ctx.getDelegator();
-        LocalDispatcher dispatcher = ctx.getDispatcher();
-        GenericValue userLogin = (GenericValue) context.get("userLogin");
-
-        String orderId = (String) context.get("orderId");
-        try {
-            GenericValue order = EntityQuery.use(delegator).from("OrderHeader").where("orderId", orderId).queryOne();
-            GenericValue productStore = order.getRelatedOne("ProductStore", true);
-            if (productStore == null) {
-                Debug.logInfo("ProductStore for order ID " + orderId + " not found, requirements not created", module);
-                return ServiceUtil.returnSuccess();
-            }
-            String facilityId = productStore.getString("inventoryFacilityId");
-            List<GenericValue> orderItems = order.getRelated("OrderItem", null, null, false);
-            for (GenericValue item : orderItems) {
-                GenericValue product = item.getRelatedOne("Product", false);
-                if (product == null) continue;
-                if ((!"PRODRQM_AUTO".equals(product.get("requirementMethodEnumId")) &&
-                        !"PRODRQM_AUTO".equals(productStore.get("requirementMethodEnumId"))) ||
-                        (product.get("requirementMethodEnumId") == null &&
-                           !"PRODRQM_AUTO".equals(productStore.get("requirementMethodEnumId")))) continue;
-                BigDecimal quantity = item.getBigDecimal("quantity");
-                BigDecimal cancelQuantity = item.getBigDecimal("cancelQuantity");
-                BigDecimal required = quantity.subtract(cancelQuantity == null ? BigDecimal.ZERO : cancelQuantity);
-                if (required.compareTo(BigDecimal.ZERO) <= 0) continue;
-
-                Map<String, Object> input = UtilMisc.toMap("userLogin", userLogin, "facilityId", facilityId, "productId", product.get("productId"), "quantity", required, "requirementTypeId", "PRODUCT_REQUIREMENT");
-                Map<String, Object> results = dispatcher.runSync("createRequirement", input);
-                if (ServiceUtil.isError(results)) return results;
-                String requirementId = (String) results.get("requirementId");
-
-                input = UtilMisc.toMap("userLogin", userLogin, "orderId", order.get("orderId"), "orderItemSeqId", item.get("orderItemSeqId"), "requirementId", requirementId, "quantity", required);
-                results = dispatcher.runSync("createOrderRequirementCommitment", input);
-                if (ServiceUtil.isError(results)) return results;
-            }
-        } catch (GenericEntityException e) {
-            Debug.logError(e, module);
-        } catch (GenericServiceException e) {
-            Debug.logError(e, module);
-        }
-        return ServiceUtil.returnSuccess();
-    }
-
-    // note that this service is designed to work only when a sales order status changes from CREATED -> APPROVED because HOLD -> APPROVED is too complex
-    public static Map<String, Object> createATPRequirementsForOrder(DispatchContext ctx, Map<String, ? extends Object> context) {
-        Delegator delegator = ctx.getDelegator();
-        LocalDispatcher dispatcher = ctx.getDispatcher();
-        GenericValue userLogin = (GenericValue) context.get("userLogin");
-
-        /*
-         * The strategy in this service is to begin making requirements when the product falls below the
-         * ProductFacility.minimumStock.  Because the minimumStock is an upper bound, the quantity to be required
-         * is either that required to bring the ATP back up to the minimumStock level or the amount ordered,
-         * whichever is less.
-         *
-         * If there is a way to support reorderQuantity without losing the order item -> requirement association data,
-         * then this service should be updated.
-         *
-         * The result is that this service generates many small requirements when stock levels are low for a product,
-         * which is perfectly fine since the system is capable of creating POs in bulk from aggregate requirements.
-         * The only concern would be a UI to manage numerous requirements with ease, preferrably by aggregating
-         * on productId.
-         */
-        String orderId = (String) context.get("orderId");
-        try {
-            GenericValue order = EntityQuery.use(delegator).from("OrderHeader").where("orderId", orderId).queryOne();
-            GenericValue productStore = order.getRelatedOne("ProductStore", true);
-            if (productStore == null) {
-                Debug.logInfo("ProductStore for order ID " + orderId + " not found, ATP requirements not created", module);
-                return ServiceUtil.returnSuccess();
-            }
-            String facilityId = productStore.getString("inventoryFacilityId");
-            List<GenericValue> orderItems = order.getRelated("OrderItem", null, null, false);
-            for (GenericValue item : orderItems) {
-                GenericValue product = item.getRelatedOne("Product", false);
-                if (product == null) continue;
-
-                if (!("PRODRQM_ATP".equals(product.get("requirementMethodEnumId")) ||
-                        ("PRODRQM_ATP".equals(productStore.get("requirementMethodEnumId")) && product.get("requirementMethodEnumId") == null))) continue;
-
-                BigDecimal quantity = item.getBigDecimal("quantity");
-                BigDecimal cancelQuantity = item.getBigDecimal("cancelQuantity");
-                BigDecimal ordered = quantity.subtract(cancelQuantity == null ? BigDecimal.ZERO : cancelQuantity);
-                if (ordered.compareTo(BigDecimal.ZERO) <= 0) continue;
-
-                // get the minimum stock for this facility (if not configured assume a minimum of zero, ie create requirements when it goes into backorder)
-                GenericValue productFacility = EntityQuery.use(delegator).from("ProductFacility").where("facilityId", facilityId, "productId", product.get("productId")).queryOne();
-                BigDecimal minimumStock = BigDecimal.ZERO;
-                if (productFacility != null && productFacility.get("minimumStock") != null) {
-                    minimumStock = productFacility.getBigDecimal("minimumStock");
-                }
-
-                // get the facility ATP for product, which should be updated for this item's reservation
-                Map<String, Object> results = dispatcher.runSync("getInventoryAvailableByFacility", UtilMisc.toMap("userLogin", userLogin, "productId", product.get("productId"), "facilityId", facilityId));
-                if (ServiceUtil.isError(results)) return results;
-                BigDecimal atp = ((BigDecimal) results.get("availableToPromiseTotal")); // safe since this is a required OUT param
-
-                // count all current requirements for this product
-                BigDecimal pendingRequirements = BigDecimal.ZERO;
-                EntityConditionList<EntityExpr> ecl = EntityCondition.makeCondition(UtilMisc.toList(
-                        EntityCondition.makeCondition("facilityId", EntityOperator.EQUALS, facilityId),
-                        EntityCondition.makeCondition("productId", EntityOperator.EQUALS, product.get("productId")),
-                        EntityCondition.makeCondition("requirementTypeId", EntityOperator.EQUALS, "PRODUCT_REQUIREMENT"),
-                        EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "REQ_ORDERED"),
-                        EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "REQ_REJECTED")),
-                        EntityOperator.AND);
-                List<GenericValue> requirements = EntityQuery.use(delegator).from("Requirement").where(ecl).queryList();
-                for (GenericValue requirement : requirements) {
-                    pendingRequirements = pendingRequirements.add(requirement.get("quantity") == null ? BigDecimal.ZERO : requirement.getBigDecimal("quantity"));
-                }
-
-                // the minimum stock is an upper bound, therefore we either require up to the minimum stock or the input required quantity, whichever is less
-                BigDecimal shortfall = minimumStock.subtract(atp).subtract(pendingRequirements);
-                BigDecimal required = ordered.compareTo(shortfall) < 0 ? ordered : shortfall;
-                if (required.compareTo(BigDecimal.ZERO) <= 0) continue;
-
-                Map<String, Object> input = UtilMisc.toMap("userLogin", userLogin, "facilityId", facilityId, "productId", product.get("productId"), "quantity", required, "requirementTypeId", "PRODUCT_REQUIREMENT");
-                results = dispatcher.runSync("createRequirement", input);
-                if (ServiceUtil.isError(results)) return results;
-                String requirementId = (String) results.get("requirementId");
-
-                input = UtilMisc.toMap("userLogin", userLogin, "orderId", order.get("orderId"), "orderItemSeqId", item.get("orderItemSeqId"), "requirementId", requirementId, "quantity", required);
-                results = dispatcher.runSync("createOrderRequirementCommitment", input);
-                if (ServiceUtil.isError(results)) return results;
-            }
-        } catch (GenericEntityException e) {
-            Debug.logError(e, module);
-        } catch (GenericServiceException e) {
-            Debug.logError(e, module);
-        }
-        return ServiceUtil.returnSuccess();
-    }
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ofbiz.order.requirement;
+
+import java.util.*;
+import java.math.BigDecimal;
+import java.sql.Timestamp;
+
+import org.ofbiz.base.util.*;
+import org.ofbiz.entity.condition.*;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.util.EntityQuery;
+import org.ofbiz.entity.util.EntityUtil;
+import org.ofbiz.service.DispatchContext;
+import org.ofbiz.service.GenericServiceException;
+import org.ofbiz.service.LocalDispatcher;
+import org.ofbiz.service.ServiceUtil;
+
+/**
+ * Requirement Services
+ */
+
+public class RequirementServices {
+
+    public static final String module = RequirementServices.class.getName();
+    public static final String resource_error = "OrderErrorUiLabels";
+
+    public static Map<String, Object> getRequirementsForSupplier(DispatchContext ctx, Map<String, ? extends Object> context) {
+        Delegator delegator = ctx.getDelegator();
+        LocalDispatcher dispatcher = ctx.getDispatcher();
+        Locale locale = (Locale) context.get("locale");
+
+        EntityCondition requirementConditions = (EntityCondition) context.get("requirementConditions");
+        String partyId = (String) context.get("partyId");
+        String unassignedRequirements = (String) context.get("unassignedRequirements");
+        List<String> statusIds = UtilGenerics.checkList(context.get("statusIds"));
+        //TODO currencyUomId still not used
+        //String currencyUomId = (String) context.get("currencyUomId");
+        try {
+            List<EntityCondition> conditions = UtilMisc.toList(
+                    EntityCondition.makeCondition("requirementTypeId", EntityOperator.EQUALS, "PRODUCT_REQUIREMENT"),
+                    EntityUtil.getFilterByDateExpr()
+                   );
+            if (UtilValidate.isNotEmpty(statusIds)) {
+                conditions.add(EntityCondition.makeCondition("statusId", EntityOperator.IN, statusIds));
+            } else {
+                conditions.add(EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "REQ_APPROVED"));
+            }
+            if (requirementConditions != null) conditions.add(requirementConditions);
+
+            // we're either getting the requirements for a given supplier, unassigned requirements, or requirements for all suppliers
+            if (UtilValidate.isNotEmpty(partyId)) {
+                conditions.add(EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, partyId));
+                conditions.add(EntityCondition.makeCondition("roleTypeId", EntityOperator.EQUALS, "SUPPLIER"));
+            } else if (UtilValidate.isNotEmpty(unassignedRequirements)) {
+                conditions.add(EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, null));
+            } else {
+                conditions.add(EntityCondition.makeCondition("roleTypeId", EntityOperator.EQUALS, "SUPPLIER"));
+            }
+
+            List<GenericValue> requirementAndRoles = EntityQuery.use(delegator).from("RequirementAndRole")
+                    .where(conditions)
+                    .orderBy("partyId", "requirementId")
+                    .queryList();
+
+            // maps to cache the associated suppliers and products data, so we don't do redundant DB and service requests
+            Map<String, GenericValue> suppliers = new HashMap<String, GenericValue>();
+            Map<String, GenericValue> gids = new HashMap<String, GenericValue>();
+            Map<String, Map<String, Object>> inventories = new HashMap<String, Map<String,Object>>();
+            Map<String, BigDecimal> productsSold = new HashMap<String, BigDecimal>();
+
+            // to count quantity, running total, and distinct products in list
+            BigDecimal quantity = BigDecimal.ZERO;
+            BigDecimal amountTotal = BigDecimal.ZERO;
+            Set<String> products = new HashSet<String>();
+
+            // time period to count products ordered from, six months ago and the 1st of that month
+            Timestamp timePeriodStart = UtilDateTime.getMonthStart(UtilDateTime.nowTimestamp(), 0, -6);
+
+            // join in fields with extra data about the suppliers and products
+            List<Map<String, Object>> requirements = new LinkedList<Map<String,Object>>();
+            for (GenericValue requirement : requirementAndRoles) {
+                Map<String, Object> union = new HashMap<String, Object>();
+                String productId = requirement.getString("productId");
+                partyId = requirement.getString("partyId");
+                String facilityId = requirement.getString("facilityId");
+                BigDecimal requiredQuantity = requirement.getBigDecimal("quantity");
+
+                // get an available supplier product, preferably the one with the smallest minimum quantity to order, followed by price
+                String supplierKey =  partyId + "^" + productId;
+                GenericValue supplierProduct = suppliers.get(supplierKey);
+                if (supplierProduct == null) {
+                    // TODO: it is possible to restrict to quantity > minimumOrderQuantity, but then the entire requirement must be skipped
+                    supplierProduct = EntityQuery.use(delegator).from("SupplierProduct")
+                            .where("partyId", partyId, "productId", productId)
+                            .orderBy("minimumOrderQuantity", "lastPrice")
+                            .filterByDate("availableFromDate", "availableThruDate")
+                            .queryFirst();
+                    suppliers.put(supplierKey, supplierProduct);
+                }
+
+                // add our supplier product and cost of this line to the data
+                if (supplierProduct != null) {
+                    union.putAll(supplierProduct.getAllFields());
+                    BigDecimal lastPrice = supplierProduct.getBigDecimal("lastPrice");
+                    amountTotal = amountTotal.add(lastPrice.multiply(requiredQuantity));
+                }
+
+                // for good identification, get the UPCA type (UPC code)
+                GenericValue gid = gids.get(productId);
+                if (gid == null) {
+                    gid = EntityQuery.use(delegator).from("GoodIdentification").where("goodIdentificationTypeId", "UPCA", "productId", requirement.get("productId")).queryOne();
+                    gids.put(productId, gid);
+                }
+                if (gid != null) union.put("idValue", gid.get("idValue"));
+
+                // the ATP and QOH quantities
+                if (UtilValidate.isNotEmpty(facilityId)) {
+                    String inventoryKey = facilityId + "^" + productId;
+                    Map<String, Object> inventory = inventories.get(inventoryKey);
+                    if (inventory == null) {
+                        inventory = dispatcher.runSync("getInventoryAvailableByFacility", UtilMisc.toMap("productId", productId, "facilityId", facilityId));
+                        if (ServiceUtil.isError(inventory)) {
+                            return inventory;
+                        }
+                        inventories.put(inventoryKey, inventory);
+                    }
+                    if (inventory != null) {
+                        union.put("qoh", inventory.get("quantityOnHandTotal"));
+                        union.put("atp", inventory.get("availableToPromiseTotal"));
+                    }
+                }
+
+                // how many of the products were sold (note this is for a fixed time period across all product stores)
+                BigDecimal sold = productsSold.get(productId);
+                if (sold == null) {
+                    EntityCondition prodConditions = EntityCondition.makeCondition(UtilMisc.toList(
+                                EntityCondition.makeCondition("productId", EntityOperator.EQUALS, productId),
+                                EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "SALES_ORDER"),
+                                EntityCondition.makeCondition("orderStatusId", EntityOperator.NOT_IN, UtilMisc.toList("ORDER_REJECTED", "ORDER_CANCELLED")),
+                                EntityCondition.makeCondition("orderItemStatusId", EntityOperator.NOT_IN, UtilMisc.toList("ITEM_REJECTED", "ITEM_CANCELLED")),
+                                EntityCondition.makeCondition("orderDate", EntityOperator.GREATER_THAN_EQUAL_TO, timePeriodStart)
+                               ), EntityOperator.AND);
+                    GenericValue count = EntityQuery.use(delegator).select("quantityOrdered").from("OrderItemQuantityReportGroupByProduct").where(prodConditions).queryFirst();
+                    if (count != null) {
+                        sold = count.getBigDecimal("quantityOrdered");
+                        if (sold != null) productsSold.put(productId, sold);
+                    }
+                }
+                if (sold != null) {
+                    union.put("qtySold", sold);
+                }
+
+                // keep a running total of distinct products and quantity to order
+                if (requirement.getBigDecimal("quantity") == null) requirement.put("quantity", BigDecimal.ONE); // default quantity = 1
+                quantity = quantity.add(requiredQuantity);
+                products.add(productId);
+
+                // add all the requirement fields last, to overwrite any conflicting fields
+                union.putAll(requirement.getAllFields());
+                requirements.add(union);
+            }
+
+            Map<String, Object> results = ServiceUtil.returnSuccess();
+            results.put("requirementsForSupplier", requirements);
+            results.put("distinctProductCount", Integer.valueOf(products.size()));
+            results.put("quantityTotal", quantity);
+            results.put("amountTotal", amountTotal);
+            return results;
+        } catch (GenericServiceException e) {
+            Debug.logError(e, module);
+            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderServiceExceptionSeeLogs", locale));
+        } catch (GenericEntityException e) {
+            Debug.logError(e, module);
+            return ServiceUtil.returnError(UtilProperties.getMessage(resource_error, "OrderEntityExceptionSeeLogs", locale));
+        }
+    }
+
+    // note that this service is designed to work only when a sales order status changes from CREATED -> APPROVED because HOLD -> APPROVED is too complex
+    public static Map<String, Object> createAutoRequirementsForOrder(DispatchContext ctx, Map<String, ? extends Object> context) {
+        Delegator delegator = ctx.getDelegator();
+        LocalDispatcher dispatcher = ctx.getDispatcher();
+        GenericValue userLogin = (GenericValue) context.get("userLogin");
+
+        String orderId = (String) context.get("orderId");
+        try {
+            GenericValue order = EntityQuery.use(delegator).from("OrderHeader").where("orderId", orderId).queryOne();
+            GenericValue productStore = order.getRelatedOne("ProductStore", true);
+            if (productStore == null) {
+                Debug.logInfo("ProductStore for order ID " + orderId + " not found, requirements not created", module);
+                return ServiceUtil.returnSuccess();
+            }
+            String facilityId = productStore.getString("inventoryFacilityId");
+            List<GenericValue> orderItems = order.getRelated("OrderItem", null, null, false);
+            for (GenericValue item : orderItems) {
+                GenericValue product = item.getRelatedOne("Product", false);
+                if (product == null) continue;
+                if ((!"PRODRQM_AUTO".equals(product.get("requirementMethodEnumId")) &&
+                        !"PRODRQM_AUTO".equals(productStore.get("requirementMethodEnumId"))) ||
+                        (product.get("requirementMethodEnumId") == null &&
+                           !"PRODRQM_AUTO".equals(productStore.get("requirementMethodEnumId")))) continue;
+                BigDecimal quantity = item.getBigDecimal("quantity");
+                BigDecimal cancelQuantity = item.getBigDecimal("cancelQuantity");
+                BigDecimal required = quantity.subtract(cancelQuantity == null ? BigDecimal.ZERO : cancelQuantity);
+                if (required.compareTo(BigDecimal.ZERO) <= 0) continue;
+
+                Map<String, Object> input = UtilMisc.toMap("userLogin", userLogin, "facilityId", facilityId, "productId", product.get("productId"), "quantity", required, "requirementTypeId", "PRODUCT_REQUIREMENT");
+                Map<String, Object> results = dispatcher.runSync("createRequirement", input);
+                if (ServiceUtil.isError(results)) return results;
+                String requirementId = (String) results.get("requirementId");
+
+                input = UtilMisc.toMap("userLogin", userLogin, "orderId", order.get("orderId"), "orderItemSeqId", item.get("orderItemSeqId"), "requirementId", requirementId, "quantity", required);
+                results = dispatcher.runSync("createOrderRequirementCommitment", input);
+                if (ServiceUtil.isError(results)) return results;
+            }
+        } catch (GenericEntityException e) {
+            Debug.logError(e, module);
+        } catch (GenericServiceException e) {
+            Debug.logError(e, module);
+        }
+        return ServiceUtil.returnSuccess();
+    }
+
+    // note that this service is designed to work only when a sales order status changes from CREATED -> APPROVED because HOLD -> APPROVED is too complex
+    public static Map<String, Object> createATPRequirementsForOrder(DispatchContext ctx, Map<String, ? extends Object> context) {
+        Delegator delegator = ctx.getDelegator();
+        LocalDispatcher dispatcher = ctx.getDispatcher();
+        GenericValue userLogin = (GenericValue) context.get("userLogin");
+
+        /*
+         * The strategy in this service is to begin making requirements when the product falls below the
+         * ProductFacility.minimumStock.  Because the minimumStock is an upper bound, the quantity to be required
+         * is either that required to bring the ATP back up to the minimumStock level or the amount ordered,
+         * whichever is less.
+         *
+         * If there is a way to support reorderQuantity without losing the order item -> requirement association data,
+         * then this service should be updated.
+         *
+         * The result is that this service generates many small requirements when stock levels are low for a product,
+         * which is perfectly fine since the system is capable of creating POs in bulk from aggregate requirements.
+         * The only concern would be a UI to manage numerous requirements with ease, preferrably by aggregating
+         * on productId.
+         */
+        String orderId = (String) context.get("orderId");
+        try {
+            GenericValue order = EntityQuery.use(delegator).from("OrderHeader").where("orderId", orderId).queryOne();
+            GenericValue productStore = order.getRelatedOne("ProductStore", true);
+            if (productStore == null) {
+                Debug.logInfo("ProductStore for order ID " + orderId + " not found, ATP requirements not created", module);
+                return ServiceUtil.returnSuccess();
+            }
+            String facilityId = productStore.getString("inventoryFacilityId");
+            List<GenericValue> orderItems = order.getRelated("OrderItem", null, null, false);
+            for (GenericValue item : orderItems) {
+                GenericValue product = item.getRelatedOne("Product", false);
+                if (product == null) continue;
+
+                if (!("PRODRQM_ATP".equals(product.get("requirementMethodEnumId")) ||
+                        ("PRODRQM_ATP".equals(productStore.get("requirementMethodEnumId")) && product.get("requirementMethodEnumId") == null))) continue;
+
+                BigDecimal quantity = item.getBigDecimal("quantity");
+                BigDecimal cancelQuantity = item.getBigDecimal("cancelQuantity");
+                BigDecimal ordered = quantity.subtract(cancelQuantity == null ? BigDecimal.ZERO : cancelQuantity);
+                if (ordered.compareTo(BigDecimal.ZERO) <= 0) continue;
+
+                // get the minimum stock for this facility (if not configured assume a minimum of zero, ie create requirements when it goes into backorder)
+                GenericValue productFacility = EntityQuery.use(delegator).from("ProductFacility").where("facilityId", facilityId, "productId", product.get("productId")).queryOne();
+                BigDecimal minimumStock = BigDecimal.ZERO;
+                if (productFacility != null && productFacility.get("minimumStock") != null) {
+                    minimumStock = productFacility.getBigDecimal("minimumStock");
+                }
+
+                // get the facility ATP for product, which should be updated for this item's reservation
+                Map<String, Object> results = dispatcher.runSync("getInventoryAvailableByFacility", UtilMisc.toMap("userLogin", userLogin, "productId", product.get("productId"), "facilityId", facilityId));
+                if (ServiceUtil.isError(results)) return results;
+                BigDecimal atp = ((BigDecimal) results.get("availableToPromiseTotal")); // safe since this is a required OUT param
+
+                // count all current requirements for this product
+                BigDecimal pendingRequirements = BigDecimal.ZERO;
+                EntityConditionList<EntityExpr> ecl = EntityCondition.makeCondition(UtilMisc.toList(
+                        EntityCondition.makeCondition("facilityId", EntityOperator.EQUALS, facilityId),
+                        EntityCondition.makeCondition("productId", EntityOperator.EQUALS, product.get("productId")),
+                        EntityCondition.makeCondition("requirementTypeId", EntityOperator.EQUALS, "PRODUCT_REQUIREMENT"),
+                        EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "REQ_ORDERED"),
+                        EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "REQ_REJECTED")),
+                        EntityOperator.AND);
+                List<GenericValue> requirements = EntityQuery.use(delegator).from("Requirement").where(ecl).queryList();
+                for (GenericValue requirement : requirements) {
+                    pendingRequirements = pendingRequirements.add(requirement.get("quantity") == null ? BigDecimal.ZERO : requirement.getBigDecimal("quantity"));
+                }
+
+                // the minimum stock is an upper bound, therefore we either require up to the minimum stock or the input required quantity, whichever is less
+                BigDecimal shortfall = minimumStock.subtract(atp).subtract(pendingRequirements);
+                BigDecimal required = ordered.compareTo(shortfall) < 0 ? ordered : shortfall;
+                if (required.compareTo(BigDecimal.ZERO) <= 0) continue;
+
+                Map<String, Object> input = UtilMisc.toMap("userLogin", userLogin, "facilityId", facilityId, "productId", product.get("productId"), "quantity", required, "requirementTypeId", "PRODUCT_REQUIREMENT");
+                results = dispatcher.runSync("createRequirement", input);
+                if (ServiceUtil.isError(results)) return results;
+                String requirementId = (String) results.get("requirementId");
+
+                input = UtilMisc.toMap("userLogin", userLogin, "orderId", order.get("orderId"), "orderItemSeqId", item.get("orderItemSeqId"), "requirementId", requirementId, "quantity", required);
+                results = dispatcher.runSync("createOrderRequirementCommitment", input);
+                if (ServiceUtil.isError(results)) return results;
+            }
+        } catch (GenericEntityException e) {
+            Debug.logError(e, module);
+        } catch (GenericServiceException e) {
+            Debug.logError(e, module);
+        }
+        return ServiceUtil.returnSuccess();
+    }
+}
+

Propchange: ofbiz/trunk/applications/order/src/org/ofbiz/order/requirement/RequirementServices.java
            ('svn:eol-style' removed)

Modified: ofbiz/trunk/applications/product/src/org/ofbiz/product/inventory/InventoryWorker.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/src/org/ofbiz/product/inventory/InventoryWorker.java?rev=1695126&r1=1695125&r2=1695126&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/src/org/ofbiz/product/inventory/InventoryWorker.java (original)
+++ ofbiz/trunk/applications/product/src/org/ofbiz/product/inventory/InventoryWorker.java Mon Aug 10 16:15:37 2015
@@ -1,147 +1,147 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.ofbiz.product.inventory;
-
-import java.math.BigDecimal;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.UtilMisc;
-import org.ofbiz.base.util.UtilValidate;
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.GenericEntityException;
-import org.ofbiz.entity.GenericValue;
-import org.ofbiz.entity.condition.EntityCondition;
-import org.ofbiz.entity.condition.EntityConditionList;
-import org.ofbiz.entity.condition.EntityOperator;
-import org.ofbiz.entity.util.EntityQuery;
-
-public class InventoryWorker {
-
-    public final static String module = InventoryWorker.class.getName();
-
-    /**
-     * Finds all outstanding Purchase orders for a productId.  The orders and the items cannot be completed, cancelled, or rejected
-     * @param productId the product id
-     * @param delegator the delegator
-     * @return returns all outstanding Purchase orders for a productId
-     */
-    public static List<GenericValue> getOutstandingPurchaseOrders(String productId, Delegator delegator) {
-        try {
-            List<EntityCondition> purchaseOrderConditions = UtilMisc.<EntityCondition>toList(EntityCondition.makeCondition("orderStatusId", EntityOperator.NOT_EQUAL, "ORDER_COMPLETED"),
-                    EntityCondition.makeCondition("orderStatusId", EntityOperator.NOT_EQUAL, "ORDER_CANCELLED"),
-                    EntityCondition.makeCondition("orderStatusId", EntityOperator.NOT_EQUAL, "ORDER_REJECTED"),
-                    EntityCondition.makeCondition("itemStatusId", EntityOperator.NOT_EQUAL, "ITEM_COMPLETED"),
-                    EntityCondition.makeCondition("itemStatusId", EntityOperator.NOT_EQUAL, "ITEM_CANCELLED"),
-                    EntityCondition.makeCondition("itemStatusId", EntityOperator.NOT_EQUAL, "ITEM_REJECTED"));
-            purchaseOrderConditions.add(EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "PURCHASE_ORDER"));
-            purchaseOrderConditions.add(EntityCondition.makeCondition("productId", EntityOperator.EQUALS, productId));
-            List<GenericValue> purchaseOrders = EntityQuery.use(delegator).from("OrderHeaderAndItems")
-                    .where(EntityCondition.makeCondition(purchaseOrderConditions, EntityOperator.AND))
-                    .orderBy("estimatedDeliveryDate DESC", "orderDate")
-                    .queryList();
-            return purchaseOrders;
-        } catch (GenericEntityException ex) {
-            Debug.logError("Unable to find outstanding purchase orders for product [" + productId + "] due to " + ex.getMessage() + " - returning null", module);
-            return null;
-        }
-    }
-
-    /**
-     * Finds the net outstanding ordered quantity for a productId, netting quantity on outstanding purchase orders against cancelQuantity
-     * @param productId the product id
-     * @param delegator the delegator
-     * @return returns the net outstanding ordered quantity for a productId
-     */
-    public static BigDecimal getOutstandingPurchasedQuantity(String productId, Delegator delegator) {
-        BigDecimal qty = BigDecimal.ZERO;
-        List<GenericValue> purchaseOrders = getOutstandingPurchaseOrders(productId, delegator);
-        if (UtilValidate.isEmpty(purchaseOrders)) {
-            return qty;
-        } else {
-            for (GenericValue nextOrder: purchaseOrders) {
-                if (nextOrder.get("quantity") != null) {
-                    BigDecimal itemQuantity = nextOrder.getBigDecimal("quantity");
-                    BigDecimal cancelQuantity = BigDecimal.ZERO;
-                    if (nextOrder.get("cancelQuantity") != null) {
-                        cancelQuantity = nextOrder.getBigDecimal("cancelQuantity");
-                    }
-                    itemQuantity = itemQuantity.subtract(cancelQuantity);
-                    if (itemQuantity.compareTo(BigDecimal.ZERO) >= 0) {
-                        qty = qty.add(itemQuantity);
-                    }
-                }
-            }
-        }
-
-        return qty;
-    }
-
-    /**
-     * Gets the quanitty of each product in the order that is outstanding across all orders of the given input type.
-     * Uses the OrderItemQuantityReportGroupByProduct view entity.
-     *
-     * @param   productIds  Collection of disticnt productIds in an order. Use OrderReadHelper.getOrderProductIds()
-     * @param   orderTypeId Either "SALES_ORDER" or "PURCHASE_ORDER"
-     * @param   delegator   The delegator to use
-     * @return  Map of productIds to quantities outstanding.
-     */
-    public static Map<String, BigDecimal> getOutstandingProductQuantities(Collection<String> productIds, String orderTypeId, Delegator delegator) {
-        Set<String> fieldsToSelect = UtilMisc.toSet("productId", "quantityOpen");
-        List<EntityCondition> condList = UtilMisc.<EntityCondition>toList(
-                EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, orderTypeId),
-                EntityCondition.makeCondition("orderStatusId", EntityOperator.NOT_EQUAL, "ORDER_COMPLETED"),
-                EntityCondition.makeCondition("orderStatusId", EntityOperator.NOT_EQUAL, "ORDER_REJECTED"),
-                EntityCondition.makeCondition("orderStatusId", EntityOperator.NOT_EQUAL, "ORDER_CANCELLED")
-               );
-        if (productIds.size() > 0) {
-            condList.add(EntityCondition.makeCondition("productId", EntityOperator.IN, productIds));
-        }
-        condList.add(EntityCondition.makeCondition("orderItemStatusId", EntityOperator.NOT_EQUAL, "ITEM_COMPLETED"));
-        condList.add(EntityCondition.makeCondition("orderItemStatusId", EntityOperator.NOT_EQUAL, "ITEM_REJECTED"));
-        condList.add(EntityCondition.makeCondition("orderItemStatusId", EntityOperator.NOT_EQUAL, "ITEM_CANCELLED"));
-        EntityConditionList<EntityCondition> conditions = EntityCondition.makeCondition(condList, EntityOperator.AND);
-
-        Map<String, BigDecimal> results = new HashMap<String, BigDecimal>();
-        try {
-            List<GenericValue> orderedProducts = EntityQuery.use(delegator).select(fieldsToSelect).from("OrderItemQuantityReportGroupByProduct").where(conditions).queryList();
-            for (GenericValue value: orderedProducts) {
-                results.put(value.getString("productId"), value.getBigDecimal("quantityOpen"));
-            }
-        } catch (GenericEntityException e) {
-            Debug.logError(e, module);
-        }
-        return results;
-    }
-
-    /** As above, but for sales orders */
-    public static Map<String, BigDecimal> getOutstandingProductQuantitiesForSalesOrders(Collection<String> productIds, Delegator delegator) {
-        return getOutstandingProductQuantities(productIds, "SALES_ORDER", delegator);
-    }
-
-    /** As above, but for purchase orders */
-    public static Map<String, BigDecimal> getOutstandingProductQuantitiesForPurchaseOrders(Collection<String> productIds, Delegator delegator) {
-        return getOutstandingProductQuantities(productIds, "PURCHASE_ORDER", delegator);
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.ofbiz.product.inventory;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.entity.Delegator;
+import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.condition.EntityCondition;
+import org.ofbiz.entity.condition.EntityConditionList;
+import org.ofbiz.entity.condition.EntityOperator;
+import org.ofbiz.entity.util.EntityQuery;
+
+public class InventoryWorker {
+
+    public final static String module = InventoryWorker.class.getName();
+
+    /**
+     * Finds all outstanding Purchase orders for a productId.  The orders and the items cannot be completed, cancelled, or rejected
+     * @param productId the product id
+     * @param delegator the delegator
+     * @return returns all outstanding Purchase orders for a productId
+     */
+    public static List<GenericValue> getOutstandingPurchaseOrders(String productId, Delegator delegator) {
+        try {
+            List<EntityCondition> purchaseOrderConditions = UtilMisc.<EntityCondition>toList(EntityCondition.makeCondition("orderStatusId", EntityOperator.NOT_EQUAL, "ORDER_COMPLETED"),
+                    EntityCondition.makeCondition("orderStatusId", EntityOperator.NOT_EQUAL, "ORDER_CANCELLED"),
+                    EntityCondition.makeCondition("orderStatusId", EntityOperator.NOT_EQUAL, "ORDER_REJECTED"),
+                    EntityCondition.makeCondition("itemStatusId", EntityOperator.NOT_EQUAL, "ITEM_COMPLETED"),
+                    EntityCondition.makeCondition("itemStatusId", EntityOperator.NOT_EQUAL, "ITEM_CANCELLED"),
+                    EntityCondition.makeCondition("itemStatusId", EntityOperator.NOT_EQUAL, "ITEM_REJECTED"));
+            purchaseOrderConditions.add(EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "PURCHASE_ORDER"));
+            purchaseOrderConditions.add(EntityCondition.makeCondition("productId", EntityOperator.EQUALS, productId));
+            List<GenericValue> purchaseOrders = EntityQuery.use(delegator).from("OrderHeaderAndItems")
+                    .where(EntityCondition.makeCondition(purchaseOrderConditions, EntityOperator.AND))
+                    .orderBy("estimatedDeliveryDate DESC", "orderDate")
+                    .queryList();
+            return purchaseOrders;
+        } catch (GenericEntityException ex) {
+            Debug.logError("Unable to find outstanding purchase orders for product [" + productId + "] due to " + ex.getMessage() + " - returning null", module);
+            return null;
+        }
+    }
+
+    /**
+     * Finds the net outstanding ordered quantity for a productId, netting quantity on outstanding purchase orders against cancelQuantity
+     * @param productId the product id
+     * @param delegator the delegator
+     * @return returns the net outstanding ordered quantity for a productId
+     */
+    public static BigDecimal getOutstandingPurchasedQuantity(String productId, Delegator delegator) {
+        BigDecimal qty = BigDecimal.ZERO;
+        List<GenericValue> purchaseOrders = getOutstandingPurchaseOrders(productId, delegator);
+        if (UtilValidate.isEmpty(purchaseOrders)) {
+            return qty;
+        } else {
+            for (GenericValue nextOrder: purchaseOrders) {
+                if (nextOrder.get("quantity") != null) {
+                    BigDecimal itemQuantity = nextOrder.getBigDecimal("quantity");
+                    BigDecimal cancelQuantity = BigDecimal.ZERO;
+                    if (nextOrder.get("cancelQuantity") != null) {
+                        cancelQuantity = nextOrder.getBigDecimal("cancelQuantity");
+                    }
+                    itemQuantity = itemQuantity.subtract(cancelQuantity);
+                    if (itemQuantity.compareTo(BigDecimal.ZERO) >= 0) {
+                        qty = qty.add(itemQuantity);
+                    }
+                }
+            }
+        }
+
+        return qty;
+    }
+
+    /**
+     * Gets the quanitty of each product in the order that is outstanding across all orders of the given input type.
+     * Uses the OrderItemQuantityReportGroupByProduct view entity.
+     *
+     * @param   productIds  Collection of disticnt productIds in an order. Use OrderReadHelper.getOrderProductIds()
+     * @param   orderTypeId Either "SALES_ORDER" or "PURCHASE_ORDER"
+     * @param   delegator   The delegator to use
+     * @return  Map of productIds to quantities outstanding.
+     */
+    public static Map<String, BigDecimal> getOutstandingProductQuantities(Collection<String> productIds, String orderTypeId, Delegator delegator) {
+        Set<String> fieldsToSelect = UtilMisc.toSet("productId", "quantityOpen");
+        List<EntityCondition> condList = UtilMisc.<EntityCondition>toList(
+                EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, orderTypeId),
+                EntityCondition.makeCondition("orderStatusId", EntityOperator.NOT_EQUAL, "ORDER_COMPLETED"),
+                EntityCondition.makeCondition("orderStatusId", EntityOperator.NOT_EQUAL, "ORDER_REJECTED"),
+                EntityCondition.makeCondition("orderStatusId", EntityOperator.NOT_EQUAL, "ORDER_CANCELLED")
+               );
+        if (productIds.size() > 0) {
+            condList.add(EntityCondition.makeCondition("productId", EntityOperator.IN, productIds));
+        }
+        condList.add(EntityCondition.makeCondition("orderItemStatusId", EntityOperator.NOT_EQUAL, "ITEM_COMPLETED"));
+        condList.add(EntityCondition.makeCondition("orderItemStatusId", EntityOperator.NOT_EQUAL, "ITEM_REJECTED"));
+        condList.add(EntityCondition.makeCondition("orderItemStatusId", EntityOperator.NOT_EQUAL, "ITEM_CANCELLED"));
+        EntityConditionList<EntityCondition> conditions = EntityCondition.makeCondition(condList, EntityOperator.AND);
+
+        Map<String, BigDecimal> results = new HashMap<String, BigDecimal>();
+        try {
+            List<GenericValue> orderedProducts = EntityQuery.use(delegator).select(fieldsToSelect).from("OrderItemQuantityReportGroupByProduct").where(conditions).queryList();
+            for (GenericValue value: orderedProducts) {
+                results.put(value.getString("productId"), value.getBigDecimal("quantityOpen"));
+            }
+        } catch (GenericEntityException e) {
+            Debug.logError(e, module);
+        }
+        return results;
+    }
+
+    /** As above, but for sales orders */
+    public static Map<String, BigDecimal> getOutstandingProductQuantitiesForSalesOrders(Collection<String> productIds, Delegator delegator) {
+        return getOutstandingProductQuantities(productIds, "SALES_ORDER", delegator);
+    }
+
+    /** As above, but for purchase orders */
+    public static Map<String, BigDecimal> getOutstandingProductQuantitiesForPurchaseOrders(Collection<String> productIds, Delegator delegator) {
+        return getOutstandingProductQuantities(productIds, "PURCHASE_ORDER", delegator);
+    }
+}

Propchange: ofbiz/trunk/applications/product/src/org/ofbiz/product/inventory/InventoryWorker.java
            ('svn:eol-style' removed)

Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/concurrent/ExecutionPool.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/concurrent/ExecutionPool.java?rev=1695126&r1=1695125&r2=1695126&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/org/ofbiz/base/concurrent/ExecutionPool.java (original)
+++ ofbiz/trunk/framework/base/src/org/ofbiz/base/concurrent/ExecutionPool.java Mon Aug 10 16:15:37 2015
@@ -1,155 +1,155 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *******************************************************************************/
-package org.ofbiz.base.concurrent;
-
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.DelayQueue;
-import java.util.concurrent.Delayed;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ForkJoinPool;
-import java.util.concurrent.Future;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.SynchronousQueue;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-import org.ofbiz.base.lang.SourceMonitored;
-import org.ofbiz.base.util.Debug;
-
-@SourceMonitored
-public final class ExecutionPool {
-    public static final String module = ExecutionPool.class.getName();
-    public static final ExecutorService GLOBAL_BATCH = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 5, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), new ExecutionPoolThreadFactory(null, "OFBiz-batch"));
-    public static final ForkJoinPool GLOBAL_FORK_JOIN = new ForkJoinPool();
-    private static final ExecutorService pulseExecutionPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), new ExecutionPoolThreadFactory(null, "OFBiz-ExecutionPoolPulseWorker"));
-
-    protected static class ExecutionPoolThreadFactory implements ThreadFactory {
-        private final ThreadGroup group;
-        private final String namePrefix;
-        private volatile int count = 1;
-
-        protected ExecutionPoolThreadFactory(ThreadGroup group, String namePrefix) {
-            this.group = group;
-            this.namePrefix = namePrefix;
-        }
-
-        public Thread newThread(Runnable r) {
-            Thread t = new Thread(group, r);
-            t.setDaemon(true);
-            t.setPriority(Thread.NORM_PRIORITY);
-            t.setName(namePrefix + "-" + count++);
-            return t;
-        }
-    }
-
-    public static ScheduledExecutorService getScheduledExecutor(ThreadGroup group, String namePrefix, int threadCount, long keepAliveSeconds, boolean preStart) {
-        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(threadCount, new ExecutionPoolThreadFactory(group, namePrefix));
-        if (keepAliveSeconds > 0) {
-            executor.setKeepAliveTime(keepAliveSeconds, TimeUnit.SECONDS);
-            executor.allowCoreThreadTimeOut(true);
-        }
-        if (preStart) {
-            executor.prestartAllCoreThreads();
-        }
-        return executor;
-    }
-
-    public static <F> List<F> getAllFutures(Collection<Future<F>> futureList) {
-        List<F> result = new LinkedList<F>();
-        for (Future<F> future: futureList) {
-            try {
-                result.add(future.get());
-            } catch (ExecutionException e) {
-                Debug.logError(e, module);
-            } catch (InterruptedException e) {
-                Debug.logError(e, module);
-            }
-        }
-        return result;
-    }
-
-    public static void addPulse(Pulse pulse) {
-        delayQueue.put(pulse);
-    }
-
-    public static void removePulse(Pulse pulse) {
-        delayQueue.remove(pulse);
-    }
-
-    static {
-        int numberOfExecutionPoolPulseWorkers = Runtime.getRuntime().availableProcessors();
-        for (int i = 0; i < numberOfExecutionPoolPulseWorkers; i++) {
-            pulseExecutionPool.execute(new ExecutionPoolPulseWorker());
-        }
-    }
-
-    private static final DelayQueue<Pulse> delayQueue = new DelayQueue<Pulse>();
-
-    public static class ExecutionPoolPulseWorker implements Runnable {
-        public void run() {
-            try {
-                while (true) {
-                    delayQueue.take().run();
-                }
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    public static abstract class Pulse implements Delayed, Runnable {
-        protected final long expireTimeNanos;
-        protected final long loadTimeNanos;
-
-        protected Pulse(long delayNanos) {
-            this(System.nanoTime(), delayNanos);
-        }
-
-        protected Pulse(long loadTimeNanos, long delayNanos) {
-            this.loadTimeNanos = loadTimeNanos;
-            expireTimeNanos = loadTimeNanos + delayNanos;
-        }
-
-        public long getLoadTimeNanos() {
-            return loadTimeNanos;
-        }
-
-        public long getExpireTimeNanos() {
-            return expireTimeNanos;
-        }
-
-        public final long getDelay(TimeUnit unit) {
-            return unit.convert(expireTimeNanos - System.nanoTime(), TimeUnit.NANOSECONDS);
-        }
-
-        public final int compareTo(Delayed other) {
-            long r = (expireTimeNanos - ((Pulse) other).expireTimeNanos);
-            if (r < 0) return -1;
-            if (r > 0) return 1;
-            return 0;
-        }
-    }
-
-}
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.ofbiz.base.concurrent;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.DelayQueue;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.ofbiz.base.lang.SourceMonitored;
+import org.ofbiz.base.util.Debug;
+
+@SourceMonitored
+public final class ExecutionPool {
+    public static final String module = ExecutionPool.class.getName();
+    public static final ExecutorService GLOBAL_BATCH = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 5, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), new ExecutionPoolThreadFactory(null, "OFBiz-batch"));
+    public static final ForkJoinPool GLOBAL_FORK_JOIN = new ForkJoinPool();
+    private static final ExecutorService pulseExecutionPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), new ExecutionPoolThreadFactory(null, "OFBiz-ExecutionPoolPulseWorker"));
+
+    protected static class ExecutionPoolThreadFactory implements ThreadFactory {
+        private final ThreadGroup group;
+        private final String namePrefix;
+        private volatile int count = 1;
+
+        protected ExecutionPoolThreadFactory(ThreadGroup group, String namePrefix) {
+            this.group = group;
+            this.namePrefix = namePrefix;
+        }
+
+        public Thread newThread(Runnable r) {
+            Thread t = new Thread(group, r);
+            t.setDaemon(true);
+            t.setPriority(Thread.NORM_PRIORITY);
+            t.setName(namePrefix + "-" + count++);
+            return t;
+        }
+    }
+
+    public static ScheduledExecutorService getScheduledExecutor(ThreadGroup group, String namePrefix, int threadCount, long keepAliveSeconds, boolean preStart) {
+        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(threadCount, new ExecutionPoolThreadFactory(group, namePrefix));
+        if (keepAliveSeconds > 0) {
+            executor.setKeepAliveTime(keepAliveSeconds, TimeUnit.SECONDS);
+            executor.allowCoreThreadTimeOut(true);
+        }
+        if (preStart) {
+            executor.prestartAllCoreThreads();
+        }
+        return executor;
+    }
+
+    public static <F> List<F> getAllFutures(Collection<Future<F>> futureList) {
+        List<F> result = new LinkedList<F>();
+        for (Future<F> future: futureList) {
+            try {
+                result.add(future.get());
+            } catch (ExecutionException e) {
+                Debug.logError(e, module);
+            } catch (InterruptedException e) {
+                Debug.logError(e, module);
+            }
+        }
+        return result;
+    }
+
+    public static void addPulse(Pulse pulse) {
+        delayQueue.put(pulse);
+    }
+
+    public static void removePulse(Pulse pulse) {
+        delayQueue.remove(pulse);
+    }
+
+    static {
+        int numberOfExecutionPoolPulseWorkers = Runtime.getRuntime().availableProcessors();
+        for (int i = 0; i < numberOfExecutionPoolPulseWorkers; i++) {
+            pulseExecutionPool.execute(new ExecutionPoolPulseWorker());
+        }
+    }
+
+    private static final DelayQueue<Pulse> delayQueue = new DelayQueue<Pulse>();
+
+    public static class ExecutionPoolPulseWorker implements Runnable {
+        public void run() {
+            try {
+                while (true) {
+                    delayQueue.take().run();
+                }
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public static abstract class Pulse implements Delayed, Runnable {
+        protected final long expireTimeNanos;
+        protected final long loadTimeNanos;
+
+        protected Pulse(long delayNanos) {
+            this(System.nanoTime(), delayNanos);
+        }
+
+        protected Pulse(long loadTimeNanos, long delayNanos) {
+            this.loadTimeNanos = loadTimeNanos;
+            expireTimeNanos = loadTimeNanos + delayNanos;
+        }
+
+        public long getLoadTimeNanos() {
+            return loadTimeNanos;
+        }
+
+        public long getExpireTimeNanos() {
+            return expireTimeNanos;
+        }
+
+        public final long getDelay(TimeUnit unit) {
+            return unit.convert(expireTimeNanos - System.nanoTime(), TimeUnit.NANOSECONDS);
+        }
+
+        public final int compareTo(Delayed other) {
+            long r = (expireTimeNanos - ((Pulse) other).expireTimeNanos);
+            if (r < 0) return -1;
+            if (r > 0) return 1;
+            return 0;
+        }
+    }
+
+}

Propchange: ofbiz/trunk/framework/base/src/org/ofbiz/base/concurrent/ExecutionPool.java
            ('svn:eol-style' removed)

Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/config/CoberturaInstrumenter.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/config/CoberturaInstrumenter.java?rev=1695126&r1=1695125&r2=1695126&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/org/ofbiz/base/config/CoberturaInstrumenter.java (original)
+++ ofbiz/trunk/framework/base/src/org/ofbiz/base/config/CoberturaInstrumenter.java Mon Aug 10 16:15:37 2015
@@ -1,94 +1,94 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *******************************************************************************/
-package org.ofbiz.base.config;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.Collections;
-
-import net.sourceforge.cobertura.coveragedata.CoverageDataFileHandler;
-import net.sourceforge.cobertura.coveragedata.ProjectData;
-
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.ClassWriter;
-import org.ofbiz.base.start.Instrumenter;
-
-public final class CoberturaInstrumenter implements Instrumenter {
-    private static final Constructor<?> INSTRUMENTER_CONSTRUCTOR;
-    private static final Method IS_INSTRUMENTED_METHOD;
-    static {
-        try {
-            Class<?> clz = CoberturaInstrumenter.class.getClassLoader().loadClass("net.sourceforge.cobertura.instrument.ClassInstrumenter");
-            INSTRUMENTER_CONSTRUCTOR = clz.getConstructor(ProjectData.class, ClassVisitor.class, Collection.class, Collection.class);
-            INSTRUMENTER_CONSTRUCTOR.setAccessible(true);
-            IS_INSTRUMENTED_METHOD = clz.getDeclaredMethod("isInstrumented");
-            IS_INSTRUMENTED_METHOD.setAccessible(true);
-        } catch (Throwable t) {
-            throw (InternalError) new InternalError(t.getMessage()).initCause(t);
-        }
-    }
-
-    protected File dataFile;
-    protected ProjectData projectData;
-    protected boolean forInstrumenting;
-
-    public File getDefaultFile() throws IOException {
-        return CoverageDataFileHandler.getDefaultDataFile();
-    }
-
-    public void open(File dataFile, boolean forInstrumenting) throws IOException {
-        System.setProperty("net.sourceforge.cobertura.datafile", dataFile.toString());
-        this.forInstrumenting = forInstrumenting;
-        this.dataFile = dataFile;
-        if (forInstrumenting) {
-            if (dataFile.exists()) {
-                projectData = CoverageDataFileHandler.loadCoverageData(dataFile);
-            } else {
-                projectData = new ProjectData();
-            }
-        }
-    }
-
-    public void close() throws IOException {
-        if (forInstrumenting) {
-            CoverageDataFileHandler.saveCoverageData(projectData, dataFile);
-        }
-    }
-
-    public byte[] instrumentClass(byte[] bytes) throws IOException {
-        if (forInstrumenting) {
-            ClassReader cr = new ClassReader(bytes);
-            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS/* | ClassWriter.COMPUTE_FRAMES*/);
-            try {
-                ClassVisitor ci = (ClassVisitor) INSTRUMENTER_CONSTRUCTOR.newInstance(projectData, cw, Collections.EMPTY_LIST, Collections.EMPTY_LIST);
-                cr.accept(ci, 0);
-                if (((Boolean) IS_INSTRUMENTED_METHOD.invoke(ci)).booleanValue()) {
-                    return cw.toByteArray();
-                }
-            } catch (Throwable t) {
-                throw (IOException) new IOException(t.getMessage()).initCause(t);
-            }
-        }
-        return bytes;
-    }
-}
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.ofbiz.base.config;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+
+import net.sourceforge.cobertura.coveragedata.CoverageDataFileHandler;
+import net.sourceforge.cobertura.coveragedata.ProjectData;
+
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.ofbiz.base.start.Instrumenter;
+
+public final class CoberturaInstrumenter implements Instrumenter {
+    private static final Constructor<?> INSTRUMENTER_CONSTRUCTOR;
+    private static final Method IS_INSTRUMENTED_METHOD;
+    static {
+        try {
+            Class<?> clz = CoberturaInstrumenter.class.getClassLoader().loadClass("net.sourceforge.cobertura.instrument.ClassInstrumenter");
+            INSTRUMENTER_CONSTRUCTOR = clz.getConstructor(ProjectData.class, ClassVisitor.class, Collection.class, Collection.class);
+            INSTRUMENTER_CONSTRUCTOR.setAccessible(true);
+            IS_INSTRUMENTED_METHOD = clz.getDeclaredMethod("isInstrumented");
+            IS_INSTRUMENTED_METHOD.setAccessible(true);
+        } catch (Throwable t) {
+            throw (InternalError) new InternalError(t.getMessage()).initCause(t);
+        }
+    }
+
+    protected File dataFile;
+    protected ProjectData projectData;
+    protected boolean forInstrumenting;
+
+    public File getDefaultFile() throws IOException {
+        return CoverageDataFileHandler.getDefaultDataFile();
+    }
+
+    public void open(File dataFile, boolean forInstrumenting) throws IOException {
+        System.setProperty("net.sourceforge.cobertura.datafile", dataFile.toString());
+        this.forInstrumenting = forInstrumenting;
+        this.dataFile = dataFile;
+        if (forInstrumenting) {
+            if (dataFile.exists()) {
+                projectData = CoverageDataFileHandler.loadCoverageData(dataFile);
+            } else {
+                projectData = new ProjectData();
+            }
+        }
+    }
+
+    public void close() throws IOException {
+        if (forInstrumenting) {
+            CoverageDataFileHandler.saveCoverageData(projectData, dataFile);
+        }
+    }
+
+    public byte[] instrumentClass(byte[] bytes) throws IOException {
+        if (forInstrumenting) {
+            ClassReader cr = new ClassReader(bytes);
+            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS/* | ClassWriter.COMPUTE_FRAMES*/);
+            try {
+                ClassVisitor ci = (ClassVisitor) INSTRUMENTER_CONSTRUCTOR.newInstance(projectData, cw, Collections.EMPTY_LIST, Collections.EMPTY_LIST);
+                cr.accept(ci, 0);
+                if (((Boolean) IS_INSTRUMENTED_METHOD.invoke(ci)).booleanValue()) {
+                    return cw.toByteArray();
+                }
+            } catch (Throwable t) {
+                throw (IOException) new IOException(t.getMessage()).initCause(t);
+            }
+        }
+        return bytes;
+    }
+}

Propchange: ofbiz/trunk/framework/base/src/org/ofbiz/base/config/CoberturaInstrumenter.java
            ('svn:eol-style' removed)

Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/container/JustLoadComponentsContainer.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/container/JustLoadComponentsContainer.java?rev=1695126&r1=1695125&r2=1695126&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/org/ofbiz/base/container/JustLoadComponentsContainer.java (original)
+++ ofbiz/trunk/framework/base/src/org/ofbiz/base/container/JustLoadComponentsContainer.java Mon Aug 10 16:15:37 2015
@@ -1,58 +1,58 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *******************************************************************************/
-package org.ofbiz.base.container;
-
-import org.ofbiz.base.component.AlreadyLoadedException;
-import org.ofbiz.base.component.ComponentException;
-import org.ofbiz.base.util.Debug;
-
-/**
- * A Container implementation to run the tests configured through this testtools stuff.
- */
-public class JustLoadComponentsContainer implements Container {
-
-    public static final String module = JustLoadComponentsContainer.class.getName();
-
-    private String name;
-
-    @Override
-    public void init(String[] args, String name, String configFile) {
-        this.name = name;
-        try {
-            ComponentContainer cc = new ComponentContainer();
-            cc.loadComponents(null);
-        } catch (AlreadyLoadedException e) {
-            Debug.logError(e, module);
-        } catch (ComponentException e) {
-            Debug.logError(e, module);
-            //throw UtilMisc.initCause(new ContainerException(e.getMessage()), e);
-        }
-    }
-
-    public boolean start() throws ContainerException {
-        return true;
-    }
-
-    public void stop() throws ContainerException {
-    }
-
-    public String getName() {
-        return name;
-    }
-}
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.ofbiz.base.container;
+
+import org.ofbiz.base.component.AlreadyLoadedException;
+import org.ofbiz.base.component.ComponentException;
+import org.ofbiz.base.util.Debug;
+
+/**
+ * A Container implementation to run the tests configured through this testtools stuff.
+ */
+public class JustLoadComponentsContainer implements Container {
+
+    public static final String module = JustLoadComponentsContainer.class.getName();
+
+    private String name;
+
+    @Override
+    public void init(String[] args, String name, String configFile) {
+        this.name = name;
+        try {
+            ComponentContainer cc = new ComponentContainer();
+            cc.loadComponents(null);
+        } catch (AlreadyLoadedException e) {
+            Debug.logError(e, module);
+        } catch (ComponentException e) {
+            Debug.logError(e, module);
+            //throw UtilMisc.initCause(new ContainerException(e.getMessage()), e);
+        }
+    }
+
+    public boolean start() throws ContainerException {
+        return true;
+    }
+
+    public void stop() throws ContainerException {
+    }
+
+    public String getName() {
+        return name;
+    }
+}

Propchange: ofbiz/trunk/framework/base/src/org/ofbiz/base/container/JustLoadComponentsContainer.java
            ('svn:eol-style' removed)