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