svn commit: r583200 - in /ofbiz/trunk/applications/manufacturing: servicedef/services_production_run.xml src/org/ofbiz/manufacturing/jobshopmgt/ProductionRunServices.java

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

svn commit: r583200 - in /ofbiz/trunk/applications/manufacturing: servicedef/services_production_run.xml src/org/ofbiz/manufacturing/jobshopmgt/ProductionRunServices.java

jacopoc
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());