Author: apatel
Date: Mon Aug 10 12:36:53 2009
New Revision: 802764
URL: http://svn.apache.org/viewvc?rev=802764&view=rev
Log:
Use product average cost in COGS transactions. Thanks Sumit for patch. Thanks
Vince and Eva for defining requirement and reviewing implementation.
Modified:
ofbiz/trunk/applications/accounting/script/org/ofbiz/accounting/ledger/GeneralLedgerServices.xml
ofbiz/trunk/applications/accounting/servicedef/services_cost.xml
ofbiz/trunk/applications/product/script/org/ofbiz/product/cost/CostServices.xml
ofbiz/trunk/applications/product/servicedef/secas.xml
Modified:
ofbiz/trunk/applications/accounting/script/org/ofbiz/accounting/ledger/GeneralLedgerServices.xml
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/applications/accounting/script/org/ofbiz/accounting/ledger/GeneralLedgerServices.xml?rev=802764&r1=802763&r2=802764&view=diff
==============================================================================
---
ofbiz/trunk/applications/accounting/script/org/ofbiz/accounting/ledger/GeneralLedgerServices.xml
(original)
+++
ofbiz/trunk/applications/accounting/script/org/ofbiz/accounting/ledger/GeneralLedgerServices.xml
Mon Aug 10 12:36:53 2009
@@ -1324,10 +1324,14 @@
</entity-and>
<first-from-list list="billToCustomers" entry="billToCustomer"/>
<!-- TODO: handle serialized inventory -->
+ <set field="getProdAvgCostMap.inventoryItem"
from-field="inventoryItem"/>
+ <call-service service-name="getProductAverageCost"
in-map-name="getProdAvgCostMap">
+ <result-to-field result-name="unitCost"/>
+ </call-service>
<calculate field="origAmount" decimal-scale="${ledgerDecimals}"
rounding-mode="${roundingMode}">
<calcop operator="multiply">
<calcop operator="get" field="itemIssuance.quantity"/>
- <calcop operator="get" field="inventoryItem.unitCost"/>
+ <calcop operator="get" field="unitCost"/>
</calcop>
</calculate>
<!-- prepare the doble posting (D/C) entries (AcctgTransEntry) -->
@@ -1382,10 +1386,14 @@
</entity-and>
<first-from-list list="billToCustomers" entry="billToCustomer"/>
<!-- TODO: handle serialized inventory -->
+ <set field="getProdAvgCostMap.inventoryItem"
from-field="inventoryItem"/>
+ <call-service service-name="getProductAverageCost"
in-map-name="getProdAvgCostMap">
+ <result-to-field result-name="unitCost"/>
+ </call-service>
<calculate field="origAmount" decimal-scale="${ledgerDecimals}"
rounding-mode="${roundingMode}">
<calcop operator="multiply">
<calcop operator="get" field="parameters.canceledQuantity"/>
- <calcop operator="get" field="inventoryItem.unitCost"/>
+ <calcop operator="get" field="unitCost"/>
</calcop>
</calculate>
<!-- prepare the doble posting (D/C) entries (AcctgTransEntry) -->
@@ -1442,10 +1450,19 @@
</else>
</if-not-empty>
<!-- TODO: handle serialized inventory -->
+ <if-not-empty field="shipmentReceipt.returnId">
+ <set field="getProdAvgCostMap.inventoryItem"
from-field="inventoryItem"/>
+ <call-service service-name="getProductAverageCost"
in-map-name="getProdAvgCostMap">
+ <result-to-field result-name="unitCost"/>
+ </call-service>
+ <else>
+ <set field="unitCost" from-field="inventoryItem.unitCost"/>
+ </else>
+ </if-not-empty>
<calculate field="origAmount" decimal-scale="${ledgerDecimals}"
rounding-mode="${roundingMode}">
<calcop operator="multiply">
<calcop operator="get"
field="shipmentReceipt.quantityAccepted"/>
- <calcop operator="get" field="inventoryItem.unitCost"/>
+ <calcop operator="get" field="unitCost"/>
</calcop>
</calculate>
<!-- prepare the doble posting (D/C) entries (AcctgTransEntry) -->
Modified: ofbiz/trunk/applications/accounting/servicedef/services_cost.xml
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/applications/accounting/servicedef/services_cost.xml?rev=802764&r1=802763&r2=802764&view=diff
==============================================================================
--- ofbiz/trunk/applications/accounting/servicedef/services_cost.xml (original)
+++ ofbiz/trunk/applications/accounting/servicedef/services_cost.xml Mon Aug 10
12:36:53 2009
@@ -93,4 +93,19 @@
<auto-attributes include="pk" mode="IN" optional="false"/>
</service>
+ <service name="updateProductAverageCostOnReceiveInventory"
default-entity-name="ProductAverageCost" engine="simple"
+
location="component://product/script/org/ofbiz/product/cost/CostServices.xml"
invoke="updateProductAverageCostOnReceiveInventory" auth="true">
+ <description>Update a Product Average Cost record on receive
inventory</description>
+ <permission-service service-name="acctgCostPermissionCheck"
main-action="UPDATE"/>
+ <attribute name="facilityId" type="String" mode="IN" optional="false"/>
+ <attribute name="productId" type="String" mode="IN" optional="false"/>
+ <attribute name="inventoryItemId" type="String" mode="IN"
optional="false"/>
+ </service>
+
+ <service name="getProductAverageCost" engine="simple"
+
location="component://product/script/org/ofbiz/product/cost/CostServices.xml"
invoke="getProductAverageCost" auth="true">
+ <description>Get Average cost of a product</description>
+ <attribute name="inventoryItem" type="org.ofbiz.entity.GenericValue"
mode="IN" optional="true"/>
+ <attribute name="unitCost" type="BigDecimal" mode="OUT"
optional="false"/>
+ </service>
</services>
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=802764&r1=802763&r2=802764&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
Mon Aug 10 12:36:53 2009
@@ -490,4 +490,75 @@
<field-to-result field="currencyUomId"/>
</if-compare>
</simple-method>
+
+ <simple-method method-name="updateProductAverageCostOnReceiveInventory"
short-description="Update a Product Average Cost record on receive inventory">
+ <entity-one entity-name="InventoryItem" value-field="inventoryItem"/>
+ <set field="organizationPartyId"
from-field="inventoryItem.ownerPartyId"/>
+ <if-empty field="organizationPartyId">
+ <entity-one entity-name="Facility" value-field="facility"
auto-field-map="true"/>
+ <set field="organizationPartyId"
from-field="facility.ownerPartyId"/>
+ <if-empty field="organizationPartyId">
+ <get-related-one relation-name="ProductStore"
to-value-field="productStore" value-field="facility"/>
+ <set field="organizationPartyId"
from-field="productStore.ownerPartyId"/>
+ <if-empty field="organizationPartyId">
+ <add-error error-list-name="error_list"><fail-message
message="Owner Party is missing, please provide any of the Inventory Owner or
Facility Owner or ProductStore Owner."/></add-error>
+ </if-empty>
+ <check-errors/>
+ </if-empty>
+ </if-empty>
+
+ <entity-and entity-name="ProductAverageCost"
list="productAverageCostList" filter-by-date="true">
+ <field-map field-name="productId"
from-field="parameters.productId"/>
+ <field-map field-name="facilityId"
from-field="parameters.facilityId"/>
+ <field-map field-name="productAverageCostTypeId"
value="SIMPLE_AVG_COST"/>
+ <field-map field-name="organizationPartyId"/>
+ </entity-and>
+ <first-from-list list="productAverageCostList"
entry="productAverageCost"/>
+
+ <set-service-fields service-name="createProductAverageCost"
map="parameters" to-map="productAverageCostMap"/>
+ <set field="productAverageCostMap.productAverageCostTypeId"
value="SIMPLE_AVG_COST"/>
+ <set field="productAverageCostMap.organizationPartyId"
from-field="organizationPartyId"/>
+ <if-empty field="productAverageCost">
+ <set field="productAverageCostMap.averageCost"
from-field="inventoryItem.unitCost"/>
+ <else>
+ <!-- Expire existing one and calculate average cost -->
+ <set-service-fields service-name="updateProductAverageCost"
map="productAverageCost" to-map="updateProductAverageCostMap"/>
+ <now-timestamp field="updateProductAverageCostMap.thruDate"/>
+ <call-service service-name="updateProductAverageCost"
in-map-name="updateProductAverageCostMap"/>
+
+ <set field="productAverageCostMap.averageCost"
value="${(productAverageCost.averageCost + inventoryItem.unitCost)/2}"
type="BigDecimal"/>
+ <property-to-field resource="arithmetic"
property="finaccount.decimals" field="roundingDecimals" default="2"/>
+ <property-to-field resource="arithmetic"
property="finaccount.roundingSimpleMethod" field="roundingMode"
default="HalfUp"/>
+ <calculate field="productAverageCostMap.averageCost"
type="BigDecimal" decimal-scale="${roundingDecimals}"
rounding-mode="${roundingMode}">
+ <calcop operator="get"
field="productAverageCostMap.averageCost"/>
+ </calculate>
+ </else>
+ </if-empty>
+ <call-service service-name="createProductAverageCost"
in-map-name="productAverageCostMap"/>
+ <log level="info" message="For facilityId ${parameters.facilityId},
Average cost of product ${parameters.productId} is set from
${updateProductAverageCostMap.averageCost} to
${productAverageCostMap.averageCost}"/>
+ </simple-method>
+
+ <simple-method method-name="getProductAverageCost"
short-description="Service to get the average cost of product">
+ <set field="inventoryItem" from-field="parameters.inventoryItem"/>
+ <set field="getPartyAcctgPrefMap.organizationPartyId"
from-field="inventoryItem.ownerPartyId"/>
+ <call-service service-name="getPartyAccountingPreferences"
in-map-name="getPartyAcctgPrefMap">
+ <result-to-field result-name="partyAccountingPreference"/>
+ </call-service>
+ <if-compare field="partyAccountingPreference.cogsMethodId"
operator="equals" value="COGS_AVG_COST">
+ <entity-and entity-name="ProductAverageCost"
list="productAverageCostList" filter-by-date="true">
+ <field-map field-name="productAverageCostTypeId"
value="SIMPLE_AVG_COST"/> <!-- TODO: handle for WEIGHTED_AVG_COST and
MOVING_AVG_COST -->
+ <field-map field-name="organizationPartyId"
from-field="inventoryItem.ownerPartyId"/>
+ <field-map field-name="productId"
from-field="inventoryItem.productId"/>
+ <field-map field-name="facilityId"
from-field="inventoryItem.facilityId"/>
+ </entity-and>
+ <first-from-list list="productAverageCostList"
entry="productAverageCost"/>
+ </if-compare>
+ <if-not-empty field="productAverageCost">
+ <set field="unitCost" from-field="productAverageCost.averageCost"
type="BigDecimal"/>
+ <else>
+ <set field="unitCost" from-field="inventoryItem.unitCost"
type="BigDecimal"/>
+ </else>
+ </if-not-empty>
+ <field-to-result field="unitCost"/>
+ </simple-method>
</simple-methods>
Modified: ofbiz/trunk/applications/product/servicedef/secas.xml
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/servicedef/secas.xml?rev=802764&r1=802763&r2=802764&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/servicedef/secas.xml (original)
+++ ofbiz/trunk/applications/product/servicedef/secas.xml Mon Aug 10 12:36:53
2009
@@ -123,4 +123,10 @@
<condition field-name="orderId" operator="is-not-empty"/>
<action service="updateIssuanceShipmentAndPoOnReceiveInventory"
mode="sync"/>
</eca>
+
+ <!-- Set the average cost of product -->
+ <eca service="receiveInventoryProduct" event="commit">
+ <action service="updateProductAverageCostOnReceiveInventory"
mode="sync"/>
+ </eca>
+
</service-eca>