[costadj]Add CostAdjustment process basic implementation.
authorGorka Ion Damián <gorkaion.damian@openbravo.com>
Thu, 17 Jul 2014 12:28:37 +0200
changeset 24756 bbc815230e86
parent 24755 5d2203bb5cf7
child 24757 b56fc46c1854
[costadj]Add CostAdjustment process basic implementation.
src-db/database/model/tables/M_COSTADJUSTMENTLINE.xml
src-db/database/sourcedata/AD_COLUMN.xml
src-db/database/sourcedata/AD_FIELD.xml
src-db/database/sourcedata/AD_REFERENCE.xml
src-db/database/sourcedata/AD_REF_TABLE.xml
src-db/database/sourcedata/AD_TAB.xml
src-db/database/sourcedata/AD_TABLE.xml
src-db/database/sourcedata/AD_TABLE_TREE.xml
src/org/openbravo/costing/AverageAlgorithm.java
src/org/openbravo/costing/AverageCostAdjustment.java
src/org/openbravo/costing/CostAdjusmentProcessCheck.java
src/org/openbravo/costing/CostAdjustmentProcess.java
src/org/openbravo/costing/CostAdjustmentProcessHandler.java
src/org/openbravo/costing/CostingAlgorithm.java
src/org/openbravo/costing/CostingAlgorithmAdjustmentImp.java
src/org/openbravo/costing/CostingServer.java
src/org/openbravo/costing/ManualCostAdjustmentProcessHandler.java
--- a/src-db/database/model/tables/M_COSTADJUSTMENTLINE.xml	Thu Jul 17 12:25:10 2014 +0200
+++ b/src-db/database/model/tables/M_COSTADJUSTMENTLINE.xml	Thu Jul 17 12:28:37 2014 +0200
@@ -61,6 +61,17 @@
         <default/>
         <onCreateDefault/>
       </column>
+      <column name="ISRELATEDTRXADJUSTED" primaryKey="false" required="true" type="CHAR" size="1" autoIncrement="false">
+        <default><![CDATA[N]]></default>
+        <onCreateDefault/>
+      </column>
+      <column name="PARENT_COSTADJUSTMENTLINE_ID" primaryKey="false" required="false" type="VARCHAR" size="32" autoIncrement="false">
+        <default/>
+        <onCreateDefault/>
+      </column>
+      <foreign-key foreignTable="M_COSTADJUSTMENTLINE" name="M_COSTADJLINE_PARENTLINE">
+        <reference local="PARENT_COSTADJUSTMENTLINE_ID" foreign="M_COSTADJUSTMENTLINE_ID"/>
+      </foreign-key>
       <foreign-key foreignTable="AD_CLIENT" name="M_COSTADJUSTMENTLINE_CLIENT">
         <reference local="AD_CLIENT_ID" foreign="AD_CLIENT_ID"/>
       </foreign-key>
@@ -79,5 +90,6 @@
       <check name="M_COSTADJLINE_ACTIVE_CHK"><![CDATA[ISACTIVE IN ('Y', 'N')]]></check>
       <check name="M_COSTADJLINE_POSTING_CHK"><![CDATA[NEEDSPOSTING IN ('Y', 'N')]]></check>
       <check name="M_COSTADJLINE_SOURCE_CHK"><![CDATA[ISSOURCE IN ('Y', 'N')]]></check>
+      <check name="M_COSTADJUSTMENTLINE_RELTRXADJ"><![CDATA[ISRELATEDTRXADJUSTED IN ('Y', 'N')]]></check>
     </table>
   </database>
--- a/src-db/database/sourcedata/AD_COLUMN.xml	Thu Jul 17 12:25:10 2014 +0200
+++ b/src-db/database/sourcedata/AD_COLUMN.xml	Thu Jul 17 12:28:37 2014 +0200
@@ -329927,6 +329927,74 @@
 <!--FD3A0DB0549845F29EDCA4FC514B52AD-->  <ISUSEDSEQUENCE><![CDATA[N]]></ISUSEDSEQUENCE>
 <!--FD3A0DB0549845F29EDCA4FC514B52AD--></AD_COLUMN>
 
+<!--FD4BD9AA63ED7B3AE040007F01005BA7--><AD_COLUMN>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <AD_COLUMN_ID><![CDATA[FD4BD9AA63ED7B3AE040007F01005BA7]]></AD_COLUMN_ID>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <NAME><![CDATA[Is Related Transaction Adjusted]]></NAME>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <HELP><![CDATA[Field used by the Cost Adjustment process to label all the transaction that have been checked to search related transactions that also needs adjustment.]]></HELP>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <COLUMNNAME><![CDATA[IsRelatedTrxAdjusted]]></COLUMNNAME>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <AD_TABLE_ID><![CDATA[34E79323CEC847C2A9ED2C8430AC73D1]]></AD_TABLE_ID>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <AD_REFERENCE_ID><![CDATA[20]]></AD_REFERENCE_ID>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <FIELDLENGTH><![CDATA[1]]></FIELDLENGTH>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <DEFAULTVALUE><![CDATA[N]]></DEFAULTVALUE>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <ISKEY><![CDATA[N]]></ISKEY>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <ISPARENT><![CDATA[N]]></ISPARENT>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <ISMANDATORY><![CDATA[Y]]></ISMANDATORY>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <ISUPDATEABLE><![CDATA[Y]]></ISUPDATEABLE>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <ISIDENTIFIER><![CDATA[N]]></ISIDENTIFIER>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <SEQNO><![CDATA[160]]></SEQNO>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <ISTRANSLATED><![CDATA[N]]></ISTRANSLATED>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <ISENCRYPTED><![CDATA[N]]></ISENCRYPTED>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <ISSELECTIONCOLUMN><![CDATA[N]]></ISSELECTIONCOLUMN>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <ISSESSIONATTR><![CDATA[N]]></ISSESSIONATTR>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <ISSECONDARYKEY><![CDATA[N]]></ISSECONDARYKEY>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <ISDESENCRYPTABLE><![CDATA[N]]></ISDESENCRYPTABLE>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <DEVELOPMENTSTATUS><![CDATA[RE]]></DEVELOPMENTSTATUS>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <POSITION><![CDATA[16]]></POSITION>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <ISTRANSIENT><![CDATA[N]]></ISTRANSIENT>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <ISAUTOSAVE><![CDATA[Y]]></ISAUTOSAVE>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <VALIDATEONNEW><![CDATA[Y]]></VALIDATEONNEW>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <IMAGESIZEVALUESACTION><![CDATA[N]]></IMAGESIZEVALUESACTION>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7-->  <ISUSEDSEQUENCE><![CDATA[N]]></ISUSEDSEQUENCE>
+<!--FD4BD9AA63ED7B3AE040007F01005BA7--></AD_COLUMN>
+
+<!--FD4BD9AA63F17B3AE040007F01005BA7--><AD_COLUMN>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <AD_COLUMN_ID><![CDATA[FD4BD9AA63F17B3AE040007F01005BA7]]></AD_COLUMN_ID>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <NAME><![CDATA[Parent Cost Adjustment Line]]></NAME>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <HELP><![CDATA[References the cost adjustment line that causes the adjustment on the current transaction.]]></HELP>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <COLUMNNAME><![CDATA[Parent_Costadjustmentline_ID]]></COLUMNNAME>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <AD_TABLE_ID><![CDATA[34E79323CEC847C2A9ED2C8430AC73D1]]></AD_TABLE_ID>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <AD_REFERENCE_ID><![CDATA[18]]></AD_REFERENCE_ID>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <AD_REFERENCE_VALUE_ID><![CDATA[23AD2773FD02451DA75D1387A970CE82]]></AD_REFERENCE_VALUE_ID>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <FIELDLENGTH><![CDATA[32]]></FIELDLENGTH>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <ISKEY><![CDATA[N]]></ISKEY>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <ISPARENT><![CDATA[N]]></ISPARENT>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <ISMANDATORY><![CDATA[N]]></ISMANDATORY>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <ISUPDATEABLE><![CDATA[Y]]></ISUPDATEABLE>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <ISIDENTIFIER><![CDATA[N]]></ISIDENTIFIER>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <SEQNO><![CDATA[170]]></SEQNO>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <ISTRANSLATED><![CDATA[N]]></ISTRANSLATED>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <ISENCRYPTED><![CDATA[N]]></ISENCRYPTED>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <ISSELECTIONCOLUMN><![CDATA[N]]></ISSELECTIONCOLUMN>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <ISSESSIONATTR><![CDATA[N]]></ISSESSIONATTR>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <ISSECONDARYKEY><![CDATA[N]]></ISSECONDARYKEY>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <ISDESENCRYPTABLE><![CDATA[N]]></ISDESENCRYPTABLE>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <DEVELOPMENTSTATUS><![CDATA[RE]]></DEVELOPMENTSTATUS>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <POSITION><![CDATA[17]]></POSITION>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <ISTRANSIENT><![CDATA[N]]></ISTRANSIENT>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <ISAUTOSAVE><![CDATA[Y]]></ISAUTOSAVE>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <VALIDATEONNEW><![CDATA[Y]]></VALIDATEONNEW>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <IMAGESIZEVALUESACTION><![CDATA[N]]></IMAGESIZEVALUESACTION>
+<!--FD4BD9AA63F17B3AE040007F01005BA7-->  <ISUSEDSEQUENCE><![CDATA[N]]></ISUSEDSEQUENCE>
+<!--FD4BD9AA63F17B3AE040007F01005BA7--></AD_COLUMN>
+
 <!--FDA188A07EEB46D8A44A45943542F751--><AD_COLUMN>
 <!--FDA188A07EEB46D8A44A45943542F751-->  <AD_COLUMN_ID><![CDATA[FDA188A07EEB46D8A44A45943542F751]]></AD_COLUMN_ID>
 <!--FDA188A07EEB46D8A44A45943542F751-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-db/database/sourcedata/AD_FIELD.xml	Thu Jul 17 12:25:10 2014 +0200
+++ b/src-db/database/sourcedata/AD_FIELD.xml	Thu Jul 17 12:28:37 2014 +0200
@@ -284574,7 +284574,7 @@
 <!--FD0D66CE5B78096DE040007F010024B1-->  <ISDISPLAYED><![CDATA[Y]]></ISDISPLAYED>
 <!--FD0D66CE5B78096DE040007F010024B1-->  <DISPLAYLENGTH><![CDATA[19]]></DISPLAYLENGTH>
 <!--FD0D66CE5B78096DE040007F010024B1-->  <ISREADONLY><![CDATA[N]]></ISREADONLY>
-<!--FD0D66CE5B78096DE040007F010024B1-->  <SEQNO><![CDATA[40]]></SEQNO>
+<!--FD0D66CE5B78096DE040007F010024B1-->  <SEQNO><![CDATA[50]]></SEQNO>
 <!--FD0D66CE5B78096DE040007F010024B1-->  <ISSAMELINE><![CDATA[N]]></ISSAMELINE>
 <!--FD0D66CE5B78096DE040007F010024B1-->  <ISFIELDONLY><![CDATA[N]]></ISFIELDONLY>
 <!--FD0D66CE5B78096DE040007F010024B1-->  <ISENCRYPTED><![CDATA[N]]></ISENCRYPTED>
