Posted by
jacopoc on
Oct 09, 2007; 4:47pm
URL: http://ofbiz.116.s1.nabble.com/svn-commit-r583200-in-ofbiz-trunk-applications-manufacturing-servicedef-services-production-run-xml-a-tp213496.html
Author: jacopoc
Date: Tue Oct 9 08:47:23 2007
New Revision: 583200
URL:
http://svn.apache.org/viewvc?rev=583200&view=revLog:
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());