Author: jacopoc
Date: Wed Mar 24 11:20:53 2010
New Revision: 927011

URL: http://svn.apache.org/viewvc?rev=927011&view=rev
Log:
More enhancements in the LIFO/FIFO implementation: now I have re-enabled the 
original "average cost" costing method (that was, and is, only partially 
implemented btw); I have also added a "new" costing method based on real 
inventory item unit costs: this was actually the only method (implicitly) 
supported before the implementation of LIFO and FIFO.
 

Modified:
    ofbiz/trunk/applications/accounting/data/AccountingTypeData.xml
    
ofbiz/trunk/applications/accounting/script/org/ofbiz/accounting/ledger/GeneralLedgerServices.xml

Modified: ofbiz/trunk/applications/accounting/data/AccountingTypeData.xml
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/accounting/data/AccountingTypeData.xml?rev=927011&r1=927010&r2=927011&view=diff
==============================================================================
--- ofbiz/trunk/applications/accounting/data/AccountingTypeData.xml (original)
+++ ofbiz/trunk/applications/accounting/data/AccountingTypeData.xml Wed Mar 24 
11:20:53 2010
@@ -955,6 +955,7 @@ under the License.
     <Enumeration description="LIFO" enumCode="LIFO" enumId="COGS_LIFO" 
sequenceId="01" enumTypeId="COGS_METHODS"/>
     <Enumeration description="FIFO" enumCode="FIFO" enumId="COGS_FIFO" 
sequenceId="02" enumTypeId="COGS_METHODS"/>
     <Enumeration description="Average Cost" enumCode="AVG_COST" 
enumId="COGS_AVG_COST" sequenceId="03" enumTypeId="COGS_METHODS"/>
+    <Enumeration description="Inventory Item Cost" enumCode="INV_COST" 
enumId="COGS_INV_COST" sequenceId="04" enumTypeId="COGS_METHODS"/>
 
     <!-- inventory sequencing mode for accounting preferences -->
     <EnumerationType description="Invoice Sequence Mode" 
enumTypeId="INVOICE_SEQMD" hasTable="N" parentTypeId=""/>

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=927011&r1=927010&r2=927011&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
 Wed Mar 24 11:20:53 2010
@@ -1097,71 +1097,35 @@ under the License.
             <field-map field-name="roleTypeId" value="BILL_TO_CUSTOMER"/>
         </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="unitCost"/>
-            </calcop>
-        </calculate>
-        -->
         <!-- prepare the double posting (D/C) entries (AcctgTransEntry) -->
         <!-- Credit -->
+        <!-- TODO: handle serialized inventory -->
         <set field="partyAccountingPreferencesCallMap.organizationPartyId" 
from-field="inventoryItem.ownerPartyId"/>
         <call-service service-name="getPartyAccountingPreferences" 
in-map-name="partyAccountingPreferencesCallMap">
              <result-to-field result-name="partyAccountingPreference" 
field="partyAcctgPreference"/>
         </call-service>
-        <if-compare field="partyAcctgPreference.cogsMethodId" 
operator="equals" value="COGS_FIFO" type="String">
-            <set value="+datetimeReceived" field="orderByString"/>
-        </if-compare>
-        <if-compare field="partyAcctgPreference.cogsMethodId" 
operator="equals" value="COGS_LIFO" type="String">
-            <set value="-datetimeReceived" field="orderByString"/>
-        </if-compare>
-        <if-empty field="orderByString">
-            <add-error><fail-message message="COGS costing method is not 
supported: ${partyAcctgPreference.cogsMethodId}"/></add-error>
-            <check-errors/>
-        </if-empty>
-        <entity-condition entity-name="InventoryItem" 
list="costInventoryItems">
-            <condition-list combine="and">
-                <condition-expr field-name="ownerPartyId" operator="equals" 
from-field="inventoryItem.ownerPartyId"/>
-                <condition-expr field-name="facilityId" operator="equals" 
from-field="inventoryItem.facilityId"/>
-                <condition-expr field-name="productId" operator="equals" 
from-field="inventoryItem.productId"/>
-                <condition-expr field-name="accountingQuantityTotal" 
operator="greater" value="0.0"/>
-            </condition-list>
-            <order-by field-name="${orderByString}"/>
-        </entity-condition>
-        <set field="remainingQuantity" from-field="itemIssuance.quantity"/>
         <set field="totalAmount" value="0.0" type="BigDecimal"/>
