Author: jacopoc
Date: Tue Oct  9 08:47:23 2007
New Revision: 583200

URL: http://svn.apache.org/viewvc?rev=583200&view=rev
Log:
Implemented service that computes the actual/real production run routing task's 
costs.

Modified:
    
ofbiz/trunk/applications/manufacturing/servicedef/services_production_run.xml
    
ofbiz/trunk/applications/manufacturing/src/org/ofbiz/manufacturing/jobshopmgt/ProductionRunServices.java

Modified: 
ofbiz/trunk/applications/manufacturing/servicedef/services_production_run.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/manufacturing/servicedef/services_production_run.xml?rev=583200&r1=583199&r2=583200&view=diff
==============================================================================
--- 
ofbiz/trunk/applications/manufacturing/servicedef/services_production_run.xml 
(original)
+++ 
ofbiz/trunk/applications/manufacturing/servicedef/services_production_run.xml 
Tue Oct  9 08:47:23 2007
@@ -329,4 +329,9 @@
         <attribute mode="IN" name="workEffortId" optional="false" 
type="String"/>
         <attribute mode="OUT" name="totalCost" optional="false" 
type="BigDecimal"/>
     </service>
+    <service name="createProductionRunTaskCosts" engine="java"
+            
location="org.ofbiz.manufacturing.jobshopmgt.ProductionRunServices" 
invoke="createProductionRunTaskCosts" auth="true">
+        <description>Compute the actual costs for the production run 
task.</description>
+        <attribute mode="IN" name="productionRunTaskId" optional="false" 
type="String"/>
+    </service>
 </services>

Modified: 
ofbiz/trunk/applications/manufacturing/src/org/ofbiz/manufacturing/jobshopmgt/ProductionRunServices.java
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/manufacturing/src/org/ofbiz/manufacturing/jobshopmgt/ProductionRunServices.java?rev=583200&r1=583199&r2=583200&view=diff
==============================================================================
--- 
ofbiz/trunk/applications/manufacturing/src/org/ofbiz/manufacturing/jobshopmgt/ProductionRunServices.java
 (original)
+++ 
ofbiz/trunk/applications/manufacturing/src/org/ofbiz/manufacturing/jobshopmgt/ProductionRunServices.java
 Tue Oct  9 08:47:23 2007
@@ -857,6 +857,18 @@
                     return 
ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"ManufacturingProductionRunStatusNotChanged", locale));
                 }
             }
+            // Calculate and store the production run task actual costs
+            serviceContext.clear();
+            serviceContext.put("productionRunTaskId", taskId);
+            serviceContext.put("userLogin", userLogin);
+            resultService = null;
+            try {
+                resultService = 
dispatcher.runSync("createProductionRunTaskCosts", serviceContext);
+            } catch (GenericServiceException e) {
+                Debug.logError(e, "Problem calling the 
createProductionRunTaskCosts service", module);
+                return 
ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"ManufacturingProductionRunStatusNotChanged", locale));
+            }
+
             result.put("oldStatusId", oldStatusId);
             result.put("newStatusId", "PRUN_COMPLETED");
             result.put(ModelService.SUCCESS_MESSAGE, 
UtilProperties.getMessage(resource, 
"ManufacturingProductionRunStatusChanged",UtilMisc.toMap("newStatusId", 
"PRUN_DOC_PRINTED"), locale));
@@ -925,6 +937,118 @@
         return result;
     }
 
