You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ja...@apache.org on 2009/12/23 16:07:10 UTC
svn commit: r893541 - in /ofbiz/trunk/applications:
manufacturing/src/org/ofbiz/manufacturing/jobshopmgt/
manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/
manufacturing/webapp/manufacturing/jobshopmgt/ product/data/
product/script/org/ofb...
Author: jacopoc
Date: Wed Dec 23 15:07:06 2009
New Revision: 893541
URL: http://svn.apache.org/viewvc?rev=893541&view=rev
Log:
Enhancements to the support of actual costs in production runs:
* in form definitions: converted (not working) bsh calls into groovy calls
* added cost information to screens showing inventory consumed and produced by production runs
* added support for actual overhead costs of production runs
Modified:
ofbiz/trunk/applications/manufacturing/src/org/ofbiz/manufacturing/jobshopmgt/ProductionRunServices.java
ofbiz/trunk/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunCosts.groovy
ofbiz/trunk/applications/manufacturing/webapp/manufacturing/jobshopmgt/ProductionRunForms.xml
ofbiz/trunk/applications/product/data/ProductTypeData.xml
ofbiz/trunk/applications/product/script/org/ofbiz/product/cost/CostServices.xml
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=893541&r1=893540&r2=893541&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 Wed Dec 23 15:07:06 2009
@@ -845,6 +845,17 @@
Debug.logError(e, "Problem calling the updateWorkEffort service", module);
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));
+ }
// If this is the last task, then the production run is marked as 'completed'
if (allTaskCompleted) {
serviceContext.clear();
@@ -858,17 +869,49 @@
Debug.logError(e, "Problem calling the updateWorkEffort service", module);
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));
+ // and compute the overhead costs associated to the finished product
+ try {
+ // get the currency
+ GenericValue facility = productionRun.getGenericValue().getRelatedOne("Facility");
+ Map outputMap = dispatcher.runSync("getPartyAccountingPreferences", UtilMisc.<String, Object>toMap("userLogin", userLogin, "organizationPartyId", facility.getString("ownerPartyId")));
+ Map partyAccountingPreference = (Map)outputMap.get("partyAccountingPreference");
+ if (partyAccountingPreference == null) {
+ return ServiceUtil.returnError("Unable to find a currency for production run costs");
+ }
+ outputMap = dispatcher.runSync("getProductionRunCost", UtilMisc.<String, Object>toMap("userLogin", userLogin, "workEffortId", productionRunId));
+
+ BigDecimal totalCost = (BigDecimal)outputMap.get("totalCost");
+ if (totalCost == null) {
+ totalCost = ZERO;
+ }
+
+ List productCostComponentCalcs = delegator.findByAnd("ProductCostComponentCalc", UtilMisc.toMap("productId", productionRun.getProductProduced().getString("productId")), UtilMisc.toList("sequenceNum"));
+ for (int i = 0; i < productCostComponentCalcs.size(); i++) {
+ GenericValue productCostComponentCalc = (GenericValue)productCostComponentCalcs.get(i);
+ GenericValue costComponentCalc = productCostComponentCalc.getRelatedOne("CostComponentCalc");
+ GenericValue customMethod = costComponentCalc.getRelatedOne("CustomMethod");
+ if (customMethod == null) {
+ // TODO: not supported for CostComponentCalc entries directly associated to a product
+ Debug.logWarning("Unable to create cost component for cost component calc with id [" + costComponentCalc.getString("costComponentCalcId") + "] because customMethod is not set", module);
+ } else {
+ Map costMethodResult = dispatcher.runSync(customMethod.getString("customMethodName"), UtilMisc.toMap("productCostComponentCalc", productCostComponentCalc,
+ "costComponentCalc", costComponentCalc,
+ "costComponentTypePrefix", "ACTUAL",
+ "baseCost", totalCost,
+ "currencyUomId", (String)partyAccountingPreference.get("baseCurrencyUomId"),
+ "userLogin", userLogin));
+ BigDecimal productCostAdjustment = (BigDecimal)costMethodResult.get("productCostAdjustment");
+ totalCost = totalCost.add(productCostAdjustment);
+ Map inMap = UtilMisc.toMap("userLogin", userLogin, "workEffortId", productionRunId);
+ inMap.put("costComponentTypeId", "ACTUAL_" + productCostComponentCalc.getString("costComponentTypeId"));
+ inMap.put("costUomId", (String)partyAccountingPreference.get("baseCurrencyUomId"));
+ inMap.put("cost", productCostAdjustment);
+ dispatcher.runSync("createCostComponent", inMap);
+ }
+ }
+ } catch(Exception e) {
+ return ServiceUtil.returnError("Unable to compute overhead costs for production run: " + e.getMessage());
+ }
}
result.put("oldStatusId", oldStatusId);
@@ -1551,14 +1594,23 @@
Debug.logWarning(e.getMessage(), module);
return ServiceUtil.returnError(e.getMessage());
}
- // calculate the inventory item unit cost
+ // the inventory item unit cost is the product's standard cost
BigDecimal unitCost = ZERO;
try {
- Map outputMap = dispatcher.runSync("getProductionRunCost", UtilMisc.<String, Object>toMap("userLogin", userLogin, "workEffortId", productionRunId));
- BigDecimal totalCost = (BigDecimal)outputMap.get("totalCost");
- // FIXME
- unitCost = totalCost.divide(quantity, decimals, rounding);
- } catch (GenericServiceException e) {
+ // get the currency
+ GenericValue facility = productionRun.getGenericValue().getRelatedOne("Facility");
+ Map outputMap = dispatcher.runSync("getPartyAccountingPreferences", UtilMisc.<String, Object>toMap("userLogin", userLogin, "organizationPartyId", facility.getString("ownerPartyId")));
+ Map partyAccountingPreference = (Map)outputMap.get("partyAccountingPreference");
+ if (partyAccountingPreference == null) {
+ return ServiceUtil.returnError("Unable to find a currency for production run costs");
+ }
+ outputMap = dispatcher.runSync("getProductCost", UtilMisc.<String, Object>toMap("userLogin", userLogin, "productId", productionRun.getProductProduced().getString("productId"), "currencyUomId", (String)partyAccountingPreference.get("baseCurrencyUomId"), "costComponentTypePrefix", "EST_STD"));
+ unitCost = (BigDecimal)outputMap.get("productCost");
+ if (unitCost == null) {
+ unitCost = ZERO;
+ }
+
+ } catch (Exception e) {
Debug.logWarning(e.getMessage(), module);
return ServiceUtil.returnError(e.getMessage());
}
Modified: ofbiz/trunk/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunCosts.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunCosts.groovy?rev=893541&r1=893540&r2=893541&view=diff
==============================================================================
--- ofbiz/trunk/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunCosts.groovy (original)
+++ ofbiz/trunk/applications/manufacturing/webapp/manufacturing/WEB-INF/actions/jobshopmgt/ProductionRunCosts.groovy Wed Dec 23 15:07:06 2009
@@ -29,4 +29,11 @@
taskCostsForm.putInContext("taskCosts", costs);
taskCosts.add([task : task ,costsForm : taskCostsForm]);
}
-context.taskCosts = taskCosts;
\ No newline at end of file
+// get the costs directly associated to the production run (e.g. overhead costs)
+productionRun = delegator.findOne("WorkEffort", [workEffortId: productionRunId], true);
+costs = EntityUtil.filterByDate(delegator.findByAnd("CostComponent", [workEffortId : productionRunId]));
+HtmlFormWrapper taskCostsForm = new HtmlFormWrapper("component://manufacturing/webapp/manufacturing/jobshopmgt/ProductionRunForms.xml", "ProductionRunTaskCosts", request, response);
+taskCostsForm.putInContext("taskCosts", costs);
+taskCosts.add([task : productionRun ,costsForm : taskCostsForm]);
+
+context.taskCosts = taskCosts;
Modified: ofbiz/trunk/applications/manufacturing/webapp/manufacturing/jobshopmgt/ProductionRunForms.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/manufacturing/webapp/manufacturing/jobshopmgt/ProductionRunForms.xml?rev=893541&r1=893540&r2=893541&view=diff
==============================================================================
--- ofbiz/trunk/applications/manufacturing/webapp/manufacturing/jobshopmgt/ProductionRunForms.xml (original)
+++ ofbiz/trunk/applications/manufacturing/webapp/manufacturing/jobshopmgt/ProductionRunForms.xml Wed Dec 23 15:07:06 2009
@@ -140,13 +140,14 @@
</hyperlink>
</field>
<field name="lotId" entry-name="inventoryItemId"><display-entity entity-name="InventoryItem" key-field-name="inventoryItemId" description="${lotId} "/></field>
- <field name="creationDate" entry-name="inventoryItemId"><display-entity entity-name="InventoryItem" key-field-name="inventoryItemId" description="${datetimeReceived}"/></field>
+ <field name="unitCost" entry-name="inventoryItemId"><display-entity entity-name="InventoryItem" key-field-name="inventoryItemId" description="${unitCost} "/></field>
+\ <field name="creationDate" entry-name="inventoryItemId"><display-entity entity-name="InventoryItem" key-field-name="inventoryItemId" description="${datetimeReceived}"/></field>
</form>
<form name="ViewListProductionRunRoutingTasks" type="list" title="" list-name="productionRunRoutingTasks"
odd-row-style="alternate-row" default-table-style="basic-table hover-bar">
<row-actions>
- <set field="estimatedTotalMilliSeconds" value="${bsh:estimatedMilliSeconds * quantity}" type="BigDecimal"/>
+ <set field="estimatedTotalMilliSeconds" value="${groovy:estimatedMilliSeconds * quantity}" type="BigDecimal"/>
</row-actions>
<field name="priority" title="${uiLabelMap.CommonSequenceNum}"><display/></field>
<field name="workEffortId" title="${uiLabelMap.ManufacturingTaskName}"><display description="${workEffortName} [${workEffortId}]"/></field>
@@ -160,7 +161,7 @@
<form name="ListProductionRunRoutingTasks" type="list" target="ProductionRunTasks" title="" list-name="productionRunRoutingTasks"
odd-row-style="alternate-row" header-row-style="header-row-2" default-table-style="basic-table hover-bar">
<row-actions>
- <set field="estimatedTotalMilliSeconds" value="${bsh:estimatedMilliSeconds * quantity}" type="BigDecimal"/>
+ <set field="estimatedTotalMilliSeconds" value="${groovy:estimatedMilliSeconds * quantity}" type="BigDecimal"/>
</row-actions>
<field name="priority" title="${uiLabelMap.CommonSequenceNum}"><display/></field>
<field name="workEffortId" title="${uiLabelMap.ManufacturingTaskName}"><display description="${workEffortName} [${workEffortId}]"/></field>
@@ -509,12 +510,12 @@
header-row-style="header-row" default-table-style="basic-table">
<field name="productionRunId"><hidden/></field>
<field name="workEffortId"><hidden/></field>
- <field name="productId" title="${uiLabelMap.ProductProductId}" use-when="${bsh:delivProducts.size()>0}">
+ <field name="productId" title="${uiLabelMap.ProductProductId}" use-when="${groovy:delivProducts.size()>0}">
<drop-down allow-empty="false">
<list-options list-name="delivProducts" key-name="productId" description="${productId}"/>
</drop-down>
</field>
- <field name="productId" title="${uiLabelMap.ProductProductId}" use-when="${bsh:delivProducts.size()==0}"><lookup target-form-name="LookupProduct"/></field>
+ <field name="productId" title="${uiLabelMap.ProductProductId}" use-when="${groovy:delivProducts.size()==0}"><lookup target-form-name="LookupProduct"/></field>
<field name="quantity" title="${uiLabelMap.ManufacturingAddQuantityProduced}">
<text/>
</field>
@@ -904,7 +905,7 @@
<form name="ProductionRunTaskActualComponents" type="list" target="updateProductionRunComponent" paginate-target="ProductionRunActualComponents" title="" list-name="records"
odd-row-style="alternate-row" default-table-style="basic-table hover-bar">
<row-actions>
- <set field="quantityOnHandDiff" value="${bsh:-1*quantityOnHandDiff}" type="BigDecimal"/>
+ <set field="quantityOnHandDiff" value="${groovy:-1*quantityOnHandDiff}" type="BigDecimal"/>
</row-actions>
<field name="inventoryItemId" widget-style="buttontext">
<hyperlink target="/facility/control/EditInventoryItem" description="${inventoryItemId}" also-hidden="false" target-type="inter-app">
@@ -917,6 +918,9 @@
<field name="workEffortId"><hidden/></field>
<field name="productionRunId"><hidden/></field>
<field name="quantityOnHandDiff" title="${uiLabelMap.CommonQuantity}"><display/></field>
+ <field name="unitCost" entry-name="inventoryItemId">
+ <display-entity entity-name="InventoryItem" key-field-name="inventoryItemId" description="${unitCost}"/>
+ </field>
<field name="reasonEnumId">
<display-entity entity-name="Enumeration" key-field-name="enumId" description="${description}"/>
</field>
Modified: ofbiz/trunk/applications/product/data/ProductTypeData.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/data/ProductTypeData.xml?rev=893541&r1=893540&r2=893541&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/data/ProductTypeData.xml (original)
+++ ofbiz/trunk/applications/product/data/ProductTypeData.xml Wed Dec 23 15:07:06 2009
@@ -35,6 +35,9 @@
<CostComponentType costComponentTypeId="ACTUAL_ROUTE_COST" description="Actual Route (fixed asset usage) Cost" hasTable="N" parentTypeId="ROUTE_COST"/>
<CostComponentType costComponentTypeId="ACTUAL_LABOR_COST" description="Actual Labor Cost" hasTable="N" parentTypeId="LABOR_COST"/>
<CostComponentType costComponentTypeId="ACTUAL_OTHER_COST" description="Actual Other Cost" hasTable="N" parentTypeId="OTHER_COST"/>
+ <CostComponentType costComponentTypeId="ACTUAL_GEN_COST" description="Actual General Cost" hasTable="N" parentTypeId="GEN_COST"/>
+ <CostComponentType costComponentTypeId="ACTUAL_IND_COST" description="Actual Indirect Cost" hasTable="N" parentTypeId="IND_COST"/>
+ <CostComponentType costComponentTypeId="ACTUAL_OTHER_COST" description="Actual Other Cost" hasTable="N" parentTypeId="OTHER_COST"/>
<!-- Cost Formulae -->
<CustomMethodType customMethodTypeId="COST_FORMULA" description="Formula for calculating costs for tasks and products"/>
Modified: ofbiz/trunk/applications/product/script/org/ofbiz/product/cost/CostServices.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/script/org/ofbiz/product/cost/CostServices.xml?rev=893541&r1=893540&r2=893541&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/script/org/ofbiz/product/cost/CostServices.xml (original)
+++ ofbiz/trunk/applications/product/script/org/ofbiz/product/cost/CostServices.xml Wed Dec 23 15:07:06 2009
@@ -390,6 +390,7 @@
<get-related-one relation-name="CustomMethod" to-value-field="customMethod" value-field="costComponentCalc"/>
<if-empty field="customMethod">
<!-- TODO: not supported for CostComponentCalc entries directly associated to a product -->
+ <log level="warning" message="Unable to create cost component for cost component calc with id [${costComponentCalc.costComponentCalcId}] because customMethod is not set"/>
<else>
<clear-field field="customMethodParameters"/>
<set field="customMethodParameters.productCostComponentCalc" from-field="productCostComponentCalc"/>