-        <iterate list="costInventoryItems" entry="costInventoryItem">
-            <if-compare field="remainingQuantity" operator="greater" 
value="0.0" type="BigDecimal">
-                <if-compare-field field="remainingQuantity" 
operator="less-equals" to-field="costInventoryItem.accountingQuantityTotal" 
type="BigDecimal">
-                    <set field="costInventoryItemQuantity" 
from-field="remainingQuantity"/>
-                    <set field="remainingQuantity" value="0.0" 
type="BigDecimal"/>
+        <if>
+            <condition>
+                <or>
+                    <if-compare field="partyAcctgPreference.cogsMethodId" 
operator="equals" value="COGS_INV_COST" type="String"/>
+                    <if-compare field="partyAcctgPreference.cogsMethodId" 
operator="equals" value="COGS_AVG_COST" type="String"/>
+                </or>
+            </condition>
+            <then>
+                <if-compare field="partyAcctgPreference.cogsMethodId" 
operator="equals" value="COGS_AVG_COST" type="String">
+                    <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="costInventoryItemQuantity" 
from-field="costInventoryItem.accountingQuantityTotal"/>
-                        <set field="remainingQuantity" 
value="${remainingQuantity - costInventoryItem.accountingQuantityTotal}" 
type="BigDecimal"/>
+                        <set field="unitCost" 
from-field="inventoryItem.unitCost"/>
                     </else>
-                </if-compare-field>
-                <!-- An inventory item detail record is created to keep track 
of the units (value) that we are going to add to the inventory account -->
-                <set from-field="costInventoryItem.inventoryItemId" 
field="createDetailMap.inventoryItemId"/>
-                <set value="${-1 * costInventoryItemQuantity}" 
field="createDetailMap.accountingQuantityDiff" type="BigDecimal"/>
-                <call-service service-name="createInventoryItemDetail" 
in-map-name="createDetailMap"/>
-
-                <calculate field="costInventoryItemAmount" 
decimal-scale="${ledgerDecimals}" rounding-mode="${roundingMode}">
-                    <calcop operator="multiply">
-                        <calcop operator="get" 
field="costInventoryItemQuantity"/>
-                        <calcop operator="get" 
field="costInventoryItem.unitCost"/>
-                    </calcop>
-                </calculate>
+                </if-compare>
                 <calculate field="totalAmount" 
decimal-scale="${ledgerDecimals}" rounding-mode="${roundingMode}">
-                    <calcop operator="sum">
-                        <calcop operator="get" 
field="costInventoryItemAmount"/>
-                        <calcop operator="get" field="totalAmount"/>
+                    <calcop operator="multiply">
+                        <calcop operator="get" field="itemIssuance.quantity"/>
+                        <calcop operator="get" field="unitCost"/>
                     </calcop>
                 </calculate>
                 <make-value entity-name="AcctgTransEntry" 
value-field="creditEntry"/>
@@ -1169,21 +1133,85 @@ under the License.
                 <set field="creditEntry.glAccountTypeId" 
value="INVENTORY_ACCOUNT"/>
                 <set field="creditEntry.organizationPartyId" 
from-field="inventoryItem.ownerPartyId"/>
                 <set field="creditEntry.productId" 