@@ -284655,7 +284655,7 @@
 <!--FD0D66CE5B7B096DE040007F010024B1-->  <ISDISPLAYED><![CDATA[Y]]></ISDISPLAYED>
 <!--FD0D66CE5B7B096DE040007F010024B1-->  <DISPLAYLENGTH><![CDATA[1]]></DISPLAYLENGTH>
 <!--FD0D66CE5B7B096DE040007F010024B1-->  <ISREADONLY><![CDATA[N]]></ISREADONLY>
-<!--FD0D66CE5B7B096DE040007F010024B1-->  <SEQNO><![CDATA[50]]></SEQNO>
+<!--FD0D66CE5B7B096DE040007F010024B1-->  <SEQNO><![CDATA[60]]></SEQNO>
 <!--FD0D66CE5B7B096DE040007F010024B1-->  <ISSAMELINE><![CDATA[N]]></ISSAMELINE>
 <!--FD0D66CE5B7B096DE040007F010024B1-->  <ISFIELDONLY><![CDATA[N]]></ISFIELDONLY>
 <!--FD0D66CE5B7B096DE040007F010024B1-->  <ISENCRYPTED><![CDATA[N]]></ISENCRYPTED>
@@ -284683,7 +284683,7 @@
 <!--FD0D66CE5B7C096DE040007F010024B1-->  <ISDISPLAYED><![CDATA[Y]]></ISDISPLAYED>
 <!--FD0D66CE5B7C096DE040007F010024B1-->  <DISPLAYLENGTH><![CDATA[19]]></DISPLAYLENGTH>
 <!--FD0D66CE5B7C096DE040007F010024B1-->  <ISREADONLY><![CDATA[N]]></ISREADONLY>
-<!--FD0D66CE5B7C096DE040007F010024B1-->  <SEQNO><![CDATA[60]]></SEQNO>
+<!--FD0D66CE5B7C096DE040007F010024B1-->  <SEQNO><![CDATA[70]]></SEQNO>
 <!--FD0D66CE5B7C096DE040007F010024B1-->  <ISSAMELINE><![CDATA[N]]></ISSAMELINE>
 <!--FD0D66CE5B7C096DE040007F010024B1-->  <ISFIELDONLY><![CDATA[N]]></ISFIELDONLY>
 <!--FD0D66CE5B7C096DE040007F010024B1-->  <ISENCRYPTED><![CDATA[N]]></ISENCRYPTED>
@@ -284724,6 +284724,60 @@
 <!--FD339410474C47CEBEC6D4071EF8FB4A-->  <EM_OBUIAPP_SHOWSUMMARY><![CDATA[N]]></EM_OBUIAPP_SHOWSUMMARY>
 <!--FD339410474C47CEBEC6D4071EF8FB4A--></AD_FIELD>
 
+<!--FD4BD9AA640C7B3AE040007F01005BA7--><AD_FIELD>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <AD_FIELD_ID><![CDATA[FD4BD9AA640C7B3AE040007F01005BA7]]></AD_FIELD_ID>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <NAME><![CDATA[Is Related Transaction Adjusted]]></NAME>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <HELP><![CDATA[Field used by the Cost Adjustment process to label all the transaction that have been checked to search related transactions that also needs adjustment.]]></HELP>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <ISCENTRALLYMAINTAINED><![CDATA[Y]]></ISCENTRALLYMAINTAINED>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <AD_TAB_ID><![CDATA[06DCB72BB6D24F82BCDA5FFF8EA0425C]]></AD_TAB_ID>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <AD_COLUMN_ID><![CDATA[FD4BD9AA63ED7B3AE040007F01005BA7]]></AD_COLUMN_ID>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <IGNOREINWAD><![CDATA[N]]></IGNOREINWAD>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <ISDISPLAYED><![CDATA[N]]></ISDISPLAYED>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <DISPLAYLENGTH><![CDATA[1]]></DISPLAYLENGTH>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <ISREADONLY><![CDATA[N]]></ISREADONLY>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <SEQNO><![CDATA[80]]></SEQNO>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <ISSAMELINE><![CDATA[N]]></ISSAMELINE>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <ISFIELDONLY><![CDATA[N]]></ISFIELDONLY>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <ISENCRYPTED><![CDATA[N]]></ISENCRYPTED>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <SHOWINRELATION><![CDATA[N]]></SHOWINRELATION>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <ISFIRSTFOCUSEDFIELD><![CDATA[N]]></ISFIRSTFOCUSEDFIELD>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <STARTINODDCOLUMN><![CDATA[N]]></STARTINODDCOLUMN>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <STARTNEWLINE><![CDATA[N]]></STARTNEWLINE>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <ISSHOWNINSTATUSBAR><![CDATA[N]]></ISSHOWNINSTATUSBAR>
+<!--FD4BD9AA640C7B3AE040007F01005BA7-->  <EM_OBUIAPP_SHOWSUMMARY><![CDATA[N]]></EM_OBUIAPP_SHOWSUMMARY>
+<!--FD4BD9AA640C7B3AE040007F01005BA7--></AD_FIELD>
+
+<!--FD4BD9AA640D7B3AE040007F01005BA7--><AD_FIELD>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <AD_FIELD_ID><![CDATA[FD4BD9AA640D7B3AE040007F01005BA7]]></AD_FIELD_ID>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <NAME><![CDATA[Parent Cost Adjustment Line]]></NAME>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <HELP><![CDATA[References the cost adjustment line that causes the adjustment on the current transaction.]]></HELP>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <ISCENTRALLYMAINTAINED><![CDATA[Y]]></ISCENTRALLYMAINTAINED>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <AD_TAB_ID><![CDATA[06DCB72BB6D24F82BCDA5FFF8EA0425C]]></AD_TAB_ID>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <AD_COLUMN_ID><![CDATA[FD4BD9AA63F17B3AE040007F01005BA7]]></AD_COLUMN_ID>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <IGNOREINWAD><![CDATA[N]]></IGNOREINWAD>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <ISDISPLAYED><![CDATA[Y]]></ISDISPLAYED>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <DISPLAYLENGTH><![CDATA[32]]></DISPLAYLENGTH>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <ISREADONLY><![CDATA[N]]></ISREADONLY>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <SEQNO><![CDATA[40]]></SEQNO>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <ISSAMELINE><![CDATA[N]]></ISSAMELINE>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <ISFIELDONLY><![CDATA[N]]></ISFIELDONLY>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <ISENCRYPTED><![CDATA[N]]></ISENCRYPTED>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <SHOWINRELATION><![CDATA[Y]]></SHOWINRELATION>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <ISFIRSTFOCUSEDFIELD><![CDATA[N]]></ISFIRSTFOCUSEDFIELD>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <STARTINODDCOLUMN><![CDATA[N]]></STARTINODDCOLUMN>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <STARTNEWLINE><![CDATA[N]]></STARTNEWLINE>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <ISSHOWNINSTATUSBAR><![CDATA[N]]></ISSHOWNINSTATUSBAR>
+<!--FD4BD9AA640D7B3AE040007F01005BA7-->  <EM_OBUIAPP_SHOWSUMMARY><![CDATA[N]]></EM_OBUIAPP_SHOWSUMMARY>
+<!--FD4BD9AA640D7B3AE040007F01005BA7--></AD_FIELD>
+
 <!--FD9A7BECCEF146DF974108248D63BDBE--><AD_FIELD>
 <!--FD9A7BECCEF146DF974108248D63BDBE-->  <AD_FIELD_ID><![CDATA[FD9A7BECCEF146DF974108248D63BDBE]]></AD_FIELD_ID>
 <!--FD9A7BECCEF146DF974108248D63BDBE-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-db/database/sourcedata/AD_REFERENCE.xml	Thu Jul 17 12:25:10 2014 +0200
+++ b/src-db/database/sourcedata/AD_REFERENCE.xml	Thu Jul 17 12:28:37 2014 +0200
@@ -4491,6 +4491,18 @@
 <!--22F546D49D3A48E1B2B4F50446A8DE58-->  <ISVALUEDISPLAYED><![CDATA[N]]></ISVALUEDISPLAYED>
 <!--22F546D49D3A48E1B2B4F50446A8DE58--></AD_REFERENCE>
 
+<!--23AD2773FD02451DA75D1387A970CE82--><AD_REFERENCE>
+<!--23AD2773FD02451DA75D1387A970CE82-->  <AD_REFERENCE_ID><![CDATA[23AD2773FD02451DA75D1387A970CE82]]></AD_REFERENCE_ID>
+<!--23AD2773FD02451DA75D1387A970CE82-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--23AD2773FD02451DA75D1387A970CE82-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--23AD2773FD02451DA75D1387A970CE82-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--23AD2773FD02451DA75D1387A970CE82-->  <NAME><![CDATA[M_CostAdjustmentLine]]></NAME>
+<!--23AD2773FD02451DA75D1387A970CE82-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--23AD2773FD02451DA75D1387A970CE82-->  <ISBASEREFERENCE><![CDATA[N]]></ISBASEREFERENCE>
+<!--23AD2773FD02451DA75D1387A970CE82-->  <PARENTREFERENCE_ID><![CDATA[18]]></PARENTREFERENCE_ID>
+<!--23AD2773FD02451DA75D1387A970CE82-->  <ISVALUEDISPLAYED><![CDATA[N]]></ISVALUEDISPLAYED>
+<!--23AD2773FD02451DA75D1387A970CE82--></AD_REFERENCE>
+
 <!--25400A74C902418B815D70EFDCD29153--><AD_REFERENCE>
 <!--25400A74C902418B815D70EFDCD29153-->  <AD_REFERENCE_ID><![CDATA[25400A74C902418B815D70EFDCD29153]]></AD_REFERENCE_ID>
 <!--25400A74C902418B815D70EFDCD29153-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-db/database/sourcedata/AD_REF_TABLE.xml	Thu Jul 17 12:25:10 2014 +0200
+++ b/src-db/database/sourcedata/AD_REF_TABLE.xml	Thu Jul 17 12:28:37 2014 +0200
@@ -1159,6 +1159,17 @@
 <!--22F546D49D3A48E1B2B4F50446A8DE58-->  <ORDERBYCLAUSE><![CDATA[C_DocType.isdefault DESC, C_DocType.Name]]></ORDERBYCLAUSE>
 <!--22F546D49D3A48E1B2B4F50446A8DE58--></AD_REF_TABLE>
 
