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"/>