from-field="inventoryItem.productId"/>
-                <set field="creditEntry.inventoryItemId" 
from-field="costInventoryItem.inventoryItemId"/>
-                <set field="creditEntry.origAmount" 
from-field="costInventoryItemAmount"/>
+                <set field="creditEntry.inventoryItemId" 
from-field="inventoryItem.inventoryItemId"/>
+                <set field="creditEntry.origAmount" from-field="totalAmount"/>
                 <set field="creditEntry.origCurrencyUomId" 
from-field="inventoryItem.currencyUomId"/>
                 <if-not-empty field="billToCustomer">
                     <set field="creditEntry.partyId" 
from-field="billToCustomer.partyId"/>
                     <set field="creditEntry.roleTypeId" 
from-field="billToCustomer.roleTypeId"/>
                 </if-not-empty>
                 <set field="acctgTransEntries[]" from-field="creditEntry" 
type="Object"/>
-                <clear-field field="creditEntry"/>
-            </if-compare>
-        </iterate>
-        <if-compare field="remainingQuantity" operator="greater" value="0.0" 
type="BigDecimal">
-            <add-error><fail-message message="Could not find enough accounting 
inventory for product [${inventoryItem.productId}]; remaining quantity: 
${remainingQuantity}"/></add-error>
-            <check-errors/>
-        </if-compare>
+            </then>
+            <else>
+                <if-compare field="partyAcctgPreference.cogsMethodId" 
operator="equals" value="COGS_FIFO" type="String">
+                    <set value="+datetimeReceived" field="orderByString"/>
+                </if-compare>
+                <if-compare field="partyAcctgPreference.cogsMethodId" 
operator="equals" value="COGS_LIFO" type="String">
+                    <set value="-datetimeReceived" field="orderByString"/>
+                </if-compare>
+                <if-empty field="orderByString">
+                    <add-error><fail-message message="COGS costing method is 
not supported: ${partyAcctgPreference.cogsMethodId}"/></add-error>
+                    <check-errors/>
+                </if-empty>
+                <entity-condition entity-name="InventoryItem" 
list="costInventoryItems">
+                    <condition-list combine="and">
+                        <condition-expr field-name="ownerPartyId" 
operator="equals" from-field="inventoryItem.ownerPartyId"/>
+                        <condition-expr field-name="facilityId" 
operator="equals" from-field="inventoryItem.facilityId"/>
+                        <condition-expr field-name="productId" 
operator="equals" from-field="inventoryItem.productId"/>
+                        <condition-expr field-name="accountingQuantityTotal" 
operator="greater" value="0.0"/>
+                    </condition-list>
+                    <order-by field-name="${orderByString}"/>
+                </entity-condition>
+                <set field="remainingQuantity" 
from-field="itemIssuance.quantity"/>
+                <iterate list="costInventoryItems" entry="costInventoryItem">
+                    <if-compare field="remainingQuantity" operator="greater" 
value="0.0" type="BigDecimal">
+                        <if-compare-field field="remainingQuantity" 
operator="less-equals" to-field="costInventoryItem.accountingQuantityTotal" 
type="BigDecimal">
+                            <set field="costInventoryItemQuantity" 
from-field="remainingQuantity"/>
+                            <set field="remainingQuantity" value="0.0" 
type="BigDecimal"/>
+                            <else>
+                                <set field="costInventoryItemQuantity" 
from-field="costInventoryItem.accountingQuantityTotal"/>
+                                <set field="remainingQuantity" 
value="${remainingQuantity - costInventoryItem.accountingQuantityTotal}" 
type="BigDecimal"/>
+                            </else>
+                        </if-compare-field>
+                        <!-- An inventory item detail record is created to 
keep track of the units (value) that we are going to add to the inventory 
account -->
+                        <set from-field="costInventoryItem.inventoryItemId" 
field="createDetailMap.inventoryItemId"/>
+                        <set value="${-1 * costInventoryItemQuantity}" 
field="createDetailMap.accountingQuantityDiff" type="BigDecimal"/>
+                        <call-service service-name="createInventoryItemDetail" 
in-map-name="createDetailMap"/>
+
+                        <calculate field="costInventoryItemAmount" 
decimal-scale="${ledgerDecimals}" rounding-mode="${roundingMode}">
+                            <calcop operator="multiply">
+                                <calcop operator="get" 
field="costInventoryItemQuantity"/>
+                                <calcop operator="get" 
field="costInventoryItem.unitCost"/>
+                            </calcop>
+                        </calculate>
+                        <calculate field="totalAmount" 
decimal-scale="${ledgerDecimals}" rounding-mode="${roundingMode}">
+                            <calcop operator="add">
+                                <calcop operator="get" 
field="costInventoryItemAmount"/>
+                                <calcop operator="get" field="totalAmount"/>
+                            </calcop>
+                        </calculate>
+                        <make-value entity-name="AcctgTransEntry" 
value-field="creditEntry"/>
+                        <set field="creditEntry.debitCreditFlag" value="C"/>
+                        <set field="creditEntry.glAccountTypeId" 
value="INVENTORY_ACCOUNT"/>
+                        <set field="creditEntry.organizationPartyId" 
from-field="inventoryItem.ownerPartyId"/>
+                        <set field="creditEntry.productId" 
from-field="inventoryItem.productId"/>
+                        <set field="creditEntry.inventoryItemId" 
from-field="costInventoryItem.inventoryItemId"/>
+                        <set field="creditEntry.origAmount" 
from-field="costInventoryItemAmount"/>
+                        <set field="creditEntry.origCurrencyUomId" 
from-field="inventoryItem.currencyUomId"/>
+                        <if-not-empty field="billToCustomer">
+                            <set field="creditEntry.partyId" 
from-field="billToCustomer.partyId"/>
+                            <set field="creditEntry.roleTypeId" 
from-field="billToCustomer.roleTypeId"/>
+                        </if-not-empty>
+                        <set field="acctgTransEntries[]" 
from-field="creditEntry" type="Object"/>
+                        <clear-field field="creditEntry"/>
+                    </if-compare>
+                </iterate>
+                <if-compare field="remainingQuantity" operator="greater" 
value="0.0" type="BigDecimal">
+                    <add-error><fail-message message="Could not find enough 
accounting inventory for product [${inventoryItem.productId}]; remaining 
quantity: ${remainingQuantity}"/></add-error>
+                    <check-errors/>
+                </if-compare>
+            </else>
+        </if>
         <!-- Debit -->
         <make-value entity-name="AcctgTransEntry" value-field="debitEntry"/>
         <set field="debitEntry.debitCreditFlag" value="D"/>