+<!--23AD2773FD02451DA75D1387A970CE82--><AD_REF_TABLE>
+<!--23AD2773FD02451DA75D1387A970CE82-->  <AD_REFERENCE_ID><![CDATA[23AD2773FD02451DA75D1387A970CE82]]></AD_REFERENCE_ID>
+<!--23AD2773FD02451DA75D1387A970CE82-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--23AD2773FD02451DA75D1387A970CE82-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--23AD2773FD02451DA75D1387A970CE82-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--23AD2773FD02451DA75D1387A970CE82-->  <AD_TABLE_ID><![CDATA[34E79323CEC847C2A9ED2C8430AC73D1]]></AD_TABLE_ID>
+<!--23AD2773FD02451DA75D1387A970CE82-->  <AD_KEY><![CDATA[FD0CA136DD4B9858E040007F01001C35]]></AD_KEY>
+<!--23AD2773FD02451DA75D1387A970CE82-->  <AD_DISPLAY><![CDATA[FD0CA136DD4C9858E040007F01001C35]]></AD_DISPLAY>
+<!--23AD2773FD02451DA75D1387A970CE82-->  <ISVALUEDISPLAYED><![CDATA[N]]></ISVALUEDISPLAYED>
+<!--23AD2773FD02451DA75D1387A970CE82--></AD_REF_TABLE>
+
 <!--2F57E5B5EBF44E0A9D45492DECBD3CC1--><AD_REF_TABLE>
 <!--2F57E5B5EBF44E0A9D45492DECBD3CC1-->  <AD_REFERENCE_ID><![CDATA[2F57E5B5EBF44E0A9D45492DECBD3CC1]]></AD_REFERENCE_ID>
 <!--2F57E5B5EBF44E0A9D45492DECBD3CC1-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-db/database/sourcedata/AD_TAB.xml	Thu Jul 17 12:25:10 2014 +0200
+++ b/src-db/database/sourcedata/AD_TAB.xml	Thu Jul 17 12:28:37 2014 +0200
@@ -13264,12 +13264,12 @@
 <!--06DCB72BB6D24F82BCDA5FFF8EA0425C-->  <ISINFOTAB><![CDATA[N]]></ISINFOTAB>
 <!--06DCB72BB6D24F82BCDA5FFF8EA0425C-->  <ISTRANSLATIONTAB><![CDATA[N]]></ISTRANSLATIONTAB>
 <!--06DCB72BB6D24F82BCDA5FFF8EA0425C-->  <ISREADONLY><![CDATA[N]]></ISREADONLY>
-<!--06DCB72BB6D24F82BCDA5FFF8EA0425C-->  <HASTREE><![CDATA[N]]></HASTREE>
+<!--06DCB72BB6D24F82BCDA5FFF8EA0425C-->  <HASTREE><![CDATA[Y]]></HASTREE>
 <!--06DCB72BB6D24F82BCDA5FFF8EA0425C-->  <PROCESSING><![CDATA[N]]></PROCESSING>
 <!--06DCB72BB6D24F82BCDA5FFF8EA0425C-->  <IMPORTFIELDS><![CDATA[N]]></IMPORTFIELDS>
 <!--06DCB72BB6D24F82BCDA5FFF8EA0425C-->  <ISSORTTAB><![CDATA[N]]></ISSORTTAB>
 <!--06DCB72BB6D24F82BCDA5FFF8EA0425C-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
-<!--06DCB72BB6D24F82BCDA5FFF8EA0425C-->  <UIPATTERN><![CDATA[STD]]></UIPATTERN>
+<!--06DCB72BB6D24F82BCDA5FFF8EA0425C-->  <UIPATTERN><![CDATA[SR]]></UIPATTERN>
 <!--06DCB72BB6D24F82BCDA5FFF8EA0425C-->  <SHOWPARENTBUTTONS><![CDATA[Y]]></SHOWPARENTBUTTONS>
 <!--06DCB72BB6D24F82BCDA5FFF8EA0425C-->  <DISABLE_PARENT_KEY_PROPERTY><![CDATA[N]]></DISABLE_PARENT_KEY_PROPERTY>
 <!--06DCB72BB6D24F82BCDA5FFF8EA0425C-->  <ISREADONLYTREE><![CDATA[N]]></ISREADONLYTREE>
--- a/src-db/database/sourcedata/AD_TABLE.xml	Thu Jul 17 12:25:10 2014 +0200
+++ b/src-db/database/sourcedata/AD_TABLE.xml	Thu Jul 17 12:28:37 2014 +0200
@@ -9475,6 +9475,7 @@
 <!--34E79323CEC847C2A9ED2C8430AC73D1-->  <CLASSNAME><![CDATA[CostAdjustmentLine]]></CLASSNAME>
 <!--34E79323CEC847C2A9ED2C8430AC73D1-->  <ISVIEW><![CDATA[N]]></ISVIEW>
 <!--34E79323CEC847C2A9ED2C8430AC73D1-->  <ACCESSLEVEL><![CDATA[1]]></ACCESSLEVEL>
+<!--34E79323CEC847C2A9ED2C8430AC73D1-->  <AD_WINDOW_ID><![CDATA[1688A758BDA04C88A5C1D370EB979C53]]></AD_WINDOW_ID>
 <!--34E79323CEC847C2A9ED2C8430AC73D1-->  <ISSECURITYENABLED><![CDATA[N]]></ISSECURITYENABLED>
 <!--34E79323CEC847C2A9ED2C8430AC73D1-->  <ISDELETEABLE><![CDATA[Y]]></ISDELETEABLE>
 <!--34E79323CEC847C2A9ED2C8430AC73D1-->  <ISHIGHVOLUME><![CDATA[N]]></ISHIGHVOLUME>
@@ -9484,7 +9485,7 @@
 <!--34E79323CEC847C2A9ED2C8430AC73D1-->  <DEVELOPMENTSTATUS><![CDATA[RE]]></DEVELOPMENTSTATUS>
 <!--34E79323CEC847C2A9ED2C8430AC73D1-->  <AD_PACKAGE_ID><![CDATA[5A3ED54AB1EF4B84E040007F01006125]]></AD_PACKAGE_ID>
 <!--34E79323CEC847C2A9ED2C8430AC73D1-->  <DATAORIGINTYPE><![CDATA[Table]]></DATAORIGINTYPE>
-<!--34E79323CEC847C2A9ED2C8430AC73D1-->  <ISTREE><![CDATA[N]]></ISTREE>
+<!--34E79323CEC847C2A9ED2C8430AC73D1-->  <ISTREE><![CDATA[Y]]></ISTREE>
 <!--34E79323CEC847C2A9ED2C8430AC73D1--></AD_TABLE>
 
 <!--359738C46111461EA0CA2A13E5709519--><AD_TABLE>
@@ -11530,6 +11531,7 @@
 <!--D022B92163074E5E82449C8E0B5AFDF6-->  <CLASSNAME><![CDATA[CostAdjustment]]></CLASSNAME>
 <!--D022B92163074E5E82449C8E0B5AFDF6-->  <ISVIEW><![CDATA[N]]></ISVIEW>
 <!--D022B92163074E5E82449C8E0B5AFDF6-->  <ACCESSLEVEL><![CDATA[1]]></ACCESSLEVEL>
+<!--D022B92163074E5E82449C8E0B5AFDF6-->  <AD_WINDOW_ID><![CDATA[1688A758BDA04C88A5C1D370EB979C53]]></AD_WINDOW_ID>
 <!--D022B92163074E5E82449C8E0B5AFDF6-->  <ISSECURITYENABLED><![CDATA[N]]></ISSECURITYENABLED>
 <!--D022B92163074E5E82449C8E0B5AFDF6-->  <ISDELETEABLE><![CDATA[Y]]></ISDELETEABLE>
 <!--D022B92163074E5E82449C8E0B5AFDF6-->  <ISHIGHVOLUME><![CDATA[N]]></ISHIGHVOLUME>
--- a/src-db/database/sourcedata/AD_TABLE_TREE.xml	Thu Jul 17 12:25:10 2014 +0200
+++ b/src-db/database/sourcedata/AD_TABLE_TREE.xml	Thu Jul 17 12:28:37 2014 +0200
@@ -19,6 +19,26 @@
 <!--21E9F7EED1F24E95B0F4F21CF87AF995-->  <NODEDELETIONPOLICY><![CDATA[RCN]]></NODEDELETIONPOLICY>
 <!--21E9F7EED1F24E95B0F4F21CF87AF995--></AD_TABLE_TREE>
 
+<!--3F611D8CE181477698F568E21CE1960C--><AD_TABLE_TREE>
+<!--3F611D8CE181477698F568E21CE1960C-->  <AD_TABLE_TREE_ID><![CDATA[3F611D8CE181477698F568E21CE1960C]]></AD_TABLE_TREE_ID>
+<!--3F611D8CE181477698F568E21CE1960C-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--3F611D8CE181477698F568E21CE1960C-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--3F611D8CE181477698F568E21CE1960C-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--3F611D8CE181477698F568E21CE1960C-->  <AD_TABLE_ID><![CDATA[34E79323CEC847C2A9ED2C8430AC73D1]]></AD_TABLE_ID>
+<!--3F611D8CE181477698F568E21CE1960C-->  <LINKTOPARENTCOLUMN><![CDATA[FD4BD9AA63F17B3AE040007F01005BA7]]></LINKTOPARENTCOLUMN>
+<!--3F611D8CE181477698F568E21CE1960C-->  <NODEIDCOLUMN><![CDATA[FD0CA136DD439858E040007F01001C35]]></NODEIDCOLUMN>
+<!--3F611D8CE181477698F568E21CE1960C-->  <HASMULTIPARENTNODES><![CDATA[N]]></HASMULTIPARENTNODES>
+<!--3F611D8CE181477698F568E21CE1960C-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--3F611D8CE181477698F568E21CE1960C-->  <APPLYWHERECLAUSETOCHILDNODES><![CDATA[Y]]></APPLYWHERECLAUSETOCHILDNODES>
+<!--3F611D8CE181477698F568E21CE1960C-->  <NAME><![CDATA[Cost Adjustment Line]]></NAME>
+<!--3F611D8CE181477698F568E21CE1960C-->  <ISPARENTSELECTIONALLOWED><![CDATA[Y]]></ISPARENTSELECTIONALLOWED>
+<!--3F611D8CE181477698F568E21CE1960C-->  <ISORDERED><![CDATA[N]]></ISORDERED>
+<!--3F611D8CE181477698F568E21CE1960C-->  <TREESTRUCTURE><![CDATA[LinkToParent]]></TREESTRUCTURE>
+<!--3F611D8CE181477698F568E21CE1960C-->  <ISHANDLENODESMANUALLY><![CDATA[N]]></ISHANDLENODESMANUALLY>
+<!--3F611D8CE181477698F568E21CE1960C-->  <ISMAINTREE><![CDATA[Y]]></ISMAINTREE>
+<!--3F611D8CE181477698F568E21CE1960C-->  <NODEDELETIONPOLICY><![CDATA[DNAIHC]]></NODEDELETIONPOLICY>
+<!--3F611D8CE181477698F568E21CE1960C--></AD_TABLE_TREE>
+
 <!--50741E7509994C5C8F764A18FA77CCE3--><AD_TABLE_TREE>
 <!--50741E7509994C5C8F764A18FA77CCE3-->  <AD_TABLE_TREE_ID><![CDATA[50741E7509994C5C8F764A18FA77CCE3]]></AD_TABLE_TREE_ID>
 <!--50741E7509994C5C8F764A18FA77CCE3-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src/org/openbravo/costing/AverageAlgorithm.java	Thu Jul 17 12:25:10 2014 +0200
