|
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"/> |
| Free forum by Nabble | Edit this page |