@@ -1284,11 +1312,34 @@ under the License.
         </else>
         </if-not-empty>
         <!-- TODO: handle serialized inventory -->
+        <set field="partyAccountingPreferencesCallMap.organizationPartyId" 
from-field="inventoryItem.ownerPartyId"/>
+        <call-service service-name="getPartyAccountingPreferences" 
in-map-name="partyAccountingPreferencesCallMap">
+             <result-to-field result-name="partyAccountingPreference" 
field="partyAcctgPreference"/>
+        </call-service>
         <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>
+            <if>
+                <condition>
+                    <or>
+                        <if-compare field="partyAcctgPreference.cogsMethodId" 
operator="equals" value="COGS_INV_COST" type="String"/>
+                        <if-compare field="partyAcctgPreference.cogsMethodId" 
operator="equals" value="COGS_AVG_COST" type="String"/>
+                    </or>
+                </condition>
+                <then>
+                    <if-compare field="partyAcctgPreference.cogsMethodId" 
operator="equals" value="COGS_AVG_COST" type="String">
+                        <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-compare>
+                </then>
+                <else>
+                    <!-- LIFO and FIFO-->
+                    <set field="unitCost" from-field="inventoryItem.unitCost"/>
+                </else>
+            </if>
         <else>
             <set field="unitCost" from-field="inventoryItem.unitCost"/>
         </else>


Reply via email to