+++ b/src/org/openbravo/costing/AverageAlgorithm.java	Thu Jul 17 12:28:37 2014 +0200
@@ -23,10 +23,12 @@
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
 
 import org.openbravo.base.exception.OBException;
 import org.openbravo.base.provider.OBProvider;
+import org.openbravo.base.structure.BaseOBObject;
 import org.openbravo.costing.CostingServer.TrxType;
 import org.openbravo.dal.service.OBDal;
 import org.openbravo.dal.service.OBQuery;
@@ -43,18 +45,7 @@
     BigDecimal trxCost = super.getTransactionCost();
     // If it is a transaction whose cost has not been calculated based on current average cost
     // calculate new average cost.
-    switch (trxType) {
-    case Receipt:
-    case ReceiptVoid:
-    case ShipmentVoid:
-    case ShipmentReturn:
-    case ShipmentNegative:
-    case InventoryIncrease:
-    case IntMovementTo:
-    case InternalConsNegative:
-    case InternalConsVoid:
-    case BOMProduct:
-    case ManufacturingProduced:
+    if (modifiesAverage(trxType)) {
       Costing currentCosting = getProductCost();
       BigDecimal trxCostWithSign = (transaction.getMovementQuantity().signum() == -1) ? trxCost
           .negate() : trxCost;
@@ -83,8 +74,6 @@
       }
       insertCost(currentCosting, newCost, currentStock, trxCostWithSign);
 
-    default:
-      break;
     }
     return trxCost;
   }
@@ -205,8 +194,12 @@
   }
 
   private Costing getProductCost() {
-    Product product = transaction.getProduct();
-    Date date = transaction.getTransactionProcessDate();
+    return getProductCost(transaction.getTransactionProcessDate(), transaction.getProduct(),
+        costDimensions, costOrg);
+  }
+
+  protected static Costing getProductCost(Date date, Product product,
+      HashMap<CostDimension, BaseOBObject> costDimensions, Organization costOrg) {
     StringBuffer where = new StringBuffer();
     where.append(Costing.PROPERTY_PRODUCT + ".id = :product");
     where.append("  and " + Costing.PROPERTY_STARTINGDATE + " <= :startingDate");
@@ -262,4 +255,23 @@
     }
   }
 