+    public static Map createProductionRunTaskCosts(DispatchContext ctx, Map 
context) {
+        GenericDelegator delegator = ctx.getDelegator();
+        LocalDispatcher dispatcher = ctx.getDispatcher();
+        GenericValue userLogin = (GenericValue) context.get("userLogin");
+
+        // this is the id of the actual (real) production run task
+        String productionRunTaskId = 
(String)context.get("productionRunTaskId");
+        try {
+            GenericValue workEffort = delegator.findByPrimaryKey("WorkEffort", 
UtilMisc.toMap("workEffortId", productionRunTaskId));
+            if (UtilValidate.isEmpty(workEffort)) {
+                return ServiceUtil.returnError("Cannot find the production run 
task with id [" + productionRunTaskId + "]");
+            }
+            double actualTotalMilliSeconds = 0.0;
+            Double actualSetupMillis = 
workEffort.getDouble("actualSetupMillis");
+            Double actualMilliSeconds = 
workEffort.getDouble("actualMilliSeconds");
+            if (actualSetupMillis != null) {
+                actualTotalMilliSeconds += actualSetupMillis.doubleValue();
+            }
+            if (actualMilliSeconds != null) {
+                actualTotalMilliSeconds += actualMilliSeconds.doubleValue();
+            }
+            // Get the template (aka routing task) of the work effort
+            List routingTasks = 
EntityUtil.filterByDate(delegator.findByAnd("WorkEffortAssoc",
+                                                                            
UtilMisc.toMap("workEffortIdTo", productionRunTaskId,
+                                                                               
            "workEffortAssocTypeId", "WORK_EFF_TEMPLATE")));
+            GenericValue routingTask = EntityUtil.getFirst(routingTasks);
+            List workEffortCostCalcs = null;
+            if (UtilValidate.isEmpty(routingTask)) {
+                // there is no template, try to get the cost entries for the 
actual production run task, if any
+                workEffortCostCalcs = 
delegator.findByAnd("WorkEffortCostCalc", UtilMisc.toMap("workEffortId", 
productionRunTaskId));
+            } else {
+                workEffortCostCalcs = 
delegator.findByAnd("WorkEffortCostCalc", UtilMisc.toMap("workEffortId", 
routingTask.getString("workEffortIdFrom")));
+            }
+            // Get all the valid CostComponentCalc entries
+            workEffortCostCalcs = EntityUtil.filterByDate(workEffortCostCalcs);
+            Iterator workEffortCostCalcsIt = workEffortCostCalcs.iterator();
+            while (workEffortCostCalcsIt.hasNext()) {
+                GenericValue workEffortCostCalc = 
(GenericValue)workEffortCostCalcsIt.next();
+                GenericValue costComponentCalc = 
workEffortCostCalc.getRelatedOne("CostComponentCalc");
+                GenericValue customMethod = 
costComponentCalc.getRelatedOne("CustomMethod");
+                if (UtilValidate.isEmpty(customMethod) || 
UtilValidate.isEmpty(customMethod.getString("customMethodName"))) {
+                    // compute the total time
+                    double totalTime = actualTotalMilliSeconds;
+                    if (costComponentCalc.get("perMilliSecond") != null) {
+                        long perMilliSecond = 
costComponentCalc.getLong("perMilliSecond").longValue();
+                        if (perMilliSecond != 0) {
+                            totalTime = totalTime / perMilliSecond;
+                        }
+                    }
+                    // compute the cost
+                    BigDecimal fixedCost = 
costComponentCalc.getBigDecimal("fixedCost");
+                    BigDecimal variableCost = 
costComponentCalc.getBigDecimal("variableCost");
+                    if (fixedCost == null) {
+                        fixedCost = BigDecimal.ZERO;
+                    }
+                    if (variableCost == null) {
+                        variableCost = BigDecimal.ZERO;
+                    }
+                    BigDecimal totalCost = 
fixedCost.add(variableCost.multiply(BigDecimal.valueOf(totalTime))).setScale(decimals,
 rounding);
+                    // store the cost
+                    Map inMap = UtilMisc.toMap("userLogin", userLogin, 
"workEffortId", productionRunTaskId);
+                    inMap.put("costComponentTypeId", "ACTUAL_" + 
workEffortCostCalc.getString("costComponentTypeId"));
+                    inMap.put("costComponentCalcId", 
costComponentCalc.getString("costComponentCalcId"));
+                    inMap.put("costUomId", 
costComponentCalc.getString("currencyUomId"));
+                    inMap.put("cost", new Double(totalCost.doubleValue()));
+                    dispatcher.runSync("createCostComponent", inMap);
+                } else {
+                    // use the custom method (aka formula) to compute the costs
+                    Map inMap = UtilMisc.toMap("userLogin", userLogin, 
"workEffort", workEffort);
+                    inMap.put("workEffortCostCalc", workEffortCostCalc);
+                    inMap.put("costComponentCalc", costComponentCalc);
+                    
dispatcher.runSync(customMethod.getString("customMethodName"), inMap);
+                }
+            }
+        } catch(Exception e) {
+            return ServiceUtil.returnError("Unable to create routing costs for 
the production run task [" + productionRunTaskId + "]: " + e.getMessage());
+        }
+        // materials costs: these are the costs derived from the materials 
used by the production run task
+        try {
+            Iterator inventoryAssignIt = 
delegator.findByAnd("WorkEffortAndInventoryAssign", 
UtilMisc.toMap("workEffortId", productionRunTaskId)).iterator();
+            Map materialsCostByCurrency = FastMap.newInstance();
+            while (inventoryAssignIt.hasNext()) {
+                GenericValue inventoryConsumed = 
(GenericValue)inventoryAssignIt.next();
+                BigDecimal quantity = 
inventoryConsumed.getBigDecimal("quantity");
+                BigDecimal unitCost = 
inventoryConsumed.getBigDecimal("unitCost");
+                if (UtilValidate.isEmpty(unitCost) || 
UtilValidate.isEmpty(quantity)) {
+                    continue;
+                }
+                String currencyUomId = 
inventoryConsumed.getString("currencyUomId");
+                if (!materialsCostByCurrency.containsKey(currencyUomId)) {
+                    materialsCostByCurrency.put(currencyUomId, 
BigDecimal.ZERO);
+                }
+                BigDecimal materialsCost = 
(BigDecimal)materialsCostByCurrency.get(currencyUomId);
+                materialsCost = 
materialsCost.add(unitCost.multiply(quantity)).setScale(decimals, rounding);
+                materialsCostByCurrency.put(currencyUomId, materialsCost);
+            }
+            Iterator currencyIt = materialsCostByCurrency.keySet().iterator();
+            while (currencyIt.hasNext()) {
+                String currencyUomId = (String)currencyIt.next();
+                BigDecimal materialsCost = 
(BigDecimal)materialsCostByCurrency.get(currencyUomId);
+                Map inMap = UtilMisc.toMap("userLogin", userLogin, 
"workEffortId", productionRunTaskId);
+                inMap.put("costComponentTypeId", "ACTUAL_MAT_COST");
+                inMap.put("costUomId", currencyUomId);
+                inMap.put("cost", new Double(materialsCost.doubleValue()));
+                dispatcher.runSync("createCostComponent", inMap);
+            }
+        } catch(Exception e) {
+            return ServiceUtil.returnError("Unable to create materials costs 
for the production run task [" + productionRunTaskId + "]: " + e.getMessage());
+        }
+        return ServiceUtil.returnSuccess();
+    }
+
     /**
      * check if field for routingTask update are correct and if need 
recalculated data in Production Run.
      *  Check<ul>
@@ -1397,7 +1521,7 @@
             Map outputMap = dispatcher.runSync("getProductionRunCost", 
UtilMisc.toMap("userLogin", userLogin, "workEffortId", productionRunId));
             BigDecimal totalCost = (BigDecimal)outputMap.get("totalCost");
             // FIXME
-            unitCost = totalCost.divide(new 
BigDecimal(quantity.doubleValue()), decimals, rounding);
+            unitCost = 
totalCost.divide(BigDecimal.valueOf(quantity.doubleValue()), decimals, 
rounding);
         } catch (GenericServiceException e) {
             Debug.logWarning(e.getMessage(), module);
             return ServiceUtil.returnError(e.getMessage());


Reply via email to