+  protected static boolean modifiesAverage(TrxType trxType) {
+    switch (trxType) {
+    case Receipt:
+    case ReceiptVoid:
+    case ShipmentVoid:
+    case ShipmentReturn:
+    case ShipmentNegative:
+    case InventoryIncrease:
+    case IntMovementTo:
+    case InternalConsNegative:
+    case InternalConsVoid:
+    case BOMProduct:
+    case ManufacturingProduced:
+      return true;
+    default:
+      return false;
+    }
+  }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openbravo/costing/AverageCostAdjustment.java	Thu Jul 17 12:28:37 2014 +0200
@@ -0,0 +1,369 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.0  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License.
+ * The Original Code is Openbravo ERP.
+ * The Initial Developer of the Original Code is Openbravo SLU
+ * All portions are Copyright (C) 2014 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ *************************************************************************
+ */
+package org.openbravo.costing;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+
+import org.hibernate.Query;
+import org.hibernate.ScrollMode;
+import org.hibernate.ScrollableResults;
+import org.openbravo.base.session.OBPropertiesProvider;
+import org.openbravo.base.structure.BaseOBObject;
+import org.openbravo.client.kernel.ComponentProvider;
+import org.openbravo.costing.CostingAlgorithm.CostDimension;
+import org.openbravo.costing.CostingServer.TrxType;
+import org.openbravo.dal.core.OBContext;
+import org.openbravo.dal.security.OrganizationStructureProvider;
+import org.openbravo.dal.service.OBDal;
+import org.openbravo.dal.service.OBQuery;
+import org.openbravo.financial.FinancialUtils;
+import org.openbravo.model.common.currency.Currency;
+import org.openbravo.model.common.enterprise.Locator;
+import org.openbravo.model.common.enterprise.Organization;
+import org.openbravo.model.common.enterprise.Warehouse;
+import org.openbravo.model.common.plm.Product;
+import org.openbravo.model.materialmgmt.cost.CostAdjustment;
+import org.openbravo.model.materialmgmt.cost.CostAdjustmentLine;
+import org.openbravo.model.materialmgmt.cost.Costing;
+import org.openbravo.model.materialmgmt.cost.CostingRule;
+import org.openbravo.model.materialmgmt.cost.TransactionCost;
+import org.openbravo.model.materialmgmt.transaction.MaterialTransaction;
+import org.openbravo.model.materialmgmt.transaction.ShipmentInOut;
+import org.openbravo.model.materialmgmt.transaction.ShipmentInOutLine;
+
+@ComponentProvider.Qualifier("B069080A0AE149A79CF1FA0E24F16AB6")
+public class AverageCostAdjustment extends CostingAlgorithmAdjustmentImp {
+
+  @Override
+  void getRelatedTransactionsByAlgorithm() {
+    // Search all transactions after the date of the adjusted line and recalculate the costs of them
+    // to adjust differences
+    MaterialTransaction basetrx = getTransaction();
+    // Transactions of closing inventories are managed by generic CostAdjustmentProcess adjusting
+    // the cost of the related opening inventory.
+    if (basetrx.getPhysicalInventoryLine() != null
+        && basetrx.getPhysicalInventoryLine().getRelatedInventory() != null) {
+      return;
+    }
+    BigDecimal adjustmentBalance = getCostAdjLine().getAdjustmentAmount();
+    Costing costing = AverageAlgorithm.getProductCost(getCostAdjLine().getTransactionDate(),
+        basetrx.getProduct(), getCostDimensions(), getCostOrg());
+    BigDecimal cost = costing.getCost();
+    int precission = getCostCurrency().getCostingPrecision().intValue();
+
+    BigDecimal currentStock = getCurrentStock();
+    BigDecimal currentValueAmt = getCurrentValuedStock();
+    if (AverageAlgorithm.modifiesAverage(trxType) && currentStock.signum() != 0) {
+      cost = currentValueAmt.add(adjustmentBalance).divide(currentStock, precission,
+          RoundingMode.HALF_UP);
+    }
+    ScrollableResults trxs = getRelatedTransactions();
+    try {
+      while (trxs.next()) {
+        MaterialTransaction trx = (MaterialTransaction) trxs.get()[0];
+
+        TrxType currentTrxType = TrxType.getTrxType(trx);
+        // Transactions of voided documents do not need adjustment
+        switch (currentTrxType) {
+        case ReceiptVoid:
+        case ShipmentVoid:
+        case InternalConsVoid:
+          continue;
+        case Receipt:
+        case ReceiptNegative:
+        case ReceiptReturn:
+        case Shipment:
+        case ShipmentNegative:
+        case ShipmentReturn:
+          if (trx.getGoodsShipmentLine().getShipmentReceipt().getDocumentStatus().equals("VO")) {
+            continue;
+          }
+          break;
+        case InternalCons:
+        case InternalConsNegative:
+          if (trx.getInternalConsumptionLine().getInternalConsumption().getStatus().equals("VO")) {
+            continue;
+          }
+          break;
+        default:
+          break;
+        }
+
+        BigDecimal trxCost = getTrxCost(trx);
+        currentValueAmt = currentValueAmt.add(trxCost);
+        currentStock = currentStock.add(trx.getMovementQuantity());
+        // FIXME: Also check decreasing inventories with custom cost.
+        if (AverageAlgorithm.modifiesAverage(currentTrxType)) {
+          // Recalculate average, if current stock is zero the average is not modified
+          if (currentStock.signum() != 0) {
+            cost = currentValueAmt.add(adjustmentBalance).divide(currentStock, precission,
+                RoundingMode.HALF_UP);
+          }
+          Costing curCosting = trx.getMaterialMgmtCostingList().get(0);
+          if (curCosting.getCost().compareTo(cost) == 0) {
+            // new cost hasn't changed, following transactions will have the same cost, so no more
+            // related transactions are needed to include.
+            return;
+          }
+        } else if (!trx.isManualcostadjustment()) {
+          // Check current trx cost matches new expected cost
+          BigDecimal expectedCost = cost.multiply(trx.getMovementQuantity().abs());
+          if (expectedCost.compareTo(trxCost) != 0) {
+            // If there is a difference insert a cost adjustment line.
+            CostAdjustmentLine newCAL = CostAdjustmentUtils.insertCostAdjustmentLine(trx,
+                getCostAdjLine().getCostAdjustment(), expectedCost.subtract(trxCost), false,
+                trx.getTransactionProcessDate(), null);
+            newCAL.setRelatedTransactionAdjusted(false);
+          }
+        }
+
+        OBDal.getInstance().flush();
+        OBDal.getInstance().getSession().clear();
+      }
+    } finally {
+      trxs.close();
+    }
+  }
+
+  private BigDecimal getTrxCost(MaterialTransaction trx) {
+    StringBuffer select = new StringBuffer();
+    select.append("select sum(cal." + CostAdjustmentLine.PROPERTY_ADJUSTMENTAMOUNT + ") as cost");
+    select.append(" from " + CostAdjustmentLine.ENTITY_NAME + " as cal");
+    select.append("   join cal." + CostAdjustmentLine.PROPERTY_COSTADJUSTMENT + " as ca");
+    select.append(" where cal." + CostAdjustmentLine.PROPERTY_INVENTORYTRANSACTION + ".id = :trx");
+    // Get amounts of processed adjustments and the adjustment that it is being processed.
+    select.append("   and (ca = :ca");
+    select.append("     or ca." + CostAdjustment.PROPERTY_PROCESSED + " = true)");
+    // TODO: Add filter to consider only costs based on the algorithm (avoid landed cost)
+
+    Query qryCost = OBDal.getInstance().getSession().createQuery(select.toString());
+    qryCost.setParameter("trx", strTransactionId);
+    qryCost.setParameter("ca", getCostAdjLine().getCostAdjustment());
+
+    Object adjCost = qryCost.uniqueResult();
+    BigDecimal cost = trx.getTransactionCost();
+    if (adjCost != null) {
+      cost = cost.add((BigDecimal) adjCost);
+    }
+    return cost;
+  }
+
+  @Override
+  BigDecimal getOutgoingBackdatedTrxAdjAmt() {
+    // Calculate the average cost on the transaction's movement date and adjust the cost if needed.
+    MaterialTransaction trx = getTransaction();
+    CostAdjustmentLine costAdjLine = getCostAdjLine();
+    Costing costing = AverageAlgorithm.getProductCost(costAdjLine.getTransactionDate(),
+        trx.getProduct(), getCostDimensions(), getCostOrg());
+    BigDecimal cost = costing.getCost();
+    Currency costCurrency = getCostCurrency();
+    if (costing.getCurrency() != costCurrency) {
+      cost = FinancialUtils.getConvertedAmount(costing.getCost(), costing.getCurrency(),
+          costCurrency, trx.getTransactionProcessDate(), getCostOrg(),
+          FinancialUtils.PRECISION_COSTING);
+    }
+    BigDecimal expectedCostAmt = trx.getMovementQuantity().abs().multiply(cost);
+    BigDecimal currentCost = trx.getTransactionCost();
+    return expectedCostAmt.subtract(currentCost);
+  }
+
+  private ScrollableResults getRelatedTransactions() {
+    CostingRule costingRule = getCostingRule();
+    OrganizationStructureProvider osp = OBContext.getOBContext().getOrganizationStructureProvider(
+        costingRule.getClient().getId());
+    Set<String> orgs = osp.getChildTree(strCostOrgId, true);
+    HashMap<CostDimension, BaseOBObject> costDimensions = getCostDimensions();
+    Warehouse warehouse = (Warehouse) costDimensions.get(CostDimension.Warehouse);
+    MaterialTransaction trx = getTransaction();
+
+    StringBuffer where = new StringBuffer();
+    where.append(" as trx");
+    where.append(" join trx." + Product.PROPERTY_ORGANIZATION + " as org");
+    where.append(" join trx." + Product.PROPERTY_STORAGEBIN + " as loc");
+    where.append(" where trx." + MaterialTransaction.PROPERTY_ISCOSTCALCULATED + " = true");
+    where.append("  and trx." + MaterialTransaction.PROPERTY_PRODUCT + " = :product");
+    // Consider only transactions with movement date equal or later than the movement date of the
+    // adjusted transaction. But for transactions with the same movement date only those with a
+    // transaction date after the process date of the adjusted transaction.
+    where.append("  and (trx." + MaterialTransaction.PROPERTY_MOVEMENTDATE + " > :mvtdate");
+    where.append("    or (trx." + MaterialTransaction.PROPERTY_MOVEMENTDATE + " = :mvtdate");
+    where.append("  and trx." + MaterialTransaction.PROPERTY_TRANSACTIONPROCESSDATE
+        + " > :trxdate ))");
+    if (costingRule.getEndingDate() != null) {
+      where.append("  and trx." + MaterialTransaction.PROPERTY_TRANSACTIONPROCESSDATE
+          + " <= :enddate");
+    }
+    where.append("  and org.id in (:orgs)");
+    if (warehouse != null) {
+      where.append("  and loc." + Locator.PROPERTY_WAREHOUSE + " = :warehouse");
+    }
+    where.append(" order by trx." + MaterialTransaction.PROPERTY_MOVEMENTDATE);
+    where.append("   , trx." + MaterialTransaction.PROPERTY_TRANSACTIONPROCESSDATE);
+    where.append("   , trx." + MaterialTransaction.PROPERTY_MOVEMENTLINE);
+    // This makes M- to go before M+. In Oracle it must go with desc as if not, M+ would go before
+    // M-.
+    if (OBPropertiesProvider.getInstance().getOpenbravoProperties().getProperty("bbdd.rdbms")
+        .equalsIgnoreCase("oracle")) {
+      where.append("   , trx." + MaterialTransaction.PROPERTY_MOVEMENTTYPE + " desc ");
+    } else {
+      where.append("   , trx." + MaterialTransaction.PROPERTY_MOVEMENTTYPE);
+    }
+    OBQuery<MaterialTransaction> trxQry = OBDal.getInstance().createQuery(
+        MaterialTransaction.class, where.toString());
+    trxQry.setFilterOnReadableOrganization(false);
+    trxQry.setNamedParameter("mvtdate", trx.getMovementDate());
+    trxQry.setNamedParameter("trxdate", trx.getTransactionProcessDate());
+    if (costingRule.getEndingDate() != null) {
+      trxQry.setNamedParameter("enddate", costingRule.getEndingDate());
+    }
+    trxQry.setNamedParameter("orgs", orgs);
+    trxQry.setNamedParameter("product", trx.getProduct());
+    if (warehouse != null) {
+      trxQry.setNamedParameter("warehouse", warehouse);
+    }
+
+    return trxQry.scroll(ScrollMode.FORWARD_ONLY);
+  }
+
+  /**
+   * Calculates the stock of the product on the given date and for the given cost dimensions. It
+   * only takes transactions that have its cost calculated.
+   */
+  private BigDecimal getCurrentStock() {
+    // Get child tree of organizations.
+    Set<String> orgs = OBContext.getOBContext().getOrganizationStructureProvider()
+        .getChildTree(strCostOrgId, true);
+    HashMap<CostDimension, BaseOBObject> costDimensions = getCostDimensions();
+    MaterialTransaction trx = getTransaction();
+
+    StringBuffer select = new StringBuffer();
+    select
+        .append(" select sum(trx." + MaterialTransaction.PROPERTY_MOVEMENTQUANTITY + ") as stock");
+    select.append(" from " + MaterialTransaction.ENTITY_NAME + " as trx");
+    select.append("   join trx." + MaterialTransaction.PROPERTY_STORAGEBIN + " as locator");
+    select.append(" where trx." + MaterialTransaction.PROPERTY_PRODUCT + " = :product");
+    // Include only transactions that have its cost calculated. Should be all.
+    select.append("   and trx." + MaterialTransaction.PROPERTY_ISCOSTCALCULATED + " = true");
+    // Consider only transactions with movement date equal or lower than the movement date of the
+    // adjusted transaction. But for transactions with the same movement date only those with a
+    // transaction date equal or before the process date of the adjusted transaction.
+    select.append("   and (trx." + MaterialTransaction.PROPERTY_MOVEMENTDATE + " < :mvtdate");
+    select.append("     or (trx." + MaterialTransaction.PROPERTY_MOVEMENTDATE + " = :mvtdate");
+    select.append("   and trx." + MaterialTransaction.PROPERTY_TRANSACTIONPROCESSDATE
+        + " <= :trxdate ))");
+    if (costDimensions.get(CostDimension.Warehouse) != null) {
+      select.append("  and locator." + Locator.PROPERTY_WAREHOUSE + ".id = :warehouse");
+    }
+    select.append("   and trx." + MaterialTransaction.PROPERTY_ORGANIZATION + ".id in (:orgs)");
+    Query trxQry = OBDal.getInstance().getSession().createQuery(select.toString());
+    trxQry.setParameter("product", trx.getProduct());
+    trxQry.setParameter("mvtdate", trx.getMovementDate());
+    trxQry.setParameter("trxdate", trx.getTransactionProcessDate());
+    if (costDimensions.get(CostDimension.Warehouse) != null) {
+      trxQry.setParameter("warehouse", costDimensions.get(CostDimension.Warehouse).getId());
+    }
+    trxQry.setParameterList("orgs", orgs);
+    Object stock = trxQry.uniqueResult();
+    if (stock != null) {
+      return (BigDecimal) stock;
+    }
+    return BigDecimal.ZERO;
+  }
+
+  /**
+   * Calculates the value of the stock of the product on the given date, for the given cost
+   * dimensions and for the given currency. It only takes transactions that have its cost
+   * calculated.
+   */
+  private BigDecimal getCurrentValuedStock() {
+    Organization org = getCostOrg();
+    Currency currency = getCostCurrency();
+    MaterialTransaction trx = getTransaction();
+    HashMap<CostDimension, BaseOBObject> costDimensions = getCostDimensions();
+
+    // Get child tree of organizations.
+    Set<String> orgs = OBContext.getOBContext().getOrganizationStructureProvider()
+        .getChildTree(org.getId(), true);
+
+    StringBuffer select = new StringBuffer();
+    select.append(" select sum(case");
+    select.append("     when trx." + MaterialTransaction.PROPERTY_MOVEMENTQUANTITY
+        + " < 0 then -tc." + TransactionCost.PROPERTY_COST);
+    select.append("     else tc." + TransactionCost.PROPERTY_COST + " end ) as cost");
+    select.append(" , tc." + TransactionCost.PROPERTY_CURRENCY + ".id as currency");
+    select.append(" , coalesce(sr." + ShipmentInOut.PROPERTY_ACCOUNTINGDATE + ", trx."
+        + MaterialTransaction.PROPERTY_MOVEMENTDATE + ") as mdate");
+    select.append(" , sum(trx." + MaterialTransaction.PROPERTY_MOVEMENTQUANTITY + ") as stock");
+
+    select.append(" from " + TransactionCost.ENTITY_NAME + " as tc");
+    select.append("  join tc." + TransactionCost.PROPERTY_INVENTORYTRANSACTION + " as trx");
+    select.append("  join trx." + MaterialTransaction.PROPERTY_STORAGEBIN + " as locator");
+    select.append("  left join trx." + MaterialTransaction.PROPERTY_GOODSSHIPMENTLINE + " as line");
+    select.append("  left join line." + ShipmentInOutLine.PROPERTY_SHIPMENTRECEIPT + " as sr");
+
+    select.append(" where trx." + MaterialTransaction.PROPERTY_PRODUCT + " = :product");
+    // Include only transactions that have its cost calculated
+    select.append("   and trx." + MaterialTransaction.PROPERTY_ISCOSTCALCULATED + " = true");
+    // Consider only transactions with movement date equal or lower than the movement date of the
+    // adjusted transaction. But for transactions with the same movement date only those with a
+    // transaction date equal or before the process date of the adjusted transaction.
+    select.append("   and (trx." + MaterialTransaction.PROPERTY_MOVEMENTDATE + " < :mvtdate");
+    select.append("     or (trx." + MaterialTransaction.PROPERTY_MOVEMENTDATE + " = :mvtdate");
+    select.append("   and trx." + MaterialTransaction.PROPERTY_TRANSACTIONPROCESSDATE
+        + " <= :trxdate ))");
+    if (costDimensions.get(CostDimension.Warehouse) != null) {
+      select.append("  and locator." + Locator.PROPERTY_WAREHOUSE + ".id = :warehouse");
+    }
+    select.append("   and trx." + MaterialTransaction.PROPERTY_ORGANIZATION + ".id in (:orgs)");
+
+    select.append(" group by tc." + TransactionCost.PROPERTY_CURRENCY);
+    select.append("   , coalesce(sr." + ShipmentInOut.PROPERTY_ACCOUNTINGDATE + ", trx."
+        + MaterialTransaction.PROPERTY_MOVEMENTDATE + ")");
+
+    Query trxQry = OBDal.getInstance().getSession().createQuery(select.toString());
+    trxQry.setParameter("product", trx.getProduct());
+    trxQry.setParameter("mvtdate", trx.getMovementDate());
+    trxQry.setParameter("trxdate", trx.getTransactionProcessDate());
+    if (costDimensions.get(CostDimension.Warehouse) != null) {
+      trxQry.setParameter("warehouse", costDimensions.get(CostDimension.Warehouse).getId());
+    }
+    trxQry.setParameterList("orgs", orgs);
+    @SuppressWarnings("unchecked")
+    List<Object[]> o = trxQry.list();
+    BigDecimal costsum = BigDecimal.ZERO;
+    for (Object[] resultSet : o) {
+      BigDecimal origAmt = (BigDecimal) resultSet[0];
+      Currency origCur = OBDal.getInstance().get(Currency.class, resultSet[1]);
+      Date convDate = (Date) resultSet[2];
+
+      if (origCur != currency) {
+        costsum = costsum.add(FinancialUtils.getConvertedAmount(origAmt, origCur, currency,
+            convDate, org, FinancialUtils.PRECISION_COSTING));
+      } else {
+        costsum = costsum.add(origAmt);
+      }
+    }
+    return costsum;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openbravo/costing/CostAdjusmentProcessCheck.java	Thu Jul 17 12:28:37 2014 +0200
@@ -0,0 +1,40 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.0  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License.
+ * The Original Code is Openbravo ERP.
+ * The Initial Developer of the Original Code is Openbravo SLU
+ * All portions are Copyright (C) 2014 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ *************************************************************************
+ */
+package org.openbravo.costing;
+
+import javax.enterprise.context.RequestScoped;
+
+import org.codehaus.jettison.json.JSONObject;
+import org.openbravo.base.exception.OBException;
+import org.openbravo.model.materialmgmt.cost.CostAdjustment;
+
+@RequestScoped
+public interface CostAdjusmentProcessCheck {
+  /**
+   * This method executes the needed checks to the cost adjustment when the process starts.
+   * 
+   * @param costAdjustment
+   *          the cost adjustment being processed.
+   * @param message
+   *          a JSONObject with the message that is returned to the user.
+   * @throws OBException
+   *           when any check fails ant the process is required to stop.
+   */
+  void doCheck(CostAdjustment costAdjustment, JSONObject message) throws OBException;
+}
--- a/src/org/openbravo/costing/CostAdjustmentProcess.java	Thu Jul 17 12:25:10 2014 +0200
+++ b/src/org/openbravo/costing/CostAdjustmentProcess.java	Thu Jul 17 12:28:37 2014 +0200
@@ -20,16 +20,24 @@
 
 import java.util.Date;
 
+import javax.enterprise.inject.Any;
+import javax.enterprise.inject.Instance;
+import javax.inject.Inject;
+
 import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
 import org.hibernate.ScrollMode;
 import org.hibernate.ScrollableResults;
+import org.hibernate.criterion.Order;
 import org.hibernate.criterion.Restrictions;
 import org.openbravo.base.exception.OBException;
 import org.openbravo.base.provider.OBProvider;
+import org.openbravo.client.kernel.ComponentProvider;
+import org.openbravo.dal.core.OBContext;
 import org.openbravo.dal.service.OBCriteria;
 import org.openbravo.dal.service.OBDal;
 import org.openbravo.erpCommon.utility.OBMessageUtils;
+import org.openbravo.model.common.currency.Currency;
 import org.openbravo.model.materialmgmt.cost.CostAdjustment;
 import org.openbravo.model.materialmgmt.cost.CostAdjustmentLine;
 import org.openbravo.model.materialmgmt.cost.TransactionCost;
@@ -39,6 +47,12 @@
 
 public class CostAdjustmentProcess {
   private static final Logger log = LoggerFactory.getLogger(CostAdjustmentProcessHandler.class);
+  @Inject
+  @Any
+  private Instance<CostingAlgorithmAdjustmentImp> costAdjustmentAlgorithms;
+  @Inject
+  @Any
+  private Instance<CostAdjusmentProcessCheck> costAdjustmentProcessChecks;
 
   /**
    * Method to process a cost adjustment.
@@ -51,33 +65,85 @@
    *           when there is an error that prevents the cost adjustment to be processed.
    * @throws JSONException
    */
-  public static JSONObject processCostAdjustment(CostAdjustment costAdjustment) throws OBException,
+  public JSONObject processCostAdjustment(CostAdjustment costAdjustment) throws OBException,
       JSONException {
     JSONObject message = new JSONObject();
     message.put("severity", "success");
     message.put("title", "");
     message.put("text", OBMessageUtils.messageBD("Success"));
-    doChecks(costAdjustment, message);
-    calculateAdjustmentAmount(costAdjustment, message);
-    generateTransactionCosts(costAdjustment);
+    OBContext.setAdminMode(true);
+    try {
+      doChecks(costAdjustment, message);
+      calculateAdjustmentAmount(costAdjustment.getId(), message);
+      costAdjustment = OBDal.getInstance().get(CostAdjustment.class, costAdjustment.getId());
+      generateTransactionCosts(costAdjustment);
+      costAdjustment = OBDal.getInstance().get(CostAdjustment.class, costAdjustment.getId());
+      costAdjustment.setProcessed(true);
+      OBDal.getInstance().save(costAdjustment);
+
+    } finally {
+      OBContext.restorePreviousMode();
+    }
     return message;
   }
 
-  private static void doChecks(CostAdjustment costAdjustment, JSONObject message) {
+  private void doChecks(CostAdjustment costAdjustment, JSONObject message) {
 
+    // Execute checks added implementing costAdjustmentProcess interface.
+
+    for (CostAdjusmentProcessCheck checksInstance : costAdjustmentProcessChecks) {
+      checksInstance.doCheck(costAdjustment, message);
+    }
   }
 
-  private static void calculateAdjustmentAmount(CostAdjustment costAdjustment, JSONObject message) {
+  private void calculateAdjustmentAmount(String strCostAdjustmentId, JSONObject message) {
+    boolean hasNewLines = false;
     OBCriteria<CostAdjustmentLine> critLines = OBDal.getInstance().createCriteria(
         CostAdjustmentLine.class);
     critLines.createAlias(CostAdjustmentLine.PROPERTY_INVENTORYTRANSACTION, "trx");
-    critLines.add(Restrictions.eq(CostAdjustmentLine.PROPERTY_COSTADJUSTMENT, costAdjustment));
-    critLines.addOrderBy("trx." + MaterialTransaction.PROPERTY_MOVEMENTDATE, true);
-    critLines.addOrderBy("trx." + MaterialTransaction.PROPERTY_TRANSACTIONPROCESSDATE, true);
+    critLines.createAlias(CostAdjustmentLine.PROPERTY_COSTADJUSTMENT, "ca");
+    critLines.add(Restrictions.eq("ca.id", strCostAdjustmentId));
+    critLines.add(Restrictions.eq(CostAdjustmentLine.PROPERTY_ISRELATEDTRANSACTIONADJUSTED, false));
+    critLines.addOrder(Order.asc("trx." + MaterialTransaction.PROPERTY_MOVEMENTDATE));
+    critLines.addOrder(Order.asc("trx." + MaterialTransaction.PROPERTY_TRANSACTIONPROCESSDATE));
+    // critLines.addOrderBy("trx." + MaterialTransaction.PROPERTY_MOVEMENTDATE, true);
+    // critLines.addOrderBy("trx." + MaterialTransaction.PROPERTY_TRANSACTIONPROCESSDATE, true);
+    ScrollableResults lines = critLines.scroll(ScrollMode.FORWARD_ONLY);
+    try {
+      while (lines.next()) {
+        hasNewLines = true;
+        CostAdjustmentLine line = (CostAdjustmentLine) lines.get(0);
+        final String strCostAdjLineId = line.getId();
+        MaterialTransaction trx = line.getInventoryTransaction();
+        if (trx.getCostingAlgorithm() == null) {
+          throw new OBException("Cannot adjust transactions calculated with legacy cost engine.");
+        }
 
+        // Add transactions that depend on the transaction being adjusted.
+        CostingAlgorithmAdjustmentImp costAdjImp = getAlgorithmAdjustmentImp(trx
+            .getCostingAlgorithm().getId());
+
+        if (costAdjImp == null) {
+          throw new OBException(
+              "The algorithm used to calculate the cost of the transaction does not implement cost adjustments.");
+        }
+        costAdjImp.init(line);
+        costAdjImp.searchRelatedTransactionCosts();
+        // Reload cost adjustment object in case the costing algorithm has cleared the session.
+        line = OBDal.getInstance().get(CostAdjustmentLine.class, strCostAdjLineId);
+        line.setRelatedTransactionAdjusted(true);
+        OBDal.getInstance().flush();
+        OBDal.getInstance().getSession().clear();
+      }
+    } finally {
+      lines.close();
+    }
+    if (hasNewLines) {
+      calculateAdjustmentAmount(strCostAdjustmentId, message);
+    }
   }
 
-  private static void generateTransactionCosts(CostAdjustment costAdjustment) {
+  private void generateTransactionCosts(CostAdjustment costAdjustment) {
     OBCriteria<CostAdjustmentLine> critLines = OBDal.getInstance().createCriteria(
         CostAdjustmentLine.class);
     Date referenceDate = costAdjustment.getReferenceDate();
@@ -89,8 +155,9 @@
       trxCost.setInventoryTransaction(line.getInventoryTransaction());
       trxCost.setCost(line.getAdjustmentAmount());
       trxCost.setCostDate(referenceDate);
+      trxCost.setCostadjustmentline(line);
       // FIXME: Set proper currency!!!
-      trxCost.setCurrency(null);
+      trxCost.setCurrency(OBDal.getInstance().get(Currency.class, "102"));
 
       OBDal.getInstance().save(trxCost);
       OBDal.getInstance().flush();
@@ -98,4 +165,18 @@
     }
     lines.close();
   }
+
+  private CostingAlgorithmAdjustmentImp getAlgorithmAdjustmentImp(String strCostingAlgorithmId) {
+    CostingAlgorithmAdjustmentImp implementor = null;
+    for (CostingAlgorithmAdjustmentImp nextImplementor : costAdjustmentAlgorithms
+        .select(new ComponentProvider.Selector(strCostingAlgorithmId))) {
+      if (implementor == null) {
+        implementor = nextImplementor;
+      } else {
+        log.warn("More than one class found implementing cost adjustment for algorithm with id {}",
+            strCostingAlgorithmId);
+      }
+    }
+    return implementor;
+  }
 }
--- a/src/org/openbravo/costing/CostAdjustmentProcessHandler.java	Thu Jul 17 12:25:10 2014 +0200
+++ b/src/org/openbravo/costing/CostAdjustmentProcessHandler.java	Thu Jul 17 12:28:37 2014 +0200
@@ -23,6 +23,7 @@
 import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
 import org.openbravo.base.exception.OBException;
+import org.openbravo.base.weld.WeldUtils;
 import org.openbravo.client.kernel.BaseActionHandler;
 import org.openbravo.dal.service.OBDal;
 import org.openbravo.erpCommon.utility.OBMessageUtils;
@@ -43,7 +44,9 @@
       final CostAdjustment costAdjustment = OBDal.getInstance().get(CostAdjustment.class,
           strCostAdjustmentId);
 
-      JSONObject message = CostAdjustmentProcess.processCostAdjustment(costAdjustment);
+      CostAdjustmentProcess cap = WeldUtils
+          .getInstanceFromStaticBeanManager(CostAdjustmentProcess.class);
+      JSONObject message = cap.processCostAdjustment(costAdjustment);
       jsonResponse.put("message", message);
 
     } catch (OBException e) {
--- a/src/org/openbravo/costing/CostingAlgorithm.java	Thu Jul 17 12:25:10 2014 +0200
+++ b/src/org/openbravo/costing/CostingAlgorithm.java	Thu Jul 17 12:28:37 2014 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2012 Openbravo SLU
+ * All portions are Copyright (C) 2012-2014 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  *************************************************************************
@@ -531,29 +531,10 @@
   }
 
   protected BigDecimal getDefaultCost() {
-    Costing stdCost = CostingUtils.getStandardCostDefinition(transaction.getProduct(), costOrg,
-        transaction.getTransactionProcessDate(), costDimensions);
     BusinessPartner bp = CostingUtils.getTrxBusinessPartner(transaction, trxType);
-    PriceList pricelist = null;
-    if (bp != null) {
-      pricelist = bp.getPurchasePricelist();
-    }
-    ProductPrice pp = FinancialUtils.getProductPrice(transaction.getProduct(),
-        transaction.getMovementDate(), false, pricelist, false);
-    if (stdCost == null && pp == null) {
-      throw new OBException("@NoPriceListOrStandardCostForProduct@ @Organization@: "
-          + costOrg.getName() + ", @Product@: " + transaction.getProduct().getName() + ", @Date@: "
-          + OBDateUtils.formatDate(transaction.getTransactionProcessDate()));
-    } else if (stdCost != null && pp == null) {
-      return getTransactionStandardCost();
-    } else if (stdCost == null && pp != null) {
-      return getPriceListCost();
-    } else if (stdCost != null && pp != null
-        && stdCost.getStartingDate().before(pp.getPriceListVersion().getValidFromDate())) {
-      return getPriceListCost();
-    } else {
-      return getTransactionStandardCost();
-    }
+    return CostingUtils.getDefaultCost(transaction.getProduct(), transaction.getMovementQuantity(),
+        costOrg, transaction.getTransactionProcessDate(), transaction.getMovementDate(), bp,
+        costCurrency, costDimensions);
   }
 
   /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openbravo/costing/CostingAlgorithmAdjustmentImp.java	Thu Jul 17 12:28:37 2014 +0200
@@ -0,0 +1,418 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.0  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License.
+ * The Original Code is Openbravo ERP.
+ * The Initial Developer of the Original Code is Openbravo SLU
+ * All portions are Copyright (C) 2014 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ *************************************************************************
+ */
+package org.openbravo.costing;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.enterprise.context.RequestScoped;
+
+import org.openbravo.base.structure.BaseOBObject;
+import org.openbravo.costing.CostingAlgorithm.CostDimension;
+import org.openbravo.costing.CostingServer.TrxType;
+import org.openbravo.dal.service.OBDal;
+import org.openbravo.model.common.businesspartner.BusinessPartner;
+import org.openbravo.model.common.currency.Currency;
+import org.openbravo.model.common.enterprise.Organization;
+import org.openbravo.model.common.enterprise.Warehouse;
+import org.openbravo.model.common.order.OrderLine;
+import org.openbravo.model.materialmgmt.cost.CostAdjustmentLine;
+import org.openbravo.model.materialmgmt.cost.CostingRule;
+import org.openbravo.model.materialmgmt.transaction.InternalConsumptionLine;
+import org.openbravo.model.materialmgmt.transaction.InventoryCountLine;
+import org.openbravo.model.materialmgmt.transaction.MaterialTransaction;
+import org.openbravo.model.materialmgmt.transaction.ProductionLine;
+import org.openbravo.model.materialmgmt.transaction.ShipmentInOutLine;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@RequestScoped
+public abstract class CostingAlgorithmAdjustmentImp {
+  protected static Logger log4j = LoggerFactory.getLogger(CostingAlgorithmAdjustmentImp.class);
+  protected String strCostAdjLineId;
+  protected String strTransactionId;
+  protected String strCostOrgId;
+  protected String strCostCurrencyId;
+  protected TrxType trxType;
+  protected String strCostingRuleId;
+  protected HashMap<CostDimension, String> costDimensionIds = new HashMap<CostDimension, String>();
+
+  /**
+   * Initializes class variables to perform the cost adjustment process. Variables are stored by the
+   * ids instead of the BaseOBObject to be safe of session clearing.
+   * 
+   * @param costAdjLine
+   *          The Cost Adjustment Line that it is processed.
+   */
+  public void init(CostAdjustmentLine costAdjLine) {
+    strCostAdjLineId = costAdjLine.getId();
+    MaterialTransaction transaction = costAdjLine.getInventoryTransaction();
+    strTransactionId = transaction.getId();
+    CostingServer costingServer = new CostingServer(transaction);
+    strCostOrgId = costingServer.getOrganization().getId();
+    strCostCurrencyId = costingServer.getCostCurrency().getId();
+    trxType = CostingServer.TrxType.getTrxType(transaction);
+    CostingRule costingRule = costingServer.getCostingRule();
+    strCostingRuleId = costingRule.getId();
+
+    HashMap<CostDimension, BaseOBObject> costDimensions = CostingUtils.getEmptyDimensions();
+    // Production products cannot be calculated by warehouse dimension.
+    if (!transaction.getProduct().isProduction() && costingRule.isWarehouseDimension()) {
+      costDimensions.put(CostDimension.Warehouse, transaction.getStorageBin().getWarehouse());
+    }
+    for (CostDimension costDimension : costDimensions.keySet()) {
+      String value = null;
+      if (costDimensions.get(costDimension) != null) {
+        value = (String) costDimensions.get(costDimension).getId();
+      }
+      costDimensionIds.put(costDimension, value);
+    }
+  }
+
+  /**
+   * Process to include in the Cost Adjustment the required lines of transactions whose cost needs
+   * to be adjusted as a consequence of other lines already included.
+   */
+  protected void searchRelatedTransactionCosts() {
+    CostAdjustmentLine costAdjLine = getCostAdjLine();
+
+    // Backdated transactions are inserted with a null adjustment amount.
+    if (costAdjLine.getAdjustmentAmount() == null) {
+      calculateAdjustmentAmount();
+    }
+
+    // Some transaction costs are directly related to other transaction costs. These relationship
+    // must be kept when the original transaction cost is adjusted adjusting as well the dependent
+    // transactions.
+    switch (trxType) {
+    case Shipment:
+      searchReturnShipments();
+    case Receipt:
+      searchVoidInOut();
+      break;
+    case IntMovementFrom:
+      searchIntMovementTo();
+      break;
+    case InternalCons:
+      searchVoidInternalConsumption();
+      break;
+    case BOMPart:
+      searchBOMProducts();
+      break;
+    case ManufacturingConsumed:
+      searchManufacturingProduced();
+      break;
+    case InventoryDecrease:
+    case InventoryIncrease:
+      searchOpeningInventory();
+    default:
+      break;
+    }
+
+    getRelatedTransactionsByAlgorithm();
+    costAdjLine = getCostAdjLine();
+    costAdjLine.setRelatedTransactionAdjusted(true);
+    OBDal.getInstance().save(costAdjLine);
+  }
+
+  /*
+   * When the cost of a Closing Inventory is adjusted it is needed to adjust with the same amount
+   * the related Opening Inventory.
+   */
+  private void searchOpeningInventory() {
+    InventoryCountLine invline = getTransaction().getPhysicalInventoryLine().getRelatedInventory();
+    if (invline == null) {
+      return;
+    }
+    CostAdjustmentLine costadjline = getCostAdjLine();
+    MaterialTransaction trx = invline.getMaterialMgmtMaterialTransactionList().get(0);
+    CostAdjustmentLine newCAL = CostAdjustmentUtils.insertCostAdjustmentLine(trx,
+        costadjline.getCostAdjustment(), costadjline.getAdjustmentAmount().negate(), false,
+        trx.getTransactionProcessDate(), null);
+    newCAL.setRelatedTransactionAdjusted(false);
+    OBDal.getInstance().save(newCAL);
+  }
+
+  private void searchManufacturingProduced() {
+    MaterialTransaction trx = getTransaction();
+    CostAdjustmentLine costadjline = getCostAdjLine();
+    CostAdjustmentLine lastAdjLine = null;
+    BigDecimal pendingAdjAmt = costadjline.getAdjustmentAmount();
+    List<ProductionLine> productionLines = trx.getProductionLine().getProductionPlan()
+        .getManufacturingProductionLineList();
+    Collections.sort(productionLines, new Comparator<ProductionLine>() {
+      public int compare(ProductionLine pline1, ProductionLine pline2) {
+        return pline1.getComponentCost().compareTo(pline2.getComponentCost());
+      }
+    });
+    for (ProductionLine pline : productionLines) {
+      if (!pline.getProductionType().equals("P+")) {
+        continue;
+      }
+      MaterialTransaction prodtrx = pline.getMaterialMgmtMaterialTransactionList().get(0);
+      BigDecimal adjAmt = costadjline.getAdjustmentAmount().multiply(pline.getComponentCost());
+      CostAdjustmentLine newCAL = CostAdjustmentUtils.insertCostAdjustmentLine(prodtrx,
+          costadjline.getCostAdjustment(), adjAmt.negate(), false,
+          prodtrx.getTransactionProcessDate(), null);
+      newCAL.setRelatedTransactionAdjusted(false);
+      OBDal.getInstance().save(newCAL);
+
+      pendingAdjAmt = pendingAdjAmt.subtract(adjAmt);
+      lastAdjLine = newCAL;
+    }
+    // If there is more than one P+ product there can be some amount left to assign due to rounding.
+    if (pendingAdjAmt.signum() != 0 && lastAdjLine != null) {
+      lastAdjLine
+          .setAdjustmentAmount(lastAdjLine.getAdjustmentAmount().add(pendingAdjAmt.negate()));
+      OBDal.getInstance().save(lastAdjLine);
+    }
+  }
+
+  private void searchBOMProducts() {
+    MaterialTransaction trx = getTransaction();
+    CostAdjustmentLine costadjline = getCostAdjLine();
+    for (ProductionLine pline : trx.getProductionLine().getProductionPlan()
+        .getManufacturingProductionLineList()) {
+      if (pline.getMovementQuantity().signum() <= 0) {
+        continue;
+      }
+      MaterialTransaction prodtrx = pline.getMaterialMgmtMaterialTransactionList().get(0);
+      CostAdjustmentLine newCAL = CostAdjustmentUtils.insertCostAdjustmentLine(prodtrx,
+          costadjline.getCostAdjustment(), costadjline.getAdjustmentAmount().negate(), false,
+          prodtrx.getTransactionProcessDate(), null);
+      newCAL.setRelatedTransactionAdjusted(false);
+      OBDal.getInstance().save(newCAL);
+    }
+  }
+
+  private void searchVoidInternalConsumption() {
+    MaterialTransaction trx = getTransaction();
+    CostAdjustmentLine costadjline = getCostAdjLine();
+    InternalConsumptionLine intCons = trx.getInternalConsumptionLine()
+        .getMaterialMgmtInternalConsumptionLineVoidedInternalConsumptionLineList().get(0);
+    MaterialTransaction voidedTrx = intCons.getMaterialMgmtMaterialTransactionList().get(0);
+    CostAdjustmentLine newCAL = CostAdjustmentUtils.insertCostAdjustmentLine(voidedTrx,
+        costadjline.getCostAdjustment(), costadjline.getAdjustmentAmount().negate(), false,
+        voidedTrx.getTransactionProcessDate(), null);
+    newCAL.setRelatedTransactionAdjusted(false);
+    OBDal.getInstance().save(newCAL);
+  }
+
+  private void searchIntMovementTo() {
+    MaterialTransaction transaction = getTransaction();
+    CostAdjustmentLine costadjline = getCostAdjLine();
+    for (MaterialTransaction movementTransaction : transaction.getMovementLine()
+        .getMaterialMgmtMaterialTransactionList()) {
+      if (movementTransaction.getId().equals(transaction.getId())) {
+        continue;
+      }
+      CostAdjustmentUtils.insertCostAdjustmentLine(movementTransaction,
+          costadjline.getCostAdjustment(), costadjline.getAdjustmentAmount().negate(), false,
+          movementTransaction.getTransactionProcessDate(), null);
+    }
+  }
+
+  private void searchVoidInOut() {
+    ShipmentInOutLine voidedinoutline = getTransaction().getGoodsShipmentLine()
+        .getCanceledInoutLine();
+    if (voidedinoutline != null) {
+      CostAdjustmentLine costadjline = getCostAdjLine();
+      for (MaterialTransaction trx : voidedinoutline.getMaterialMgmtMaterialTransactionList()) {
+        // TODO: Generate cost adjustment line
+        CostAdjustmentUtils.insertCostAdjustmentLine(trx, costadjline.getCostAdjustment(),
+            costadjline.getAdjustmentAmount().negate(), false, trx.getTransactionProcessDate(),
+            null);
+      }
+    }
+  }
+
+  private void searchReturnShipments() {
+    ShipmentInOutLine inoutline = getTransaction().getGoodsShipmentLine();
+    CostAdjustmentLine costadjline = getCostAdjLine();
+    BigDecimal costAdjAmt = costadjline.getAdjustmentAmount().negate();
+    int precission = getCostCurrency().getStandardPrecision().intValue();
+    for (OrderLine returnorderline : inoutline.getOrderLineList()) {
+      for (ShipmentInOutLine retinoutline : returnorderline.getMaterialMgmtShipmentInOutLineList()) {
+        for (MaterialTransaction rettrx : retinoutline.getMaterialMgmtMaterialTransactionList()) {
+          // TODO: Generate cost adjustment line
+          BigDecimal adjAmt = costAdjAmt.multiply(rettrx.getMovementQuantity().abs()).divide(
+              inoutline.getMovementQuantity().abs(), precission, RoundingMode.HALF_UP);
+          CostAdjustmentUtils.insertCostAdjustmentLine(rettrx, costadjline.getCostAdjustment(),
+              adjAmt, false, rettrx.getTransactionProcessDate(), null);
+        }
+      }
+    }
+
+  }
+
+  abstract void getRelatedTransactionsByAlgorithm();
+
+  protected void calculateAdjustmentAmount() {
+    BigDecimal adjAmt = BigDecimal.ZERO;
+    // Incoming transactions does not modify the calculated cost
+    switch (trxType) {
+    case ShipmentVoid:
+    case ReceiptVoid:
+    case IntMovementTo:
+    case InternalConsVoid:
+    case BOMProduct:
+    case ManufacturingProduced:
+      // The cost of these transaction types does not depend on the date it is calculated.
+      break;
+
+    case Receipt:
+      if (hasOrder()) {
+        // If the receipt has a related order the cost amount does not depend on the date.
+        break;
+      }
+      // Check receipt default on backdated date.
+      break;
+
+    case ShipmentReturn:
+      if (hasReturnedReceipt()) {
+        // If the return receipt has a original receipt the cost amount does not depend on the date.
+        break;
+      }
+    case ShipmentNegative:
+    case InventoryIncrease:
+      if (inventoryHasCost()) {
+        // If the inventory line defined a unitary cost it does not depend on the date.
+        break;
+      }
+    case InternalConsNegative:
+      // These transaction types are calculated using the default cost. Check if there is a
+      // difference.
+      adjAmt = getDefaultCostDifference();
+      break;
+
+    case Shipment:
+    case ReceiptReturn:
+    case ReceiptNegative:
+    case InventoryDecrease:
+    case IntMovementFrom:
+    case InternalCons:
+    case BOMPart:
+    case ManufacturingConsumed:
+      // These transactions are calculated as regular outgoing transactions. The adjustment amount
+      // needs to be calculated by the algorithm.
+      adjAmt = getOutgoingBackdatedTrxAdjAmt();
+    default:
+      break;
+    }
+    CostAdjustmentLine costAdjLine = getCostAdjLine();
+    costAdjLine.setAdjustmentAmount(adjAmt);
+    OBDal.getInstance().save(costAdjLine);
+
+  }
+
+  abstract BigDecimal getOutgoingBackdatedTrxAdjAmt();
+
+  private BigDecimal getDefaultCostDifference() {
+    MaterialTransaction trx = getTransaction();
+    BusinessPartner bp = CostingUtils.getTrxBusinessPartner(trx, trxType);
+
+    BigDecimal defaultCost = CostingUtils.getDefaultCost(trx.getProduct(),
+        trx.getMovementQuantity(), getCostOrg(), getCostAdjLine().getTransactionDate(),
+        trx.getMovementDate(), bp, getCostCurrency(), getCostDimensions());
+    // FIXME: Review if previous adjustment cost need to be considered.
+    BigDecimal trxCalculatedCost = trx.getTransactionCost();
+    return trxCalculatedCost.subtract(defaultCost);
+  }
+
+  /**
+   * Checks if the goods receipt line of the adjustment line has a related purchase order line.
+   * 
+   * @param costAdjLine
+   *          the adjustment line to check.
+   * @return true if there is a related order line.
+   */
+  private boolean hasOrder() {
+    CostAdjustmentLine costAdjLine = getCostAdjLine();
+    return costAdjLine.getInventoryTransaction().getGoodsShipmentLine().getSalesOrderLine() != null;
+  }
+
+  /**
+   * Checks if the inventory line has a unit cost defined.
+   * 
+   * @param costAdjLine
+   *          the adjustment line to check.
+   * @return true if there is a unit cost.
+   */
+  private boolean inventoryHasCost() {
+    CostAdjustmentLine costAdjLine = getCostAdjLine();
+    return costAdjLine.getInventoryTransaction().getPhysicalInventoryLine().getCost() != null;
+  }
+
+  /**
+   * Checks if the returned receipt line has a related original shipment line.
+   * 
+   * @param costAdjLine
+   *          the adjustment line to check.
+   * @return true if there is a original shipment line.
+   */
+  private boolean hasReturnedReceipt() {
+    CostAdjustmentLine costAdjLine = getCostAdjLine();
+    OrderLine shipmentLine = costAdjLine.getInventoryTransaction().getGoodsShipmentLine()
+        .getSalesOrderLine();
+    return shipmentLine != null && shipmentLine.getGoodsShipmentLine() != null;
+  }
+
+  public CostAdjustmentLine getCostAdjLine() {
+    return OBDal.getInstance().get(CostAdjustmentLine.class, strCostAdjLineId);
+  }
+
+  public MaterialTransaction getTransaction() {
+    return OBDal.getInstance().get(MaterialTransaction.class, strTransactionId);
+  }
+
+  public Organization getCostOrg() {
+    return OBDal.getInstance().get(Organization.class, strCostOrgId);
+  }
+
+  public Currency getCostCurrency() {
+    return OBDal.getInstance().get(Currency.class, strCostCurrencyId);
+  }
+
+  public CostingRule getCostingRule() {
+    return OBDal.getInstance().get(CostingRule.class, strCostingRuleId);
+  }
+
+  public HashMap<CostDimension, BaseOBObject> getCostDimensions() {
+    HashMap<CostDimension, BaseOBObject> costDimensions = new HashMap<CostDimension, BaseOBObject>();
+    for (CostDimension costDimension : costDimensionIds.keySet()) {
+      switch (costDimension) {
+      case Warehouse:
+        Warehouse warehouse = null;
+        if (costDimensionIds.get(costDimension) != null) {
+          warehouse = OBDal.getInstance().get(Warehouse.class, costDimensionIds.get(costDimension));
+        }
+        costDimensions.put(costDimension, warehouse);
+        break;
+      default:
+        break;
+      }
+    }
+
+    return costDimensions;
+  }
+}
--- a/src/org/openbravo/costing/CostingServer.java	Thu Jul 17 12:25:10 2014 +0200
+++ b/src/org/openbravo/costing/CostingServer.java	Thu Jul 17 12:28:37 2014 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2012-2013 Openbravo SLU
+ * All portions are Copyright (C) 2012-2014 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  *************************************************************************
@@ -28,6 +28,7 @@
 import org.openbravo.base.exception.OBException;
 import org.openbravo.base.provider.OBProvider;
 import org.openbravo.base.util.OBClassLoader;
+import org.openbravo.base.weld.WeldUtils;
 import org.openbravo.dal.core.OBContext;
 import org.openbravo.dal.service.OBDal;
 import org.openbravo.dal.service.OBQuery;
@@ -127,7 +128,9 @@
             Boolean.TRUE, OBDateUtils.getEndOfDay(transaction.getMovementDate()), null);
 
         try {
-          JSONObject message = CostAdjustmentProcess.processCostAdjustment(costAdjustmentHeader);
+          CostAdjustmentProcess cap = WeldUtils
+              .getInstanceFromStaticBeanManager(CostAdjustmentProcess.class);
+          JSONObject message = cap.processCostAdjustment(costAdjustmentHeader);
 
           if (message.get("severity") != "success") {
             throw new OBException(OBMessageUtils.parseTranslation("@ErrorProcessingCostAdj@")
--- a/src/org/openbravo/costing/ManualCostAdjustmentProcessHandler.java	Thu Jul 17 12:25:10 2014 +0200
+++ b/src/org/openbravo/costing/ManualCostAdjustmentProcessHandler.java	Thu Jul 17 12:28:37 2014 +0200
@@ -24,6 +24,7 @@
 import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
 import org.openbravo.base.exception.OBException;
+import org.openbravo.base.weld.WeldUtils;
 import org.openbravo.client.kernel.BaseActionHandler;
 import org.openbravo.dal.service.OBDal;
 import org.openbravo.erpCommon.utility.OBMessageUtils;
@@ -72,7 +73,9 @@
       CostAdjustmentUtils.insertCostAdjustmentLine(transaction, costAdjustmentHeader, costAdjusted,
           Boolean.TRUE, null, null);
 
-      JSONObject message = CostAdjustmentProcess.processCostAdjustment(costAdjustmentHeader);
+      CostAdjustmentProcess cap = WeldUtils
+          .getInstanceFromStaticBeanManager(CostAdjustmentProcess.class);
+      JSONObject message = cap.processCostAdjustment(costAdjustmentHeader);
       jsonResponse.put("message", message);
 
     } catch (OBException e) {