Merge with PI default tip
authorEduardo Becerra <ebec70@yahoo.com>
Wed, 14 Nov 2018 08:52:36 +0100
changeset 34969 75a160f452b7
parent 34963 e0dd4d4090a1 (current diff)
parent 34968 c24eed29cc3d (diff)
Merge with PI
--- a/src-db/database/model/tables/M_INOUT.xml	Tue Nov 13 12:08:14 2018 +0100
+++ b/src-db/database/model/tables/M_INOUT.xml	Wed Nov 14 08:52:36 2018 +0100
@@ -265,6 +265,10 @@
         <default><![CDATA[N]]></default>
         <onCreateDefault><![CDATA['Y']]></onCreateDefault>
       </column>
+      <column name="INVOICEFROMSHIPMENT" primaryKey="false" required="false" type="CHAR" size="1" autoIncrement="false">
+        <default/>
+        <onCreateDefault/>
+      </column>
       <foreign-key foreignTable="M_FREIGHTCATEGORY" name="M_FREIGHTCATEGORY_M_INOUT">
         <reference local="M_FREIGHTCATEGORY_ID" foreign="M_FREIGHTCATEGORY_ID"/>
       </foreign-key>
--- a/src-db/database/sourcedata/AD_COLUMN.xml	Tue Nov 13 12:08:14 2018 +0100
+++ b/src-db/database/sourcedata/AD_COLUMN.xml	Wed Nov 14 08:52:36 2018 +0100
@@ -356602,6 +356602,45 @@
 <!--BF04DD653CA1489DABA8CB2BBD788C78-->  <ALLOWED_CROSS_ORG_LINK><![CDATA[N]]></ALLOWED_CROSS_ORG_LINK>
 <!--BF04DD653CA1489DABA8CB2BBD788C78--></AD_COLUMN>
 
+<!--BF2DF59DAC32474692434F5A21FB0C27--><AD_COLUMN>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <AD_COLUMN_ID><![CDATA[BF2DF59DAC32474692434F5A21FB0C27]]></AD_COLUMN_ID>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <NAME><![CDATA[Invoicefromshipment]]></NAME>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <DESCRIPTION><![CDATA[Generate Invoice from Shipment]]></DESCRIPTION>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <HELP><![CDATA[Generate Invoice from Shipment considering invoice terms of orders linked to shipment lines.]]></HELP>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <COLUMNNAME><![CDATA[Invoicefromshipment]]></COLUMNNAME>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <AD_TABLE_ID><![CDATA[319]]></AD_TABLE_ID>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <AD_REFERENCE_ID><![CDATA[28]]></AD_REFERENCE_ID>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <FIELDLENGTH><![CDATA[1]]></FIELDLENGTH>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <ISKEY><![CDATA[N]]></ISKEY>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <ISPARENT><![CDATA[N]]></ISPARENT>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <ISMANDATORY><![CDATA[N]]></ISMANDATORY>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <ISUPDATEABLE><![CDATA[Y]]></ISUPDATEABLE>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <ISIDENTIFIER><![CDATA[N]]></ISIDENTIFIER>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <SEQNO><![CDATA[500]]></SEQNO>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <ISTRANSLATED><![CDATA[N]]></ISTRANSLATED>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <ISENCRYPTED><![CDATA[N]]></ISENCRYPTED>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <ISSELECTIONCOLUMN><![CDATA[N]]></ISSELECTIONCOLUMN>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <AD_ELEMENT_ID><![CDATA[175283CDAAA34A78BF8A7E6BD069D2B3]]></AD_ELEMENT_ID>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <ISSESSIONATTR><![CDATA[N]]></ISSESSIONATTR>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <ISSECONDARYKEY><![CDATA[N]]></ISSECONDARYKEY>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <ISDESENCRYPTABLE><![CDATA[N]]></ISDESENCRYPTABLE>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <DEVELOPMENTSTATUS><![CDATA[RE]]></DEVELOPMENTSTATUS>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <POSITION><![CDATA[68]]></POSITION>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <ISTRANSIENT><![CDATA[N]]></ISTRANSIENT>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <ISAUTOSAVE><![CDATA[Y]]></ISAUTOSAVE>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <VALIDATEONNEW><![CDATA[Y]]></VALIDATEONNEW>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <IMAGESIZEVALUESACTION><![CDATA[N]]></IMAGESIZEVALUESACTION>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <ISUSEDSEQUENCE><![CDATA[N]]></ISUSEDSEQUENCE>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <ALLOWSORTING><![CDATA[Y]]></ALLOWSORTING>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <ALLOWFILTERING><![CDATA[Y]]></ALLOWFILTERING>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <ALLOWED_CROSS_ORG_LINK><![CDATA[N]]></ALLOWED_CROSS_ORG_LINK>
+<!--BF2DF59DAC32474692434F5A21FB0C27-->  <EM_OBUIAPP_PROCESS_ID><![CDATA[62250E8866EA4D96A66C309878DC039E]]></EM_OBUIAPP_PROCESS_ID>
+<!--BF2DF59DAC32474692434F5A21FB0C27--></AD_COLUMN>
+
 <!--BF75CF4CF9CC4AE3A5D42DAF00C42CDD--><AD_COLUMN>
 <!--BF75CF4CF9CC4AE3A5D42DAF00C42CDD-->  <AD_COLUMN_ID><![CDATA[BF75CF4CF9CC4AE3A5D42DAF00C42CDD]]></AD_COLUMN_ID>
 <!--BF75CF4CF9CC4AE3A5D42DAF00C42CDD-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-db/database/sourcedata/AD_ELEMENT.xml	Tue Nov 13 12:08:14 2018 +0100
+++ b/src-db/database/sourcedata/AD_ELEMENT.xml	Wed Nov 14 08:52:36 2018 +0100
@@ -21650,6 +21650,20 @@
 <!--17485BBD94A447C2A0C823181EF0F066-->  <ISGLOSSARY><![CDATA[N]]></ISGLOSSARY>
 <!--17485BBD94A447C2A0C823181EF0F066--></AD_ELEMENT>
 
+<!--175283CDAAA34A78BF8A7E6BD069D2B3--><AD_ELEMENT>
+<!--175283CDAAA34A78BF8A7E6BD069D2B3-->  <AD_ELEMENT_ID><![CDATA[175283CDAAA34A78BF8A7E6BD069D2B3]]></AD_ELEMENT_ID>
+<!--175283CDAAA34A78BF8A7E6BD069D2B3-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--175283CDAAA34A78BF8A7E6BD069D2B3-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--175283CDAAA34A78BF8A7E6BD069D2B3-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--175283CDAAA34A78BF8A7E6BD069D2B3-->  <COLUMNNAME><![CDATA[Invoicefromshipment]]></COLUMNNAME>
+<!--175283CDAAA34A78BF8A7E6BD069D2B3-->  <NAME><![CDATA[Generate Invoice from Shipment]]></NAME>
+<!--175283CDAAA34A78BF8A7E6BD069D2B3-->  <PRINTNAME><![CDATA[Generate Invoice from Shipment]]></PRINTNAME>
+<!--175283CDAAA34A78BF8A7E6BD069D2B3-->  <DESCRIPTION><![CDATA[Generate Invoice from Shipment]]></DESCRIPTION>
+<!--175283CDAAA34A78BF8A7E6BD069D2B3-->  <HELP><![CDATA[Generate Invoice from Shipment considering invoice terms of orders linked to shipment lines.]]></HELP>
+<!--175283CDAAA34A78BF8A7E6BD069D2B3-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--175283CDAAA34A78BF8A7E6BD069D2B3-->  <ISGLOSSARY><![CDATA[N]]></ISGLOSSARY>
+<!--175283CDAAA34A78BF8A7E6BD069D2B3--></AD_ELEMENT>
+
 <!--1781EBA322894DF58835305F5D6B26DA--><AD_ELEMENT>
 <!--1781EBA322894DF58835305F5D6B26DA-->  <AD_ELEMENT_ID><![CDATA[1781EBA322894DF58835305F5D6B26DA]]></AD_ELEMENT_ID>
 <!--1781EBA322894DF58835305F5D6B26DA-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -26138,6 +26152,18 @@
 <!--5B04EA553995A5A8E040007F01007F3D-->  <ISGLOSSARY><![CDATA[N]]></ISGLOSSARY>
 <!--5B04EA553995A5A8E040007F01007F3D--></AD_ELEMENT>
 
+<!--5B12F3FCB67D46568CED2DE9BCA8080E--><AD_ELEMENT>
+<!--5B12F3FCB67D46568CED2DE9BCA8080E-->  <AD_ELEMENT_ID><![CDATA[5B12F3FCB67D46568CED2DE9BCA8080E]]></AD_ELEMENT_ID>
+<!--5B12F3FCB67D46568CED2DE9BCA8080E-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--5B12F3FCB67D46568CED2DE9BCA8080E-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--5B12F3FCB67D46568CED2DE9BCA8080E-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--5B12F3FCB67D46568CED2DE9BCA8080E-->  <COLUMNNAME><![CDATA[processInvoice]]></COLUMNNAME>
+<!--5B12F3FCB67D46568CED2DE9BCA8080E-->  <NAME><![CDATA[Process Invoice]]></NAME>
+<!--5B12F3FCB67D46568CED2DE9BCA8080E-->  <PRINTNAME><![CDATA[Process Invoice]]></PRINTNAME>
+<!--5B12F3FCB67D46568CED2DE9BCA8080E-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--5B12F3FCB67D46568CED2DE9BCA8080E-->  <ISGLOSSARY><![CDATA[N]]></ISGLOSSARY>
+<!--5B12F3FCB67D46568CED2DE9BCA8080E--></AD_ELEMENT>
+
 <!--5BA951974876BDB2E040007F01011671--><AD_ELEMENT>
 <!--5BA951974876BDB2E040007F01011671-->  <AD_ELEMENT_ID><![CDATA[5BA951974876BDB2E040007F01011671]]></AD_ELEMENT_ID>
 <!--5BA951974876BDB2E040007F01011671-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-db/database/sourcedata/AD_FIELD.xml	Tue Nov 13 12:08:14 2018 +0100
+++ b/src-db/database/sourcedata/AD_FIELD.xml	Wed Nov 14 08:52:36 2018 +0100
@@ -313551,6 +313551,35 @@
 <!--EE0FACACA9D34C06946E1EEC0C194079-->  <EM_OBUIAPP_SHOWSUMMARY><![CDATA[N]]></EM_OBUIAPP_SHOWSUMMARY>
 <!--EE0FACACA9D34C06946E1EEC0C194079--></AD_FIELD>
 
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78--><AD_FIELD>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <AD_FIELD_ID><![CDATA[EE3B8A7F9CE540CF87CE22CDA6E23A78]]></AD_FIELD_ID>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <NAME><![CDATA[Generate Invoice from Shipment]]></NAME>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <DESCRIPTION><![CDATA[Generate Invoice from Shipment]]></DESCRIPTION>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <HELP><![CDATA[Generate Invoice from Shipment considering invoice terms of orders linked to shipment lines.]]></HELP>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <ISCENTRALLYMAINTAINED><![CDATA[Y]]></ISCENTRALLYMAINTAINED>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <AD_TAB_ID><![CDATA[257]]></AD_TAB_ID>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <AD_COLUMN_ID><![CDATA[BF2DF59DAC32474692434F5A21FB0C27]]></AD_COLUMN_ID>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <IGNOREINWAD><![CDATA[N]]></IGNOREINWAD>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <ISDISPLAYED><![CDATA[Y]]></ISDISPLAYED>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <DISPLAYLOGIC><![CDATA[@DocStatus@='CO' & @Iscompletelyinvoiced@='N']]></DISPLAYLOGIC>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <DISPLAYLENGTH><![CDATA[60]]></DISPLAYLENGTH>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <ISREADONLY><![CDATA[N]]></ISREADONLY>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <SEQNO><![CDATA[2060]]></SEQNO>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <ISSAMELINE><![CDATA[N]]></ISSAMELINE>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <ISFIELDONLY><![CDATA[N]]></ISFIELDONLY>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <ISENCRYPTED><![CDATA[N]]></ISENCRYPTED>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <SHOWINRELATION><![CDATA[N]]></SHOWINRELATION>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <ISFIRSTFOCUSEDFIELD><![CDATA[N]]></ISFIRSTFOCUSEDFIELD>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <STARTINODDCOLUMN><![CDATA[N]]></STARTINODDCOLUMN>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <STARTNEWLINE><![CDATA[N]]></STARTNEWLINE>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <ISSHOWNINSTATUSBAR><![CDATA[N]]></ISSHOWNINSTATUSBAR>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78-->  <EM_OBUIAPP_SHOWSUMMARY><![CDATA[N]]></EM_OBUIAPP_SHOWSUMMARY>
+<!--EE3B8A7F9CE540CF87CE22CDA6E23A78--></AD_FIELD>
+
 <!--EE42FF358039451A8E1DBB610AE46537--><AD_FIELD>
 <!--EE42FF358039451A8E1DBB610AE46537-->  <AD_FIELD_ID><![CDATA[EE42FF358039451A8E1DBB610AE46537]]></AD_FIELD_ID>
 <!--EE42FF358039451A8E1DBB610AE46537-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-db/database/sourcedata/AD_MESSAGE.xml	Tue Nov 13 12:08:14 2018 +0100
+++ b/src-db/database/sourcedata/AD_MESSAGE.xml	Wed Nov 14 08:52:36 2018 +0100
@@ -18822,6 +18822,18 @@
 <!--3A10B3119F8D471A8710667FB24131A0-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--3A10B3119F8D471A8710667FB24131A0--></AD_MESSAGE>
 
+<!--3A2875017B8641AE82BC5A5A659A2C46--><AD_MESSAGE>
+<!--3A2875017B8641AE82BC5A5A659A2C46-->  <AD_MESSAGE_ID><![CDATA[3A2875017B8641AE82BC5A5A659A2C46]]></AD_MESSAGE_ID>
+<!--3A2875017B8641AE82BC5A5A659A2C46-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--3A2875017B8641AE82BC5A5A659A2C46-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--3A2875017B8641AE82BC5A5A659A2C46-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--3A2875017B8641AE82BC5A5A659A2C46-->  <VALUE><![CDATA[StatusCompleted]]></VALUE>
+<!--3A2875017B8641AE82BC5A5A659A2C46-->  <MSGTEXT><![CDATA[Completed]]></MSGTEXT>
+<!--3A2875017B8641AE82BC5A5A659A2C46-->  <MSGTYPE><![CDATA[I]]></MSGTYPE>
+<!--3A2875017B8641AE82BC5A5A659A2C46-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--3A2875017B8641AE82BC5A5A659A2C46-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--3A2875017B8641AE82BC5A5A659A2C46--></AD_MESSAGE>
+
 <!--3A499712A0D54CE984A2A2AEB4121A46--><AD_MESSAGE>
 <!--3A499712A0D54CE984A2A2AEB4121A46-->  <AD_MESSAGE_ID><![CDATA[3A499712A0D54CE984A2A2AEB4121A46]]></AD_MESSAGE_ID>
 <!--3A499712A0D54CE984A2A2AEB4121A46-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -20959,6 +20971,18 @@
 <!--659D3B84D0AF4B2396F02889BF7F9914-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--659D3B84D0AF4B2396F02889BF7F9914--></AD_MESSAGE>
 
+<!--659DCCF7ACF5482DBFAA1370BEF88FD6--><AD_MESSAGE>
+<!--659DCCF7ACF5482DBFAA1370BEF88FD6-->  <AD_MESSAGE_ID><![CDATA[659DCCF7ACF5482DBFAA1370BEF88FD6]]></AD_MESSAGE_ID>
+<!--659DCCF7ACF5482DBFAA1370BEF88FD6-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--659DCCF7ACF5482DBFAA1370BEF88FD6-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--659DCCF7ACF5482DBFAA1370BEF88FD6-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--659DCCF7ACF5482DBFAA1370BEF88FD6-->  <VALUE><![CDATA[NewInvoiceGenerated]]></VALUE>
+<!--659DCCF7ACF5482DBFAA1370BEF88FD6-->  <MSGTEXT><![CDATA[New Invoice generated with document number : %s, document status: %s]]></MSGTEXT>
+<!--659DCCF7ACF5482DBFAA1370BEF88FD6-->  <MSGTYPE><![CDATA[S]]></MSGTYPE>
+<!--659DCCF7ACF5482DBFAA1370BEF88FD6-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--659DCCF7ACF5482DBFAA1370BEF88FD6-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--659DCCF7ACF5482DBFAA1370BEF88FD6--></AD_MESSAGE>
+
 <!--65C05BD368ED471CB1E6AE97DD911EDF--><AD_MESSAGE>
 <!--65C05BD368ED471CB1E6AE97DD911EDF-->  <AD_MESSAGE_ID><![CDATA[65C05BD368ED471CB1E6AE97DD911EDF]]></AD_MESSAGE_ID>
 <!--65C05BD368ED471CB1E6AE97DD911EDF-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -25176,6 +25200,18 @@
 <!--B90DAD98BE6B409FA4D10CD01397A735-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--B90DAD98BE6B409FA4D10CD01397A735--></AD_MESSAGE>
 
+<!--B9AF14E02F5944F2A57814C605933E01--><AD_MESSAGE>
+<!--B9AF14E02F5944F2A57814C605933E01-->  <AD_MESSAGE_ID><![CDATA[B9AF14E02F5944F2A57814C605933E01]]></AD_MESSAGE_ID>
+<!--B9AF14E02F5944F2A57814C605933E01-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--B9AF14E02F5944F2A57814C605933E01-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--B9AF14E02F5944F2A57814C605933E01-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--B9AF14E02F5944F2A57814C605933E01-->  <VALUE><![CDATA[StatusDraft]]></VALUE>
+<!--B9AF14E02F5944F2A57814C605933E01-->  <MSGTEXT><![CDATA[Draft]]></MSGTEXT>
+<!--B9AF14E02F5944F2A57814C605933E01-->  <MSGTYPE><![CDATA[I]]></MSGTYPE>
+<!--B9AF14E02F5944F2A57814C605933E01-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--B9AF14E02F5944F2A57814C605933E01-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--B9AF14E02F5944F2A57814C605933E01--></AD_MESSAGE>
+
 <!--B9EE1302AB724B3FA76024DB096412EE--><AD_MESSAGE>
 <!--B9EE1302AB724B3FA76024DB096412EE-->  <AD_MESSAGE_ID><![CDATA[B9EE1302AB724B3FA76024DB096412EE]]></AD_MESSAGE_ID>
 <!--B9EE1302AB724B3FA76024DB096412EE-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -27188,6 +27224,18 @@
 <!--E180D66331CC42218EE3A46A682D29BD-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--E180D66331CC42218EE3A46A682D29BD--></AD_MESSAGE>
 
+<!--E1AE98E11AAB4AA5A10DB6A6DA66E3BF--><AD_MESSAGE>
+<!--E1AE98E11AAB4AA5A10DB6A6DA66E3BF-->  <AD_MESSAGE_ID><![CDATA[E1AE98E11AAB4AA5A10DB6A6DA66E3BF]]></AD_MESSAGE_ID>
+<!--E1AE98E11AAB4AA5A10DB6A6DA66E3BF-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--E1AE98E11AAB4AA5A10DB6A6DA66E3BF-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--E1AE98E11AAB4AA5A10DB6A6DA66E3BF-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--E1AE98E11AAB4AA5A10DB6A6DA66E3BF-->  <VALUE><![CDATA[NoInvoiceGenerated]]></VALUE>
+<!--E1AE98E11AAB4AA5A10DB6A6DA66E3BF-->  <MSGTEXT><![CDATA[No invoice has been generated.]]></MSGTEXT>
+<!--E1AE98E11AAB4AA5A10DB6A6DA66E3BF-->  <MSGTYPE><![CDATA[I]]></MSGTYPE>
+<!--E1AE98E11AAB4AA5A10DB6A6DA66E3BF-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--E1AE98E11AAB4AA5A10DB6A6DA66E3BF-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--E1AE98E11AAB4AA5A10DB6A6DA66E3BF--></AD_MESSAGE>
+
 <!--E2619EAE728A409797BC6D9D7C7FC741--><AD_MESSAGE>
 <!--E2619EAE728A409797BC6D9D7C7FC741-->  <AD_MESSAGE_ID><![CDATA[E2619EAE728A409797BC6D9D7C7FC741]]></AD_MESSAGE_ID>
 <!--E2619EAE728A409797BC6D9D7C7FC741-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-db/database/sourcedata/AD_REFERENCE.xml	Tue Nov 13 12:08:14 2018 +0100
+++ b/src-db/database/sourcedata/AD_REFERENCE.xml	Wed Nov 14 08:52:36 2018 +0100
@@ -4395,6 +4395,20 @@
 <!--11F86B630ECB4A57B28927193F8AB99D-->  <ISVALUEDISPLAYED><![CDATA[N]]></ISVALUEDISPLAYED>
 <!--11F86B630ECB4A57B28927193F8AB99D--></AD_REFERENCE>
 
+<!--133F26E7C401427997D41E132940A78B--><AD_REFERENCE>
+<!--133F26E7C401427997D41E132940A78B-->  <AD_REFERENCE_ID><![CDATA[133F26E7C401427997D41E132940A78B]]></AD_REFERENCE_ID>
+<!--133F26E7C401427997D41E132940A78B-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--133F26E7C401427997D41E132940A78B-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--133F26E7C401427997D41E132940A78B-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--133F26E7C401427997D41E132940A78B-->  <NAME><![CDATA[SalesPriceLists]]></NAME>
+<!--133F26E7C401427997D41E132940A78B-->  <DESCRIPTION><![CDATA[Selects available Sales Price Lists]]></DESCRIPTION>
+<!--133F26E7C401427997D41E132940A78B-->  <HELP><![CDATA[Selects available Sales Price Lists]]></HELP>
+<!--133F26E7C401427997D41E132940A78B-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--133F26E7C401427997D41E132940A78B-->  <ISBASEREFERENCE><![CDATA[N]]></ISBASEREFERENCE>
+<!--133F26E7C401427997D41E132940A78B-->  <PARENTREFERENCE_ID><![CDATA[95E2A8B50A254B2AAE6774B8C2F28120]]></PARENTREFERENCE_ID>
+<!--133F26E7C401427997D41E132940A78B-->  <ISVALUEDISPLAYED><![CDATA[N]]></ISVALUEDISPLAYED>
+<!--133F26E7C401427997D41E132940A78B--></AD_REFERENCE>
+
 <!--14A9BE1555CF4616BDC2E0C8E5EB6542--><AD_REFERENCE>
 <!--14A9BE1555CF4616BDC2E0C8E5EB6542-->  <AD_REFERENCE_ID><![CDATA[14A9BE1555CF4616BDC2E0C8E5EB6542]]></AD_REFERENCE_ID>
 <!--14A9BE1555CF4616BDC2E0C8E5EB6542-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-db/database/sourcedata/AD_TEXTINTERFACES.xml	Tue Nov 13 12:08:14 2018 +0100
+++ b/src-db/database/sourcedata/AD_TEXTINTERFACES.xml	Wed Nov 14 08:52:36 2018 +0100
@@ -12138,6 +12138,17 @@
 <!--11BB4C748D6A43B5A8C64950A2730ED6-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
 <!--11BB4C748D6A43B5A8C64950A2730ED6--></AD_TEXTINTERFACES>
 
+<!--1202D835A7704D1BB276971A5BB2A75C--><AD_TEXTINTERFACES>
+<!--1202D835A7704D1BB276971A5BB2A75C-->  <AD_TEXTINTERFACES_ID><![CDATA[1202D835A7704D1BB276971A5BB2A75C]]></AD_TEXTINTERFACES_ID>
+<!--1202D835A7704D1BB276971A5BB2A75C-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--1202D835A7704D1BB276971A5BB2A75C-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--1202D835A7704D1BB276971A5BB2A75C-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--1202D835A7704D1BB276971A5BB2A75C-->  <TEXT><![CDATA[Invoice Date]]></TEXT>
+<!--1202D835A7704D1BB276971A5BB2A75C-->  <FILENAME><![CDATA[/org/openbravo/erpCommon/ad_actionButton/DocAction.html]]></FILENAME>
+<!--1202D835A7704D1BB276971A5BB2A75C-->  <ISUSED><![CDATA[Y]]></ISUSED>
+<!--1202D835A7704D1BB276971A5BB2A75C-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--1202D835A7704D1BB276971A5BB2A75C--></AD_TEXTINTERFACES>
+
 <!--1239DDC8CC1D46DFA50936AB7B448DC5--><AD_TEXTINTERFACES>
 <!--1239DDC8CC1D46DFA50936AB7B448DC5-->  <AD_TEXTINTERFACES_ID><![CDATA[1239DDC8CC1D46DFA50936AB7B448DC5]]></AD_TEXTINTERFACES_ID>
 <!--1239DDC8CC1D46DFA50936AB7B448DC5-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -17945,6 +17956,17 @@
 <!--6E961D44DEFA3D3DE040007F0101642C-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
 <!--6E961D44DEFA3D3DE040007F0101642C--></AD_TEXTINTERFACES>
 
+<!--6ED25A2559A14057AB572732724F264A--><AD_TEXTINTERFACES>
+<!--6ED25A2559A14057AB572732724F264A-->  <AD_TEXTINTERFACES_ID><![CDATA[6ED25A2559A14057AB572732724F264A]]></AD_TEXTINTERFACES_ID>
+<!--6ED25A2559A14057AB572732724F264A-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--6ED25A2559A14057AB572732724F264A-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--6ED25A2559A14057AB572732724F264A-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--6ED25A2559A14057AB572732724F264A-->  <TEXT><![CDATA[Process Invoice]]></TEXT>
+<!--6ED25A2559A14057AB572732724F264A-->  <FILENAME><![CDATA[/org/openbravo/erpCommon/ad_actionButton/DocAction.html]]></FILENAME>
+<!--6ED25A2559A14057AB572732724F264A-->  <ISUSED><![CDATA[Y]]></ISUSED>
+<!--6ED25A2559A14057AB572732724F264A-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--6ED25A2559A14057AB572732724F264A--></AD_TEXTINTERFACES>
+
 <!--6ED362377A45442CBAAFB7A4FD65CD08--><AD_TEXTINTERFACES>
 <!--6ED362377A45442CBAAFB7A4FD65CD08-->  <AD_TEXTINTERFACES_ID><![CDATA[6ED362377A45442CBAAFB7A4FD65CD08]]></AD_TEXTINTERFACES_ID>
 <!--6ED362377A45442CBAAFB7A4FD65CD08-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -20649,6 +20671,17 @@
 <!--A5DF7BC1C6C440048652EE5AEE8E55D2-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
 <!--A5DF7BC1C6C440048652EE5AEE8E55D2--></AD_TEXTINTERFACES>
 
+<!--A6A80F585A4E45098630A85CDC0594A0--><AD_TEXTINTERFACES>
+<!--A6A80F585A4E45098630A85CDC0594A0-->  <AD_TEXTINTERFACES_ID><![CDATA[A6A80F585A4E45098630A85CDC0594A0]]></AD_TEXTINTERFACES_ID>
+<!--A6A80F585A4E45098630A85CDC0594A0-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--A6A80F585A4E45098630A85CDC0594A0-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--A6A80F585A4E45098630A85CDC0594A0-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--A6A80F585A4E45098630A85CDC0594A0-->  <TEXT><![CDATA[Invoice if possible]]></TEXT>
+<!--A6A80F585A4E45098630A85CDC0594A0-->  <FILENAME><![CDATA[/org/openbravo/erpCommon/ad_actionButton/DocAction.html]]></FILENAME>
+<!--A6A80F585A4E45098630A85CDC0594A0-->  <ISUSED><![CDATA[Y]]></ISUSED>
+<!--A6A80F585A4E45098630A85CDC0594A0-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--A6A80F585A4E45098630A85CDC0594A0--></AD_TEXTINTERFACES>
+
 <!--A6A9B93641B042399A708A1445DD5EFE--><AD_TEXTINTERFACES>
 <!--A6A9B93641B042399A708A1445DD5EFE-->  <AD_TEXTINTERFACES_ID><![CDATA[A6A9B93641B042399A708A1445DD5EFE]]></AD_TEXTINTERFACES_ID>
 <!--A6A9B93641B042399A708A1445DD5EFE-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -21540,6 +21573,17 @@
 <!--BC2ADB71F77CFC33E040A8C064002DA8-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
 <!--BC2ADB71F77CFC33E040A8C064002DA8--></AD_TEXTINTERFACES>
 
+<!--BDF451485310480CBAC40589523A716B--><AD_TEXTINTERFACES>
+<!--BDF451485310480CBAC40589523A716B-->  <AD_TEXTINTERFACES_ID><![CDATA[BDF451485310480CBAC40589523A716B]]></AD_TEXTINTERFACES_ID>
+<!--BDF451485310480CBAC40589523A716B-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--BDF451485310480CBAC40589523A716B-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--BDF451485310480CBAC40589523A716B-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--BDF451485310480CBAC40589523A716B-->  <TEXT><![CDATA[Price List]]></TEXT>
+<!--BDF451485310480CBAC40589523A716B-->  <FILENAME><![CDATA[/org/openbravo/erpCommon/ad_actionButton/DocAction.html]]></FILENAME>
+<!--BDF451485310480CBAC40589523A716B-->  <ISUSED><![CDATA[Y]]></ISUSED>
+<!--BDF451485310480CBAC40589523A716B-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--BDF451485310480CBAC40589523A716B--></AD_TEXTINTERFACES>
+
 <!--BFB26FEF2745470C8456D5A1434DC1D3--><AD_TEXTINTERFACES>
 <!--BFB26FEF2745470C8456D5A1434DC1D3-->  <AD_TEXTINTERFACES_ID><![CDATA[BFB26FEF2745470C8456D5A1434DC1D3]]></AD_TEXTINTERFACES_ID>
 <!--BFB26FEF2745470C8456D5A1434DC1D3-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-db/database/sourcedata/OBUIAPP_PARAMETER.xml	Tue Nov 13 12:08:14 2018 +0100
+++ b/src-db/database/sourcedata/OBUIAPP_PARAMETER.xml	Wed Nov 14 08:52:36 2018 +0100
@@ -884,6 +884,35 @@
 <!--53B71BBF2F654266B15B42B894A847F6-->  <ATT_SHOWINDESCRIPTION><![CDATA[N]]></ATT_SHOWINDESCRIPTION>
 <!--53B71BBF2F654266B15B42B894A847F6--></OBUIAPP_PARAMETER>
 
+<!--5738F8786CA04941A68AD66EF04927CF--><OBUIAPP_PARAMETER>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <OBUIAPP_PARAMETER_ID><![CDATA[5738F8786CA04941A68AD66EF04927CF]]></OBUIAPP_PARAMETER_ID>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <NAME><![CDATA[Price List]]></NAME>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <DESCRIPTION><![CDATA[A catalog of selected items with prices defined generally or for a specific partner.]]></DESCRIPTION>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <HELP><![CDATA[
+Price Lists are used to determine the pricing, margin and cost of items purchased or sold.]]></HELP>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <SEQNO><![CDATA[20]]></SEQNO>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <AD_REFERENCE_ID><![CDATA[95E2A8B50A254B2AAE6774B8C2F28120]]></AD_REFERENCE_ID>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <AD_REFERENCE_VALUE_ID><![CDATA[133F26E7C401427997D41E132940A78B]]></AD_REFERENCE_VALUE_ID>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <COLUMNNAME><![CDATA[priceList]]></COLUMNNAME>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <ISCENTRALLYMAINTAINED><![CDATA[Y]]></ISCENTRALLYMAINTAINED>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <FIELDLENGTH><![CDATA[0]]></FIELDLENGTH>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <ISMANDATORY><![CDATA[Y]]></ISMANDATORY>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <DEFAULTVALUE><![CDATA[OB.getFilterExpression("org.openbravo.materialmgmt.InvoiceFromGoodsShipmentDefaultValueFilterExpression")]]></DEFAULTVALUE>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <AD_ELEMENT_ID><![CDATA[449]]></AD_ELEMENT_ID>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <ISFIXED><![CDATA[N]]></ISFIXED>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <EVALUATEFIXEDVALUE><![CDATA[N]]></EVALUATEFIXEDVALUE>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <OBUIAPP_PROCESS_ID><![CDATA[62250E8866EA4D96A66C309878DC039E]]></OBUIAPP_PROCESS_ID>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <STARTINNEWLINE><![CDATA[N]]></STARTINNEWLINE>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <NUMCOLUMN><![CDATA[2]]></NUMCOLUMN>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <DISPLAYEDROWS><![CDATA[5]]></DISPLAYEDROWS>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <DISPLAYTITLE><![CDATA[Y]]></DISPLAYTITLE>
+<!--5738F8786CA04941A68AD66EF04927CF-->  <ATT_SHOWINDESCRIPTION><![CDATA[N]]></ATT_SHOWINDESCRIPTION>
+<!--5738F8786CA04941A68AD66EF04927CF--></OBUIAPP_PARAMETER>
+
 <!--5936B9348BFF4A78A84F2A735BFEB949--><OBUIAPP_PARAMETER>
 <!--5936B9348BFF4A78A84F2A735BFEB949-->  <OBUIAPP_PARAMETER_ID><![CDATA[5936B9348BFF4A78A84F2A735BFEB949]]></OBUIAPP_PARAMETER_ID>
 <!--5936B9348BFF4A78A84F2A735BFEB949-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -2278,6 +2307,31 @@
 <!--EE46B52D4E384C5BA3F44D15F0253042-->  <ATT_SHOWINDESCRIPTION><![CDATA[N]]></ATT_SHOWINDESCRIPTION>
 <!--EE46B52D4E384C5BA3F44D15F0253042--></OBUIAPP_PARAMETER>
 
+<!--EF0F86614DD8439DA948B956E21B2778--><OBUIAPP_PARAMETER>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <OBUIAPP_PARAMETER_ID><![CDATA[EF0F86614DD8439DA948B956E21B2778]]></OBUIAPP_PARAMETER_ID>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <NAME><![CDATA[Process Invoice]]></NAME>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <SEQNO><![CDATA[30]]></SEQNO>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <AD_REFERENCE_ID><![CDATA[20]]></AD_REFERENCE_ID>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <COLUMNNAME><![CDATA[processInvoice]]></COLUMNNAME>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <ISCENTRALLYMAINTAINED><![CDATA[Y]]></ISCENTRALLYMAINTAINED>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <FIELDLENGTH><![CDATA[0]]></FIELDLENGTH>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <ISMANDATORY><![CDATA[Y]]></ISMANDATORY>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <DEFAULTVALUE><![CDATA['Y']]></DEFAULTVALUE>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <AD_ELEMENT_ID><![CDATA[5B12F3FCB67D46568CED2DE9BCA8080E]]></AD_ELEMENT_ID>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <ISFIXED><![CDATA[N]]></ISFIXED>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <EVALUATEFIXEDVALUE><![CDATA[N]]></EVALUATEFIXEDVALUE>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <OBUIAPP_PROCESS_ID><![CDATA[62250E8866EA4D96A66C309878DC039E]]></OBUIAPP_PROCESS_ID>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <STARTINNEWLINE><![CDATA[N]]></STARTINNEWLINE>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <NUMCOLUMN><![CDATA[2]]></NUMCOLUMN>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <DISPLAYEDROWS><![CDATA[5]]></DISPLAYEDROWS>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <DISPLAYTITLE><![CDATA[Y]]></DISPLAYTITLE>
+<!--EF0F86614DD8439DA948B956E21B2778-->  <ATT_SHOWINDESCRIPTION><![CDATA[N]]></ATT_SHOWINDESCRIPTION>
+<!--EF0F86614DD8439DA948B956E21B2778--></OBUIAPP_PARAMETER>
+
 <!--F693A2C4889646C8AFD301133F7B0C1F--><OBUIAPP_PARAMETER>
 <!--F693A2C4889646C8AFD301133F7B0C1F-->  <OBUIAPP_PARAMETER_ID><![CDATA[F693A2C4889646C8AFD301133F7B0C1F]]></OBUIAPP_PARAMETER_ID>
 <!--F693A2C4889646C8AFD301133F7B0C1F-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -2327,6 +2381,33 @@
 <!--F8668E58C72D4919BC70B98EA45608A6-->  <ATT_SHOWINDESCRIPTION><![CDATA[N]]></ATT_SHOWINDESCRIPTION>
 <!--F8668E58C72D4919BC70B98EA45608A6--></OBUIAPP_PARAMETER>
 
+<!--FA8CA39EA0374C31A426878F80A1E851--><OBUIAPP_PARAMETER>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <OBUIAPP_PARAMETER_ID><![CDATA[FA8CA39EA0374C31A426878F80A1E851]]></OBUIAPP_PARAMETER_ID>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <NAME><![CDATA[Invoice Date]]></NAME>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <DESCRIPTION><![CDATA[The time listed on the invoice.]]></DESCRIPTION>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <HELP><![CDATA[The Date Invoice indicates the date printed on the invoice.]]></HELP>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <SEQNO><![CDATA[10]]></SEQNO>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <AD_REFERENCE_ID><![CDATA[15]]></AD_REFERENCE_ID>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <COLUMNNAME><![CDATA[DateInvoiced]]></COLUMNNAME>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <ISCENTRALLYMAINTAINED><![CDATA[Y]]></ISCENTRALLYMAINTAINED>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <FIELDLENGTH><![CDATA[0]]></FIELDLENGTH>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <ISMANDATORY><![CDATA[Y]]></ISMANDATORY>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <DEFAULTVALUE><![CDATA[@MovementDate@]]></DEFAULTVALUE>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <AD_ELEMENT_ID><![CDATA[267]]></AD_ELEMENT_ID>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <ISFIXED><![CDATA[N]]></ISFIXED>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <EVALUATEFIXEDVALUE><![CDATA[N]]></EVALUATEFIXEDVALUE>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <OBUIAPP_PROCESS_ID><![CDATA[62250E8866EA4D96A66C309878DC039E]]></OBUIAPP_PROCESS_ID>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <STARTINNEWLINE><![CDATA[N]]></STARTINNEWLINE>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <NUMCOLUMN><![CDATA[2]]></NUMCOLUMN>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <DISPLAYEDROWS><![CDATA[5]]></DISPLAYEDROWS>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <DISPLAYTITLE><![CDATA[Y]]></DISPLAYTITLE>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <ATT_SHOWINDESCRIPTION><![CDATA[N]]></ATT_SHOWINDESCRIPTION>
+<!--FA8CA39EA0374C31A426878F80A1E851--></OBUIAPP_PARAMETER>
+
 <!--FC9ABA9B85B04AF492CF3A17D84190DA--><OBUIAPP_PARAMETER>
 <!--FC9ABA9B85B04AF492CF3A17D84190DA-->  <OBUIAPP_PARAMETER_ID><![CDATA[FC9ABA9B85B04AF492CF3A17D84190DA]]></OBUIAPP_PARAMETER_ID>
 <!--FC9ABA9B85B04AF492CF3A17D84190DA-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-db/database/sourcedata/OBUIAPP_PROCESS.xml	Tue Nov 13 12:08:14 2018 +0100
+++ b/src-db/database/sourcedata/OBUIAPP_PROCESS.xml	Wed Nov 14 08:52:36 2018 +0100
@@ -341,6 +341,26 @@
 <!--5F7C5316CB7E4598898150AC88061B1B-->  <ISCANADDRECORDSTOSELECTOR><![CDATA[N]]></ISCANADDRECORDSTOSELECTOR>
 <!--5F7C5316CB7E4598898150AC88061B1B--></OBUIAPP_PROCESS>
 
+<!--62250E8866EA4D96A66C309878DC039E--><OBUIAPP_PROCESS>
+<!--62250E8866EA4D96A66C309878DC039E-->  <OBUIAPP_PROCESS_ID><![CDATA[62250E8866EA4D96A66C309878DC039E]]></OBUIAPP_PROCESS_ID>
+<!--62250E8866EA4D96A66C309878DC039E-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--62250E8866EA4D96A66C309878DC039E-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--62250E8866EA4D96A66C309878DC039E-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--62250E8866EA4D96A66C309878DC039E-->  <VALUE><![CDATA[InvoiceFromShipment]]></VALUE>
+<!--62250E8866EA4D96A66C309878DC039E-->  <NAME><![CDATA[Invoice From Shipment]]></NAME>
+<!--62250E8866EA4D96A66C309878DC039E-->  <DESCRIPTION><![CDATA[Generate Invoice from Goods Shipment]]></DESCRIPTION>
+<!--62250E8866EA4D96A66C309878DC039E-->  <HELP><![CDATA[Generate Invoice from Goods Shipment considering the Invoice Terms of Order linked to shipment lines]]></HELP>
+<!--62250E8866EA4D96A66C309878DC039E-->  <ACCESSLEVEL><![CDATA[1]]></ACCESSLEVEL>
+<!--62250E8866EA4D96A66C309878DC039E-->  <CLASSNAME><![CDATA[org.openbravo.common.actionhandler.InvoiceFromShipmentActionHandler]]></CLASSNAME>
+<!--62250E8866EA4D96A66C309878DC039E-->  <ISBACKGROUND><![CDATA[N]]></ISBACKGROUND>
+<!--62250E8866EA4D96A66C309878DC039E-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--62250E8866EA4D96A66C309878DC039E-->  <UIPATTERN><![CDATA[OBUIAPP_PickAndExecute]]></UIPATTERN>
+<!--62250E8866EA4D96A66C309878DC039E-->  <ISMULTIRECORD><![CDATA[N]]></ISMULTIRECORD>
+<!--62250E8866EA4D96A66C309878DC039E-->  <IS_EXPLICIT_ACCESS><![CDATA[N]]></IS_EXPLICIT_ACCESS>
+<!--62250E8866EA4D96A66C309878DC039E-->  <ISGRIDLEGACY><![CDATA[N]]></ISGRIDLEGACY>
+<!--62250E8866EA4D96A66C309878DC039E-->  <ISCANADDRECORDSTOSELECTOR><![CDATA[N]]></ISCANADDRECORDSTOSELECTOR>
+<!--62250E8866EA4D96A66C309878DC039E--></OBUIAPP_PROCESS>
+
 <!--653F9E5D2CCB48E081D98D000EE7CBCF--><OBUIAPP_PROCESS>
 <!--653F9E5D2CCB48E081D98D000EE7CBCF-->  <OBUIAPP_PROCESS_ID><![CDATA[653F9E5D2CCB48E081D98D000EE7CBCF]]></OBUIAPP_PROCESS_ID>
 <!--653F9E5D2CCB48E081D98D000EE7CBCF-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-db/database/sourcedata/OBUISEL_SELECTOR.xml	Tue Nov 13 12:08:14 2018 +0100
+++ b/src-db/database/sourcedata/OBUISEL_SELECTOR.xml	Wed Nov 14 08:52:36 2018 +0100
@@ -1346,6 +1346,23 @@
 <!--F879D55C4CEA4364BEC07ED3C002F230-->  <CUSTOM_QUERY><![CDATA[N]]></CUSTOM_QUERY>
 <!--F879D55C4CEA4364BEC07ED3C002F230--></OBUISEL_SELECTOR>
 
+<!--F954803216A54931B6AD296F337A81A9--><OBUISEL_SELECTOR>
+<!--F954803216A54931B6AD296F337A81A9-->  <OBUISEL_SELECTOR_ID><![CDATA[F954803216A54931B6AD296F337A81A9]]></OBUISEL_SELECTOR_ID>
+<!--F954803216A54931B6AD296F337A81A9-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--F954803216A54931B6AD296F337A81A9-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--F954803216A54931B6AD296F337A81A9-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--F954803216A54931B6AD296F337A81A9-->  <NAME><![CDATA[SalesPriceList]]></NAME>
+<!--F954803216A54931B6AD296F337A81A9-->  <AD_REFERENCE_ID><![CDATA[133F26E7C401427997D41E132940A78B]]></AD_REFERENCE_ID>
+<!--F954803216A54931B6AD296F337A81A9-->  <AD_TABLE_ID><![CDATA[255]]></AD_TABLE_ID>
+<!--F954803216A54931B6AD296F337A81A9-->  <WHERECLAUSE><![CDATA[e.salesPriceList = true]]></WHERECLAUSE>
+<!--F954803216A54931B6AD296F337A81A9-->  <FILTER_EXPRESSION><![CDATA[OB.getFilterExpression("org.openbravo.materialmgmt.InvoiceFromGoodsShipmentPriceListFilterExpression")]]></FILTER_EXPRESSION>
+<!--F954803216A54931B6AD296F337A81A9-->  <OBCLKER_TEMPLATE_ID><![CDATA[9314DE8599AD44E7BFC4CC50699042AB]]></OBCLKER_TEMPLATE_ID>
+<!--F954803216A54931B6AD296F337A81A9-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--F954803216A54931B6AD296F337A81A9-->  <SUGGESTIONTEXTMATCHSTYLE><![CDATA[startsWith]]></SUGGESTIONTEXTMATCHSTYLE>
+<!--F954803216A54931B6AD296F337A81A9-->  <POPUPTEXTMATCHSTYLE><![CDATA[startsWith]]></POPUPTEXTMATCHSTYLE>
+<!--F954803216A54931B6AD296F337A81A9-->  <CUSTOM_QUERY><![CDATA[N]]></CUSTOM_QUERY>
+<!--F954803216A54931B6AD296F337A81A9--></OBUISEL_SELECTOR>
+
 <!--FA5BC3AD909645C3BCF9384AE635009A--><OBUISEL_SELECTOR>
 <!--FA5BC3AD909645C3BCF9384AE635009A-->  <OBUISEL_SELECTOR_ID><![CDATA[FA5BC3AD909645C3BCF9384AE635009A]]></OBUISEL_SELECTOR_ID>
 <!--FA5BC3AD909645C3BCF9384AE635009A-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-test/src/org/openbravo/test/AllAntTaskTests.java	Tue Nov 13 12:08:14 2018 +0100
+++ b/src-test/src/org/openbravo/test/AllAntTaskTests.java	Wed Nov 14 08:52:36 2018 +0100
@@ -73,6 +73,7 @@
 import org.openbravo.test.expression.OBBindingsTest;
 import org.openbravo.test.generalsetup.enterprise.organization.ADOrgPersistInfoTestSuite;
 import org.openbravo.test.inventoryStatus.InventoryStatusTest;
+import org.openbravo.test.materialMgmt.invoiceFromShipment.InvoiceFromShipmentTest;
 import org.openbravo.test.materialMgmt.iscompletelyinvoicedshipment.IsCompletelyInvoicedShipment;
 import org.openbravo.test.model.ClassLoaderTest;
 import org.openbravo.test.model.DBModifiedTest;
@@ -313,7 +314,10 @@
     ReferencedInventoryTestSuite.class,
 
     // AD_Org Persist Information
-    ADOrgPersistInfoTestSuite.class
+    ADOrgPersistInfoTestSuite.class,
+    
+    // Automatic Invoice from Goods Shipment
+    InvoiceFromShipmentTest.class
 
 })
 public class AllAntTaskTests {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src-test/src/org/openbravo/test/materialMgmt/invoiceFromShipment/InvoiceFromShipmentTest.java	Wed Nov 14 08:52:36 2018 +0100
@@ -0,0 +1,905 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.1  (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) 2018 Openbravo SLU
+ * All Rights Reserved. 
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+
+package org.openbravo.test.materialMgmt.invoiceFromShipment;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import java.math.BigDecimal;
+import java.util.Calendar;
+import java.util.Date;
+
+import org.apache.commons.lang.time.DateUtils;
+import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.hibernate.query.Query;
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.openbravo.base.exception.OBException;
+import org.openbravo.base.secureApp.VariablesSecureApp;
+import org.openbravo.base.weld.WeldUtils;
+import org.openbravo.base.weld.test.WeldBaseTest;
+import org.openbravo.client.kernel.RequestContext;
+import org.openbravo.common.actionhandler.createlinesfromprocess.CreateInvoiceLinesFromProcess;
+import org.openbravo.dal.core.DalUtil;
+import org.openbravo.dal.core.OBContext;
+import org.openbravo.dal.service.OBDal;
+import org.openbravo.dal.service.OBQuery;
+import org.openbravo.erpCommon.utility.SequenceIdData;
+import org.openbravo.erpCommon.utility.Utility;
+import org.openbravo.materialmgmt.InvoiceGeneratorFromGoodsShipment;
+import org.openbravo.model.common.invoice.Invoice;
+import org.openbravo.model.common.invoice.InvoiceLine;
+import org.openbravo.model.common.order.Order;
+import org.openbravo.model.common.order.OrderLine;
+import org.openbravo.model.common.plm.Product;
+import org.openbravo.model.materialmgmt.transaction.ShipmentInOut;
+import org.openbravo.model.materialmgmt.transaction.ShipmentInOutLine;
+import org.openbravo.model.pricing.pricelist.PriceList;
+import org.openbravo.service.db.DalConnectionProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Test class for Automatic Invoice From Goods Shipment test cases
+ *
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class InvoiceFromShipmentTest extends WeldBaseTest {
+
+  private static final Logger log = LoggerFactory.getLogger(InvoiceFromShipmentTest.class);
+
+  private static final String CLIENT_ID = "4028E6C72959682B01295A070852010D"; // QA Testing
+  private static final String ORG_ID = "357947E87C284935AD1D783CF6F099A1"; // Spain
+  private static final String USER_ID = "100"; // Openbravo
+  private static final String ROLE_ID = "4028E6C72959682B01295A071429011E"; // QA Testing Admin
+
+  private static final String GOODS_SHIPMENT_ID = "8BEAC8CAFFCE444FA15D0170F897B641";
+  private static final String SALES_ORDER = "5B29AF263D004CD3830D4F9B23C17DFD";
+  private static final String SALES_INVOICE = "B859F1D34CD348998F4D54B571010C8F";
+  private static final String T_SHIRTS_PRODUCT_ID = "0CF7C882B8BD4D249F3BCC8727A736D1";
+  private static final String DO_NOT_INVOICE = "N";
+  private static final String IMMEDIATE = "I";
+  private static final String AFTER_DELIVERY = "D";
+  private static final String AFTER_ORDER_DELIVERY = "O";
+  private static final String PRICE_LIST_SALES_ID = "4028E6C72959682B01295ADC1D55022B";
+
+  @Before
+  public void initialize() {
+    log.info("Initializing Invoice From Shipment Tests ...");
+    OBContext.setOBContext(USER_ID, ROLE_ID, CLIENT_ID, ORG_ID);
+    final OBContext obContext = OBContext.getOBContext();
+    final VariablesSecureApp vars = new VariablesSecureApp(obContext.getUser().getId(), obContext
+        .getCurrentClient().getId(), obContext.getCurrentOrganization().getId(), obContext
+        .getRole().getId(), obContext.getLanguage().getLanguage());
+    RequestContext.get().setVariableSecureApp(vars);
+  }
+
+  /**
+   * Generating invoice from a Goods Shipment linked to a Sales Order with invoice term
+   * "After Delivery"
+   * <ol>
+   * <li>Create a Sales Order with invoice term "After Delivery".</li>
+   * <li>Adds two lines of product. Book the order.</li>
+   * <li>Create a Goods Shipment.</li>
+   * <li>Adds just one line from the previous order.</li>
+   * <li>Complete the document invoicing if possible.</li>
+   * <li>Verify an invoice was created and processed containing the line from Goods Shipment.</li>
+   * </ol>
+   */
+  @Test
+  public void invoiceFromShipment_001() {
+    OBContext.setAdminMode();
+    try {
+
+      final Product product = TestUtils
+          .cloneProduct(T_SHIRTS_PRODUCT_ID, "InvoiceFromShipment_001");
+      final Order salesOrder = createSalesOrderWithInvoiceTerm(SALES_ORDER,
+          "InvoiceFromShipment_001", AFTER_DELIVERY);
+      final OrderLine orderLine = getOrderLineByLineNo(salesOrder, 10L);
+      setProductInOrderLine(orderLine, product);
+      TestUtils.processOrder(salesOrder);
+
+      final ShipmentInOut shipment = TestUtils.cloneReceiptShipment(GOODS_SHIPMENT_ID,
+          "InvoiceFromShipment_001");
+      final ShipmentInOutLine shipmentLine = getShipmentLineByLineNo(shipment, 10L);
+      setProductInShipmentLine(shipmentLine, product);
+      setOrderLineInShipmentLine(shipmentLine, orderLine);
+      TestUtils.processShipmentReceipt(shipment);
+
+      final Invoice invoice = new InvoiceGeneratorFromGoodsShipment(shipment.getId())
+          .createInvoiceConsideringInvoiceTerms(true);
+      assertGeneratedInvoiceLine(invoice, product, new BigDecimal(12));
+      assertInvoiceDatePriceListAndStatus(invoice, shipment.getMovementDate(),
+          salesOrder.getPriceList(), "CO");
+
+    } catch (Exception e) {
+      log.error(e.getMessage(), e);
+      throw new OBException(e);
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+  }
+
+  /**
+   * Generating invoice from a Goods Shipment linked to a Sales Order with invoice term
+   * "After Order Delivery"
+   * <ol>
+   * <li>Create a Sales Order with invoice term "After Order Delivery".</li>
+   * <li>Adds two lines of product. Book the order.</li>
+   * <li>Create a Goods Shipment.</li>
+   * <li>Adds the first line from the previous order.</li>
+   * <li>Complete the document invoicing if possible.</li>
+   * <li>Verify no invoice was created.</li>
+   * <li>Create a Goods Shipment.</li>
+   * <li>Adds the second line from the previous order.</li>
+   * <li>Complete the document invoicing if possible.</li>
+   * <li>Verify an invoice was created and processed containing the two lines from Sales Order.</li>
+   * </ol>
+   */
+
+  @Test
+  public void invoiceFromShipment_002() {
+    OBContext.setAdminMode();
+    try {
+
+      final Product productOne = TestUtils.cloneProduct(T_SHIRTS_PRODUCT_ID,
+          "InvoiceFromShipment_002");
+      final Product productTwo = TestUtils.cloneProduct(T_SHIRTS_PRODUCT_ID,
+          "InvoiceFromShipment_002");
+
+      final Order salesOrder = createAfterOrderDeliveredOrder(SALES_ORDER,
+          "InvoiceFromShipment_002");
+      final OrderLine firstLine = getOrderLineByLineNo(salesOrder, 10L);
+      setProductInOrderLine(firstLine, productOne);
+      final OrderLine secondLine = getOrderLineByLineNo(salesOrder, 20L);
+      setProductInOrderLine(secondLine, productTwo);
+      TestUtils.processOrder(salesOrder);
+
+      final ShipmentInOut shipment = TestUtils.cloneReceiptShipment(GOODS_SHIPMENT_ID,
+          "InvoiceFromShipment_002");
+      final ShipmentInOutLine shipmentLine = getShipmentLineByLineNo(shipment, 10L);
+      setProductInShipmentLine(shipmentLine, productOne);
+      setOrderLineInShipmentLine(shipmentLine, firstLine);
+      TestUtils.processShipmentReceipt(shipment);
+      OBDal.getInstance().refresh(salesOrder); // Necessary to update the delivery status
+
+      final Invoice invoice = new InvoiceGeneratorFromGoodsShipment(shipment.getId())
+          .createInvoiceConsideringInvoiceTerms(true);
+      assertNoInvoiceWasGenerated(invoice);
+
+      final ShipmentInOut secondShipment = TestUtils.cloneReceiptShipment(GOODS_SHIPMENT_ID,
+          "InvoiceFromShipment_002");
+      final ShipmentInOutLine secondShipmentLine = getShipmentLineByLineNo(secondShipment, 10L);
+      setProductInShipmentLine(secondShipmentLine, productTwo);
+      setOrderLineInShipmentLine(secondShipmentLine, secondLine);
+      TestUtils.processShipmentReceipt(secondShipment);
+      OBDal.getInstance().getSession().clear(); // Necessary to force DAL to refresh objects status
+
+      final Invoice secondInvoice = new InvoiceGeneratorFromGoodsShipment(secondShipment.getId())
+          .createInvoiceConsideringInvoiceTerms(true);
+      assertGeneratedInvoiceLine(secondInvoice, productOne, new BigDecimal(12));
+      assertGeneratedInvoiceLine(secondInvoice, productTwo, new BigDecimal(12));
+      assertInvoiceDatePriceListAndStatus(secondInvoice, secondShipment.getMovementDate(),
+          salesOrder.getPriceList(), "CO");
+    } catch (Exception e) {
+      log.error(e.getMessage(), e);
+      throw new OBException(e);
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+  }
+
+  /**
+   * Generating invoice from Goods Shipment not linked to a Sales Order
+   * <ol>
+   * <li>Create a Goods Shipment.</li>
+   * <li>Adds two lines of product.</li>
+   * <li>Complete the document invoicing if possible.</li>
+   * <li>Verify an invoice was created and processed containing the lines from Goods Shipment.</li>
+   * </ol>
+   */
+
+  @Test
+  public void invoiceFromShipment_003() {
+    OBContext.setAdminMode();
+    try {
+
+      final Product productOne = TestUtils.cloneProduct(T_SHIRTS_PRODUCT_ID,
+          "InvoiceFromShipment_003");
+      final Product productTwo = TestUtils.cloneProduct(T_SHIRTS_PRODUCT_ID,
+          "InvoiceFromShipment_003");
+
+      final ShipmentInOut shipment = createShipmentReceiptWithTwoLines(GOODS_SHIPMENT_ID,
+          "InvoiceFromShipment_003");
+
+      final ShipmentInOutLine firstShipmentLine = getShipmentLineByLineNo(shipment, 10L);
+      setProductInShipmentLine(firstShipmentLine, productOne);
+      ShipmentInOutLine secondShipmentLine = getShipmentLineByLineNo(shipment, 20L);
+      setProductInShipmentLine(secondShipmentLine, productTwo);
+
+      TestUtils.processShipmentReceipt(shipment);
+      final PriceList priceList = shipment.getBusinessPartner().getPriceList();
+
+      final Invoice invoice = new InvoiceGeneratorFromGoodsShipment(shipment.getId())
+          .createInvoiceConsideringInvoiceTerms(true);
+      assertGeneratedInvoiceLine(invoice, productOne, new BigDecimal(12));
+      assertGeneratedInvoiceLine(invoice, productTwo, new BigDecimal(12));
+      assertInvoiceDatePriceListAndStatus(invoice, shipment.getMovementDate(), priceList, "CO");
+    } catch (Exception e) {
+      log.error(e.getMessage(), e);
+      throw new OBException(e);
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+  }
+
+  /**
+   * Generating invoice from Goods Shipment with lines linked to Sales Order with invoice term
+   * “After Delivery” and “After Order Delivery”.
+   * <ol>
+   * <li>Create a Sales Order with invoice term “After Delivery”.</li>
+   * <li>Add one line of product. Book the order.</li>
+   * <li>Create a second Sales Order with invoice term “After Order Delivery”.</li>
+   * <li>Add two lines of product. Book the order.</li>
+   * <li>Create a Goods Shipment</li>
+   * <li>Add the line from the first order</li>
+   * <li>Add the first line from the second order</li>
+   * <li>Add a line manually</li>
+   * <li>Complete the document invoicing if possible</li>
+   * <li>Verify an invoice was created with the line from the first order and the one added
+   * manually.</li>
+   * <li>Create a second Goods Shipment</li>
+   * <li>Add the second line from the second order</li>
+   * <li>Complete the document invoicing if possible</li>
+   * <li>Verify an invoice was created containing both lines from the second order.</li>
+   * </ol>
+   */
+
+  @Test
+  public void invoiceFromShipment_004() {
+    OBContext.setAdminMode();
+    try {
+
+      final Product productOne = TestUtils.cloneProduct(T_SHIRTS_PRODUCT_ID,
+          "InvoiceFromShipment_004");
+      final Product productTwo = TestUtils.cloneProduct(T_SHIRTS_PRODUCT_ID,
+          "InvoiceFromShipment_004");
+      final Product productThree = TestUtils.cloneProduct(T_SHIRTS_PRODUCT_ID,
+          "InvoiceFromShipment_004");
+      final Product productFour = TestUtils.cloneProduct(T_SHIRTS_PRODUCT_ID,
+          "InvoiceFromShipment_004");
+
+      final Order firstSalesOrder = createSalesOrderWithInvoiceTerm(SALES_ORDER,
+          "InvoiceFromShipment_004", AFTER_DELIVERY);
+      final OrderLine firstLine = getOrderLineByLineNo(firstSalesOrder, 10L);
+      setProductInOrderLine(firstLine, productOne);
+      TestUtils.processOrder(firstSalesOrder);
+
+      final Order secondSalesOrder = createAfterOrderDeliveredOrder(SALES_ORDER,
+          "InvoiceFromShipment_004");
+      final OrderLine secondLine = getOrderLineByLineNo(secondSalesOrder, 10L);
+      setProductInOrderLine(secondLine, productTwo);
+      final OrderLine thirdLine = getOrderLineByLineNo(secondSalesOrder, 20L);
+      setProductInOrderLine(thirdLine, productThree);
+      TestUtils.processOrder(secondSalesOrder);
+
+      final ShipmentInOut shipment = createShipmentReceiptWithTwoLines(GOODS_SHIPMENT_ID,
+          "InvoiceFromShipment_004");
+      final ShipmentInOutLine firstShipmentLine = getShipmentLineByLineNo(shipment, 10L);
+      setProductInShipmentLine(firstShipmentLine, productOne);
+      setOrderLineInShipmentLine(firstShipmentLine, firstLine);
+      final ShipmentInOutLine secondShipmentLine = getShipmentLineByLineNo(shipment, 20L);
+      setProductInShipmentLine(secondShipmentLine, productTwo);
+      setOrderLineInShipmentLine(secondShipmentLine, secondLine);
+      final ShipmentInOutLine thirdShipmentLine = addLineToShipment(shipment);
+      setProductInShipmentLine(thirdShipmentLine, productFour);
+      setOrderLineInShipmentLine(thirdShipmentLine, null);
+
+      TestUtils.processShipmentReceipt(shipment);
+      OBDal.getInstance().refresh(firstSalesOrder); // Necessary to update the delivery status
+      OBDal.getInstance().refresh(secondSalesOrder); // Necessary to update the delivery status
+
+      final Invoice invoice = new InvoiceGeneratorFromGoodsShipment(shipment.getId())
+          .createInvoiceConsideringInvoiceTerms(true);
+      assertInvoiceLineNumber(invoice, 2);
+      assertGeneratedInvoiceLine(invoice, productOne, new BigDecimal(12));
+      assertGeneratedInvoiceLine(invoice, productFour, new BigDecimal(12));
+      assertInvoiceDatePriceListAndStatus(invoice, shipment.getMovementDate(),
+          firstSalesOrder.getPriceList(), "CO");
+
+      final ShipmentInOut secondShipment = TestUtils.cloneReceiptShipment(GOODS_SHIPMENT_ID,
+          "InvoiceFromShipment_004");
+      final ShipmentInOutLine fourthShipmentLine = getShipmentLineByLineNo(secondShipment, 10L);
+      setProductInShipmentLine(fourthShipmentLine, productThree);
+      setOrderLineInShipmentLine(fourthShipmentLine, thirdLine);
+
+      TestUtils.processShipmentReceipt(secondShipment);
+      OBDal.getInstance().getSession().clear(); // Necessary to force DAL to refresh objects status
+
+      final Invoice secondInvoice = new InvoiceGeneratorFromGoodsShipment(secondShipment.getId())
+          .createInvoiceConsideringInvoiceTerms(true);
+      assertInvoiceLineNumber(secondInvoice, 2);
+      assertGeneratedInvoiceLine(secondInvoice, productTwo, new BigDecimal(12));
+      assertGeneratedInvoiceLine(secondInvoice, productThree, new BigDecimal(12));
+      assertInvoiceDatePriceListAndStatus(invoice, shipment.getMovementDate(),
+          firstSalesOrder.getPriceList(), "CO");
+    } catch (Exception e) {
+      log.error(e.getMessage(), e);
+      throw new OBException(e);
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+  }
+
+  /**
+   * Generating invoice from Goods Shipment with incomplete delivery
+   * <ol>
+   * <li>Create a Sales Order win invoice term “After Delivery”.</li>
+   * <li>Adds one line of product. Book the order.</li>
+   * <li>Create a second Sales Order with invoice term “After Order Delivery”.</li>
+   * <li>Adds one line of product. Book the order.</li>
+   * <li>Create a Goods Shipment.</li>
+   * <li>Adds the line from the first order. Set movement quantity less than the proposed value.</li>
+   * <li>Adds the line from the second order. Set movement quantity less than the proposed value.</li>
+   * <li>Complete the document invoicing if possible.</li>
+   * <li>Verify an invoice was generated containing just the line from the first order</li>
+   * </ol>
+   */
+
+  @Test
+  public void invoiceFromShipment_005() {
+    OBContext.setAdminMode();
+    try {
+
+      final Product productOne = TestUtils.cloneProduct(T_SHIRTS_PRODUCT_ID,
+          "InvoiceFromShipment_005");
+      final Product productTwo = TestUtils.cloneProduct(T_SHIRTS_PRODUCT_ID,
+          "InvoiceFromShipment_005");
+
+      final Order firstSalesOrder = createSalesOrderWithInvoiceTerm(SALES_ORDER,
+          "InvoiceFromShipment_005", AFTER_DELIVERY);
+      final OrderLine firstLine = getOrderLineByLineNo(firstSalesOrder, 10L);
+      setProductInOrderLine(firstLine, productOne);
+      TestUtils.processOrder(firstSalesOrder);
+
+      final Order secondSalesOrder = createSalesOrderWithInvoiceTerm(SALES_ORDER,
+          "InvoiceFromShipment_005", AFTER_ORDER_DELIVERY);
+      final OrderLine secondLine = getOrderLineByLineNo(secondSalesOrder, 10L);
+      setProductInOrderLine(secondLine, productTwo);
+      TestUtils.processOrder(secondSalesOrder);
+
+      final ShipmentInOut shipment = createShipmentReceiptWithTwoLines(GOODS_SHIPMENT_ID,
+          "InvoiceFromShipment_005");
+      final ShipmentInOutLine firstShipmentLine = getShipmentLineByLineNo(shipment, 10L);
+      setProductInShipmentLine(firstShipmentLine, productOne);
+      setOrderLineInShipmentLine(firstShipmentLine, firstLine);
+      updateMovementQuantity(firstShipmentLine, BigDecimal.TEN);
+      final ShipmentInOutLine secondShipmentLine = getShipmentLineByLineNo(shipment, 20L);
+      setProductInShipmentLine(secondShipmentLine, productTwo);
+      setOrderLineInShipmentLine(secondShipmentLine, secondLine);
+      updateMovementQuantity(secondShipmentLine, BigDecimal.TEN);
+
+      TestUtils.processShipmentReceipt(shipment);
+      OBDal.getInstance().refresh(firstSalesOrder); // Necessary to update the delivery status
+      OBDal.getInstance().refresh(secondSalesOrder); // Necessary to update the delivery status
+
+      final Invoice invoice = new InvoiceGeneratorFromGoodsShipment(shipment.getId())
+          .createInvoiceConsideringInvoiceTerms(true);
+      assertInvoiceLineNumber(invoice, 1);
+      assertGeneratedInvoiceLine(invoice, productOne, BigDecimal.TEN);
+      assertInvoiceDatePriceListAndStatus(invoice, shipment.getMovementDate(),
+          firstSalesOrder.getPriceList(), "CO");
+    } catch (Exception e) {
+      log.error(e.getMessage(), e);
+      throw new OBException(e);
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+  }
+
+  /**
+   * Generating invoice from Goods Shipment with lines linked to Sales Order with invoice terms
+   * “Immediate” and “Do not invoice”
+   * <ol>
+   * <li>Create a Sales Order with invoice term “Immediate”</li>
+   * <li>Add one line of product. Book the order.</li>
+   * <li>Create a Sales Order with invoice term “Do not invoice”.</li>
+   * <li>Add one line to the order. Book the order.</li>
+   * <li>Create a Goods Shipment with the lines from the two orders.</li>
+   * <li>Complete the document invoicing if possible.</li>
+   * <li>Verify an invoice was created containing a line linked to the shipment line from
+   * "Immediate" Sales Order</li>
+   * </ol>
+   */
+
+  @Test
+  public void invoiceFromShipment_006() {
+    OBContext.setAdminMode();
+    try {
+
+      final Product productOne = TestUtils.cloneProduct(T_SHIRTS_PRODUCT_ID,
+          "InvoiceFromShipment_006");
+      final Product productTwo = TestUtils.cloneProduct(T_SHIRTS_PRODUCT_ID,
+          "InvoiceFromShipment_006");
+
+      final Order firstSalesOrder = createSalesOrderWithInvoiceTerm(SALES_ORDER,
+          "InvoiceFromShipment_006", IMMEDIATE);
+      final OrderLine firstLine = getOrderLineByLineNo(firstSalesOrder, 10L);
+      setProductInOrderLine(firstLine, productOne);
+      TestUtils.processOrder(firstSalesOrder);
+
+      final Order secondSalesOrder = createSalesOrderWithInvoiceTerm(SALES_ORDER,
+          "InvoiceFromShipment_006", DO_NOT_INVOICE);
+      final OrderLine secondLine = getOrderLineByLineNo(secondSalesOrder, 10L);
+      setProductInOrderLine(secondLine, productTwo);
+      TestUtils.processOrder(secondSalesOrder);
+
+      final ShipmentInOut shipment = createShipmentReceiptWithTwoLines(GOODS_SHIPMENT_ID,
+          "InvoiceFromShipment_006");
+      final ShipmentInOutLine firstShipmentLine = getShipmentLineByLineNo(shipment, 10L);
+      setProductInShipmentLine(firstShipmentLine, productOne);
+      setOrderLineInShipmentLine(firstShipmentLine, firstLine);
+      final ShipmentInOutLine secondShipmentLine = getShipmentLineByLineNo(shipment, 20L);
+      setProductInShipmentLine(secondShipmentLine, productTwo);
+      setOrderLineInShipmentLine(secondShipmentLine, secondLine);
+
+      TestUtils.processShipmentReceipt(shipment);
+
+      final Invoice invoice = new InvoiceGeneratorFromGoodsShipment(shipment.getId())
+          .createInvoiceConsideringInvoiceTerms(true);
+      assertInvoiceLineNumber(invoice, 1);
+      assertGeneratedInvoiceLine(invoice, productOne, new BigDecimal(12));
+      assertInvoiceDatePriceListAndStatus(invoice, shipment.getMovementDate(),
+          firstSalesOrder.getPriceList(), "CO");
+    } catch (Exception e) {
+      log.error(e.getMessage(), e);
+      throw new OBException(e);
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+  }
+
+  /**
+   * Generating invoice from Goods Shipment with lines partially invoiced from an order with invoice
+   * term “After Order Delivery”
+   * <ol>
+   * <li>Create a Sales Order with invoice term “After Order Delivery”.</li>
+   * <li>Add two lines of product. Book the order.</li>
+   * <li>Create a Goods Shipment.</li>
+   * <li>Add the first order line.</li>
+   * <li>Complete the document without invoicing.</li>
+   * <li>Create a second Goods Shipment.</li>
+   * <li>Add the second order line.</li>
+   * <li>Complete the document without invoicing.</li>
+   * <li>Create a Sales Invoice.</li>
+   * <li>Add the line for the first Goods Shipment.</li>
+   * <li>Invoice a quantity less than the movement quantity.</li>
+   * <li>Complete the document.</li>
+   * <li>Select the second Goods Shipment in Goods Shipment window.</li>
+   * <li>Generate invoice from shipment using the button.</li>
+   * <li>Verify a new invoice was created containing:</li>
+   * <ol>
+   * <li>A line with the product of the first Goods Shipment, and invoiced quantity as the
+   * difference between the movement quantity and the invoiced quantity of the Sales Invoice.</li>
+   * <li>A line with the product of the second Goods Shipment with invoiced quantity as the movement
+   * quantity</li>
+   * </ol>
+   * </ol>
+   */
+  @Test
+  public void invoiceFromShipment_007() {
+    OBContext.setAdminMode();
+    try {
+
+      final Product productOne = TestUtils.cloneProduct(T_SHIRTS_PRODUCT_ID,
+          "InvoiceFromShipment_007");
+      final Product productTwo = TestUtils.cloneProduct(T_SHIRTS_PRODUCT_ID,
+          "InvoiceFromShipment_007");
+
+      final Order salesOrder = createAfterOrderDeliveredOrder(SALES_ORDER,
+          "InvoiceFromShipment_007");
+      final OrderLine firstLine = getOrderLineByLineNo(salesOrder, 10L);
+      setProductInOrderLine(firstLine, productOne);
+      final OrderLine secondLine = getOrderLineByLineNo(salesOrder, 20L);
+      setProductInOrderLine(secondLine, productTwo);
+      TestUtils.processOrder(salesOrder);
+
+      final ShipmentInOut firstShipment = TestUtils.cloneReceiptShipment(GOODS_SHIPMENT_ID,
+          "InvoiceFromShipment_007");
+      final ShipmentInOutLine firstShipmentLine = getShipmentLineByLineNo(firstShipment, 10L);
+      setProductInShipmentLine(firstShipmentLine, productOne);
+      setOrderLineInShipmentLine(firstShipmentLine, firstLine);
+
+      TestUtils.processShipmentReceipt(firstShipment);
+
+      final Invoice invoice = createInvoiceFromShipment(firstShipment, SALES_INVOICE);
+      TestUtils.processInvoice(invoice);
+
+      final ShipmentInOut secondShipment = TestUtils.cloneReceiptShipment(GOODS_SHIPMENT_ID,
+          "InvoiceFromShipment_007");
+      final ShipmentInOutLine secondShipmentLine = getShipmentLineByLineNo(secondShipment, 10L);
+      setProductInShipmentLine(secondShipmentLine, productTwo);
+      setOrderLineInShipmentLine(secondShipmentLine, secondLine);
+
+      TestUtils.processShipmentReceipt(secondShipment);
+
+      final Invoice secondInvoice = new InvoiceGeneratorFromGoodsShipment(secondShipment.getId())
+          .createInvoiceConsideringInvoiceTerms(true);
+      assertInvoiceLineNumber(secondInvoice, 2);
+      assertGeneratedInvoiceLine(secondInvoice, productOne, new BigDecimal(2));
+      assertGeneratedInvoiceLine(secondInvoice, productTwo, new BigDecimal(12));
+      assertInvoiceDatePriceListAndStatus(secondInvoice, secondShipment.getMovementDate(),
+          salesOrder.getPriceList(), "CO");
+    } catch (Exception e) {
+      log.error(e.getMessage(), e);
+      throw new OBException(e);
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+  }
+
+  /**
+   * Verify no invoice is generated when processing a Goods Shipment after being previously
+   * processed
+   * <ol>
+   * <li>Create a Sales Order with invoice term "After Delivery".</li>
+   * <li>Adds two lines of product. Book the order.</li>
+   * <li>Create a Goods Shipment.</li>
+   * <li>Adds just one line from the previous order.</li>
+   * <li>Complete the document invoicing if possible.</li>
+   * <li>Verify an invoice was created and processed containing the line from Goods Shipment.</li>
+   * <li>Process the shipment a second time</li>
+   * <li>Verify no invoice was generated</li>
+   * </ol>
+   */
+
+  @Test
+  public void invoiceFromShipment_008() {
+    OBContext.setAdminMode();
+    try {
+      final Product product = TestUtils
+          .cloneProduct(T_SHIRTS_PRODUCT_ID, "InvoiceFromShipment_008");
+      final Order salesOrder = createSalesOrderWithInvoiceTerm(SALES_ORDER,
+          "InvoiceFromShipment_008", AFTER_DELIVERY);
+      final OrderLine orderLine = getOrderLineByLineNo(salesOrder, 10L);
+      setProductInOrderLine(orderLine, product);
+      TestUtils.processOrder(salesOrder);
+
+      final ShipmentInOut shipment = TestUtils.cloneReceiptShipment(GOODS_SHIPMENT_ID,
+          "InvoiceFromShipment_008");
+      final ShipmentInOutLine shipmentLine = getShipmentLineByLineNo(shipment, 10L);
+      setProductInShipmentLine(shipmentLine, product);
+      setOrderLineInShipmentLine(shipmentLine, orderLine);
+      TestUtils.processShipmentReceipt(shipment);
+
+      final Invoice invoice = new InvoiceGeneratorFromGoodsShipment(shipment.getId())
+          .createInvoiceConsideringInvoiceTerms(true);
+      assertInvoiceLineNumber(invoice, 1);
+      assertGeneratedInvoiceLine(invoice, product, new BigDecimal(12));
+      assertInvoiceDatePriceListAndStatus(invoice, shipment.getMovementDate(),
+          salesOrder.getPriceList(), "CO");
+      OBDal.getInstance().refresh(orderLine); // Necessary to force DAL to refresh invoiced qty
+
+      final Invoice secondInvoice = new InvoiceGeneratorFromGoodsShipment(shipment.getId())
+          .createInvoiceConsideringInvoiceTerms(false);
+      assertNoInvoiceWasGenerated(secondInvoice);
+
+    } catch (Exception e) {
+      log.error(e.getMessage(), e);
+      throw new OBException(e);
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+  }
+
+  /**
+   * Generating invoice from a Goods Shipment linked to a Sales Order with invoice term
+   * "After Delivery" and specific invoice date and price list
+   * <ol>
+   * <li>Create a Sales Order with invoice term "After Delivery".</li>
+   * <li>Adds two lines of product. Book the order.</li>
+   * <li>Create a Goods Shipment.</li>
+   * <li>Adds just one line from the previous order.</li>
+   * <li>Complete the document invoicing if possible with invoice date tomorrow and price list
+   * "Sales"</li>
+   * <li>Verify an invoice was created and processed containing the line from Goods Shipment with
+   * invoice date tomorrow and price list "Sales".</li>
+   * </ol>
+   */
+  @Test
+  public void invoiceFromShipment_009() {
+    OBContext.setAdminMode();
+    try {
+
+      final Product product = TestUtils
+          .cloneProduct(T_SHIRTS_PRODUCT_ID, "InvoiceFromShipment_009");
+      final Order salesOrder = createSalesOrderWithInvoiceTerm(SALES_ORDER,
+          "InvoiceFromShipment_009", AFTER_DELIVERY);
+      final OrderLine orderLine = getOrderLineByLineNo(salesOrder, 10L);
+      setProductInOrderLine(orderLine, product);
+      TestUtils.processOrder(salesOrder);
+
+      final ShipmentInOut shipment = TestUtils.cloneReceiptShipment(GOODS_SHIPMENT_ID,
+          "InvoiceFromShipment_009");
+      final ShipmentInOutLine shipmentLine = getShipmentLineByLineNo(shipment, 10L);
+      setProductInShipmentLine(shipmentLine, product);
+      setOrderLineInShipmentLine(shipmentLine, orderLine);
+      TestUtils.processShipmentReceipt(shipment);
+
+      Calendar calendar = Calendar.getInstance();
+      calendar.add(Calendar.DAY_OF_MONTH, 1);
+      Date invoiceDate = calendar.getTime();
+
+      PriceList priceList = OBDal.getInstance().get(PriceList.class, PRICE_LIST_SALES_ID);
+
+      final Invoice invoice = new InvoiceGeneratorFromGoodsShipment(shipment.getId(), invoiceDate,
+          priceList).createInvoiceConsideringInvoiceTerms(true);
+      assertGeneratedInvoiceLine(invoice, product, new BigDecimal(12));
+      assertInvoiceDatePriceListAndStatus(invoice, invoiceDate, priceList, "CO");
+
+    } catch (Exception e) {
+      log.error(e.getMessage(), e);
+      throw new OBException(e);
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+  }
+
+  /**
+   * Generating invoice from a Goods Shipment linked to a Sales Order with invoice term
+   * "After Delivery" and specific invoice date, price list and status draft
+   * <ol>
+   * <li>Create a Sales Order with invoice term "After Delivery".</li>
+   * <li>Adds two lines of product. Book the order.</li>
+   * <li>Create a Goods Shipment.</li>
+   * <li>Adds just one line from the previous order.</li>
+   * <li>Complete the document invoicing if possible with invoice date tomorrow, price list "Sales",
+   * and not processing the invoice</li>
+   * <li>Verify an invoice was created and processed containing the line from Goods Shipment with
+   * invoice date tomorrow, price list "Sales" and document status draft</li>
+   * </ol>
+   */
+  @Test
+  public void invoiceFromShipment_010() {
+    OBContext.setAdminMode();
+    try {
+
+      final Product product = TestUtils
+          .cloneProduct(T_SHIRTS_PRODUCT_ID, "InvoiceFromShipment_010");
+      final Order salesOrder = createSalesOrderWithInvoiceTerm(SALES_ORDER,
+          "InvoiceFromShipment_010", AFTER_DELIVERY);
+      final OrderLine orderLine = getOrderLineByLineNo(salesOrder, 10L);
+      setProductInOrderLine(orderLine, product);
+      TestUtils.processOrder(salesOrder);
+
+      final ShipmentInOut shipment = TestUtils.cloneReceiptShipment(GOODS_SHIPMENT_ID,
+          "InvoiceFromShipment_010");
+      final ShipmentInOutLine shipmentLine = getShipmentLineByLineNo(shipment, 10L);
+      setProductInShipmentLine(shipmentLine, product);
+      setOrderLineInShipmentLine(shipmentLine, orderLine);
+      TestUtils.processShipmentReceipt(shipment);
+
+      Calendar calendar = Calendar.getInstance();
+      calendar.add(Calendar.DAY_OF_MONTH, 1);
+      Date invoiceDate = calendar.getTime();
+
+      PriceList priceList = OBDal.getInstance().get(PriceList.class, PRICE_LIST_SALES_ID);
+
+      final Invoice invoice = new InvoiceGeneratorFromGoodsShipment(shipment.getId(), invoiceDate,
+          priceList).createInvoiceConsideringInvoiceTerms(false);
+      assertGeneratedInvoiceLine(invoice, product, new BigDecimal(12));
+      assertInvoiceDatePriceListAndStatus(invoice, invoiceDate, priceList, "DR");
+
+    } catch (Exception e) {
+      log.error(e.getMessage(), e);
+      throw new OBException(e);
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+  }
+
+  private Order createSalesOrderWithInvoiceTerm(String salesOrderId, String docNno,
+      String invoiceTerm) {
+    final Order salesOrder = TestUtils.cloneOrder(salesOrderId, docNno);
+    salesOrder.setInvoiceTerms(invoiceTerm);
+    return salesOrder;
+  }
+
+  private Order createAfterOrderDeliveredOrder(String salesOrderWithOneLineId, String docNo) {
+    final Order salesOrder = TestUtils.cloneOrder(salesOrderWithOneLineId, docNo);
+    salesOrder.setInvoiceTerms(AFTER_ORDER_DELIVERY);
+    final OrderLine orderLine = salesOrder.getOrderLineList().get(0);
+    final OrderLine newOrderLine = TestUtils.cloneOrderLine(orderLine, salesOrder);
+    newOrderLine.setLineNo(orderLine.getLineNo() + 10);
+    OBDal.getInstance().flush();
+    return salesOrder;
+  }
+
+  private void setProductInOrderLine(final OrderLine orderLine, final Product product) {
+    orderLine.setProduct(product);
+  }
+
+  private ShipmentInOut createShipmentReceiptWithTwoLines(String goodsShipmentId, String docNo) {
+    final ShipmentInOut shipment = TestUtils.cloneReceiptShipment(goodsShipmentId, docNo);
+    final ShipmentInOutLine shipmentLine = shipment.getMaterialMgmtShipmentInOutLineList().get(0);
+    final ShipmentInOutLine newShipmentLine = TestUtils.cloneReceiptShipmentLine(shipmentLine,
+        shipment);
+    newShipmentLine.setLineNo(shipmentLine.getLineNo() + 10);
+    OBDal.getInstance().flush();
+    return shipment;
+  }
+
+  private void setProductInShipmentLine(final ShipmentInOutLine shipmentLine, final Product product) {
+    shipmentLine.setProduct(product);
+  }
+
+  private void setOrderLineInShipmentLine(final ShipmentInOutLine shipmentLine,
+      final OrderLine orderLine) {
+    shipmentLine.setSalesOrderLine(orderLine);
+  }
+
+  private void updateMovementQuantity(final ShipmentInOutLine shipmentLine,
+      final BigDecimal movementQuantity) {
+    shipmentLine.setMovementQuantity(movementQuantity);
+  }
+
+  private void assertInvoiceLineNumber(final Invoice invoice, final int numLines) {
+    assertThat("Invoice should have " + numLines + " lines", invoice.getInvoiceLineList().size(),
+        equalTo(numLines));
+  }
+
+  private void assertNoInvoiceWasGenerated(final Invoice invoice) {
+    assertThat("Invoice should be null", invoice == null, equalTo(true));
+  }
+
+  private void assertGeneratedInvoiceLine(final Invoice invoice, final Product product,
+      final BigDecimal quantity) {
+    assertThat("Invoice should not be null", invoice == null, equalTo(false));
+    final InvoiceLine invoiceLine = getInvoiceLineByProductQuantity(invoice, product, quantity);
+    assertThat("Invoice Line should have the product " + product, invoiceLine == null,
+        equalTo(false));
+  }
+
+  private ShipmentInOutLine addLineToShipment(final ShipmentInOut shipment) {
+    int numberOfLines = shipment.getMaterialMgmtShipmentInOutLineList().size();
+    final ShipmentInOutLine shipmentLine = shipment.getMaterialMgmtShipmentInOutLineList().get(
+        numberOfLines - 1);
+    final ShipmentInOutLine newShipmentLine = TestUtils.cloneReceiptShipmentLine(shipmentLine,
+        shipment);
+    newShipmentLine.setLineNo(getMaxLineNo(shipment) + 10);
+    OBDal.getInstance().flush();
+    return newShipmentLine;
+  }
+
+  private Long getMaxLineNo(final ShipmentInOut shipment) {
+    final String hql = "select coalesce(max(sl.lineNo), 0) from MaterialMgmtShipmentInOutLine as sl where sl.shipmentReceipt.id = :shipmentId";
+    final Query<Long> query = OBDal.getInstance().getSession().createQuery(hql, Long.class);
+    query.setParameter("shipmentId", shipment.getId());
+    final Long maxLineNo = query.uniqueResult();
+    if (maxLineNo != null) {
+      return maxLineNo;
+    }
+    return 0L;
+  }
+
+  private OrderLine getOrderLineByLineNo(final Order salesOrder, long lineNo) {
+    final String hql = "as ol where ol.salesOrder.id = :salesOrderId and ol.lineNo = :lineNo";
+    final OBQuery<OrderLine> query = OBDal.getInstance().createQuery(OrderLine.class, hql);
+    query.setNamedParameter("salesOrderId", salesOrder.getId());
+    query.setNamedParameter("lineNo", lineNo);
+    query.setMaxResult(1);
+    return query.uniqueResult();
+  }
+
+  private ShipmentInOutLine getShipmentLineByLineNo(final ShipmentInOut shipment, long lineNo) {
+    final String hql = "as sl where sl.shipmentReceipt.id = :shipmentId and sl.lineNo = :lineNo";
+    final OBQuery<ShipmentInOutLine> query = OBDal.getInstance().createQuery(
+        ShipmentInOutLine.class, hql);
+    query.setNamedParameter("shipmentId", shipment.getId());
+    query.setNamedParameter("lineNo", lineNo);
+    query.setMaxResult(1);
+    return query.uniqueResult();
+  }
+
+  private InvoiceLine getInvoiceLineByProductQuantity(final Invoice invoice, final Product product,
+      BigDecimal quantity) {
+    final String hql = "as il where il.invoice.id = :invoiceId and il.product.id =:productId and il.invoicedQuantity = :invoicedQuantity";
+    final OBQuery<InvoiceLine> query = OBDal.getInstance().createQuery(InvoiceLine.class, hql);
+    query.setNamedParameter("invoiceId", invoice.getId());
+    query.setNamedParameter("productId", product.getId());
+    query.setNamedParameter("invoicedQuantity", quantity);
+    query.setMaxResult(1);
+    return query.uniqueResult();
+  }
+
+  private Invoice createInvoiceFromShipment(final ShipmentInOut shipment,
+      final String salesInvoiceId) {
+    final Invoice invoice = OBDal.getInstance().get(Invoice.class, salesInvoiceId);
+    final Invoice newInvoice = (Invoice) DalUtil.copy(invoice, false);
+    newInvoice.setId(SequenceIdData.getUUID());
+    newInvoice.setNewOBObject(true);
+    newInvoice.setAccountingDate(shipment.getAccountingDate());
+    newInvoice.setInvoiceDate(shipment.getMovementDate());
+    final String documentNo = Utility.getDocumentNo(OBDal.getInstance().getConnection(false),
+        new DalConnectionProvider(false), RequestContext.get().getVariablesSecureApp(), "",
+        Invoice.TABLE_NAME, newInvoice.getTransactionDocument() == null ? "" : newInvoice
+            .getTransactionDocument().getId(), newInvoice.getDocumentType() == null ? ""
+            : newInvoice.getDocumentType().getId(), false, true);
+    newInvoice.setDocumentNo(documentNo);
+    OBDal.getInstance().save(newInvoice);
+    OBDal.getInstance().flush();
+
+    final ShipmentInOutLine shipmentInOutLine = shipment.getMaterialMgmtShipmentInOutLineList()
+        .get(0);
+    WeldUtils.getInstanceFromStaticBeanManager(CreateInvoiceLinesFromProcess.class)
+        .createInvoiceLinesFromDocumentLines(
+            getShipmentLineToBeInvoiced(shipmentInOutLine, BigDecimal.TEN), newInvoice,
+            ShipmentInOutLine.class);
+
+    OBDal.getInstance().flush();
+    return newInvoice;
+  }
+
+  private JSONArray getShipmentLineToBeInvoiced(final ShipmentInOutLine shipmentInOutLine,
+      final BigDecimal invoicedQuantity) {
+
+    final JSONArray lines = new JSONArray();
+    try {
+      final JSONObject line = new JSONObject();
+      line.put("uOM", shipmentInOutLine.getUOM().getId());
+      line.put("uOM$_identifier", shipmentInOutLine.getUOM().getIdentifier());
+      line.put("product", shipmentInOutLine.getProduct().getId());
+      line.put("product$_identifier", shipmentInOutLine.getProduct().getIdentifier());
+      line.put("lineNo", shipmentInOutLine.getLineNo());
+      line.put("movementQuantity", invoicedQuantity.toString());
+      line.put("operativeQuantity",
+          shipmentInOutLine.getOperativeQuantity() == null ? shipmentInOutLine
+              .getMovementQuantity().toString() : shipmentInOutLine.getOperativeQuantity()
+              .toString());
+      line.put("id", shipmentInOutLine.getId());
+      line.put("operativeUOM", shipmentInOutLine.getOperativeUOM() == null ? shipmentInOutLine
+          .getUOM().getId() : shipmentInOutLine.getOperativeUOM().getId());
+      line.put("operativeUOM$_identifier",
+          shipmentInOutLine.getOperativeUOM() == null ? shipmentInOutLine.getUOM().getIdentifier()
+              : shipmentInOutLine.getOperativeUOM().getIdentifier());
+      line.put("orderQuantity", "");
+      lines.put(line);
+    } catch (JSONException e) {
+      log.error(e.getMessage());
+    }
+    return lines;
+  }
+
+  private void assertInvoiceDatePriceListAndStatus(Invoice invoice, Date invoiceDate,
+      PriceList priceList, String status) {
+    assertThat("Invoice status should have been " + status, invoice.getDocumentStatus(),
+        equalTo(status));
+    assertTrue("Invoice date should have been " + invoiceDate,
+        DateUtils.truncatedEquals(invoice.getInvoiceDate(), invoiceDate, Calendar.DATE));
+    assertThat("Price List should have been " + priceList.getId(), invoice.getPriceList().getId(),
+        equalTo(priceList.getId()));
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src-test/src/org/openbravo/test/materialMgmt/invoiceFromShipment/TestUtils.java	Wed Nov 14 08:52:36 2018 +0100
@@ -0,0 +1,299 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.1  (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) 2018 Openbravo SLU
+ * All Rights Reserved. 
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+package org.openbravo.test.materialMgmt.invoiceFromShipment;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+import org.hibernate.criterion.Restrictions;
+import org.openbravo.base.exception.OBException;
+import org.openbravo.dal.core.DalUtil;
+import org.openbravo.dal.service.OBCriteria;
+import org.openbravo.dal.service.OBDal;
+import org.openbravo.erpCommon.utility.SequenceIdData;
+import org.openbravo.model.common.invoice.Invoice;
+import org.openbravo.model.common.order.Order;
+import org.openbravo.model.common.order.OrderLine;
+import org.openbravo.model.common.plm.Product;
+import org.openbravo.model.materialmgmt.transaction.ShipmentInOut;
+import org.openbravo.model.materialmgmt.transaction.ShipmentInOutLine;
+import org.openbravo.model.pricing.pricelist.ProductPrice;
+import org.openbravo.service.db.CallStoredProcedure;
+
+public class TestUtils {
+
+  private static final String COMPLETE_ACTION = "CO";
+  private static final String DRAFT_STATUS = "DR";
+
+  /**
+   * Returns a new Product based on the given one. It is a clone of the first one but with different
+   * name and value
+   * 
+   * @param productId
+   *          Id of the original Product
+   * @param name
+   *          Name of the original Product
+   * @return A new Product clone based on the original one
+   */
+  static Product cloneProduct(final String productId, final String name) {
+    final Product oldProduct = OBDal.getInstance().get(Product.class, productId);
+    final Product newProduct = (Product) DalUtil.copy(oldProduct, false);
+    int numberOfProductsWithSameName = getNumberOfProducts(name) + 1;
+
+    newProduct.setSearchKey(name + "-" + numberOfProductsWithSameName);
+    newProduct.setName(name + "-" + numberOfProductsWithSameName);
+    newProduct.setId(SequenceIdData.getUUID());
+    newProduct.setNewOBObject(true);
+
+    OBDal.getInstance().save(newProduct);
+
+    // Clone Prices
+    final List<ProductPrice> oldPrices = oldProduct.getPricingProductPriceList();
+    final List<ProductPrice> newPrices = new ArrayList<>();
+    for (ProductPrice productPrice : oldPrices) {
+      final ProductPrice newProductPrice = (ProductPrice) DalUtil.copy(productPrice, false);
+      newProductPrice.setNewOBObject(true);
+      newProductPrice.setId(SequenceIdData.getUUID());
+      newProductPrice.setProduct(newProduct);
+      OBDal.getInstance().save(newProductPrice);
+      newPrices.add(newProductPrice);
+    }
+    newProduct.setPricingProductPriceList(newPrices);
+    OBDal.getInstance().flush();
+
+    return newProduct;
+  }
+
+  /**
+   * Returns the number of products with same Product name
+   */
+  static int getNumberOfProducts(final String name) {
+    try {
+      final OBCriteria<Product> criteria = OBDal.getInstance().createCriteria(Product.class);
+      criteria.add(Restrictions.like(Product.PROPERTY_NAME, name + "-%"));
+      return criteria.count();
+    } catch (Exception e) {
+      throw new OBException(e);
+    }
+  }
+
+  /**
+   * Returns a new Order Line based on the given one. It is a clone of the first one but without
+   * being invoiced or delivered
+   * 
+   * @param orderLine
+   *          Order Line to be cloned
+   * @param newOrder
+   *          new Order (a clone of the original one)
+   * @return A new Order Line clone based on the original one
+   */
+  public static Order cloneOrder(final String orderId, final String docNo) {
+    final Order oldOrder = OBDal.getInstance().get(Order.class, orderId);
+    final Order newOrder = (Order) DalUtil.copy(oldOrder, false);
+    int numberOfOrdersWithSameDocNo = getNumberOfOrders(docNo) + 1;
+
+    newOrder.setId(SequenceIdData.getUUID());
+    newOrder.setDocumentNo(docNo + "-" + numberOfOrdersWithSameDocNo);
+    newOrder.setProcessed(false);
+    newOrder.setDocumentStatus(DRAFT_STATUS);
+    newOrder.setDocumentAction(COMPLETE_ACTION);
+    newOrder.setCancelled(false);
+    newOrder.setOrderDate(Calendar.getInstance().getTime());
+    newOrder.setScheduledDeliveryDate(Calendar.getInstance().getTime());
+    newOrder.setNewOBObject(true);
+
+    OBDal.getInstance().save(newOrder);
+
+    for (OrderLine orderLine : oldOrder.getOrderLineList()) {
+      cloneOrderLine(orderLine, newOrder);
+    }
+
+    OBDal.getInstance().flush();
+
+    return newOrder;
+  }
+
+  /**
+   * Returns the number of orders with same Document Number
+   */
+  static int getNumberOfOrders(final String docNo) {
+    try {
+      final OBCriteria<Order> criteria = OBDal.getInstance().createCriteria(Order.class);
+      criteria.add(Restrictions.like(Order.PROPERTY_DOCUMENTNO, docNo + "-%"));
+      return criteria.list().size();
+    } catch (Exception e) {
+      throw new OBException(e);
+    }
+  }
+
+  /**
+   * Returns a new Order Line based on the given one. It is a clone of the first one but without
+   * being invoiced or delivered
+   * 
+   * @param orderLine
+   *          Order Line to be cloned
+   * @param newOrder
+   *          new Order (a clone of the original one)
+   * @return A new Order Line clone based on the original one
+   */
+  public static OrderLine cloneOrderLine(final OrderLine oldLine, final Order newOrder) {
+
+    // Skip discount lines
+    if (oldLine.getOrderDiscount() != null) {
+      return null;
+    }
+
+    final OrderLine newLine = (OrderLine) DalUtil.copy(oldLine, false);
+
+    newLine.setId(SequenceIdData.getUUID());
+    newLine.setSalesOrder(newOrder);
+    newLine.setDeliveredQuantity(BigDecimal.ZERO);
+    newLine.setInvoicedQuantity(BigDecimal.ZERO);
+    newLine.setReservedQuantity(BigDecimal.ZERO);
+    newLine.setNewOBObject(true);
+
+    OBDal.getInstance().save(newLine);
+    newOrder.getOrderLineList().add(newLine);
+
+    return newLine;
+  }
+
+  /**
+   * Calls C_Order_Post Database Function to complete the given Order
+   * 
+   * @param order
+   *          Order to be completed
+   * @throws OBException
+   */
+  static void processOrder(final Order order) throws OBException {
+    final List<Object> parameters = new ArrayList<Object>();
+    parameters.add(null);
+    parameters.add(order.getId());
+    final String procedureName = "c_order_post1";
+    CallStoredProcedure.getInstance().call(procedureName, parameters, null, true, false);
+  }
+
+  /**
+   * Returns a new Goods Receipt/Shipment based on the given one. It is a clone of the first one but
+   * in a not completed status
+   * 
+   * @param mInoutId
+   *          Id of original Goods Receipt/Shipment to clone
+   * @param docNo
+   *          docNo to set to the new Goods Receipt/Shipment
+   * @return a Goods Receipt/Shipment not completed
+   */
+  static ShipmentInOut cloneReceiptShipment(final String mInoutId, final String docNo) {
+    final ShipmentInOut oldInOut = OBDal.getInstance().get(ShipmentInOut.class, mInoutId);
+    final ShipmentInOut newInOut = (ShipmentInOut) DalUtil.copy(oldInOut, false);
+    int numberOfShipmentsWithSameDocNo = getNumberOfShipments(docNo) + 1;
+
+    newInOut.setId(SequenceIdData.getUUID());
+    newInOut.setDocumentNo(docNo + "-" + numberOfShipmentsWithSameDocNo);
+    newInOut.setDocumentStatus(DRAFT_STATUS);
+    newInOut.setDocumentAction(COMPLETE_ACTION);
+    newInOut.setProcessed(false);
+    newInOut.setMovementDate(new Date());
+    newInOut.setOrderDate(new Date());
+    newInOut.setNewOBObject(true);
+    newInOut.setSalesOrder(null);
+
+    OBDal.getInstance().save(newInOut);
+
+    for (ShipmentInOutLine line : oldInOut.getMaterialMgmtShipmentInOutLineList()) {
+      cloneReceiptShipmentLine(line, newInOut);
+    }
+
+    OBDal.getInstance().flush();
+    return newInOut;
+  }
+
+  /**
+   * Returns the number of Goods Receipts/Shipments with same Document Number
+   */
+  static int getNumberOfShipments(final String docNo) {
+    try {
+      final OBCriteria<ShipmentInOut> criteria = OBDal.getInstance().createCriteria(
+          ShipmentInOut.class);
+      criteria.add(Restrictions.like(ShipmentInOut.PROPERTY_DOCUMENTNO, docNo + "-%"));
+      return criteria.list().size();
+    } catch (Exception e) {
+      throw new OBException(e);
+    }
+  }
+
+  /**
+   * Returns a new Goods Receipt/Shipment Line based on the given one. It is a clone of the first
+   * one but with different product
+   * 
+   * @param line
+   *          Original Goods Receipt/Shipment
+   * @param newInOut
+   *          new Goods Receipt/Shipment (a clone of the original one)
+   * @return A new Goods Receipt/Shipment Line clone based on the original one
+   */
+  static ShipmentInOutLine cloneReceiptShipmentLine(final ShipmentInOutLine oldLine,
+      final ShipmentInOut newInOut) {
+    final ShipmentInOutLine newLine = (ShipmentInOutLine) DalUtil.copy(oldLine, false);
+
+    newLine.setId(SequenceIdData.getUUID());
+    newLine.setShipmentReceipt(newInOut);
+    newLine.setNewOBObject(true);
+    newLine.setSalesOrderLine(null);
+
+    OBDal.getInstance().save(newLine);
+    newInOut.getMaterialMgmtShipmentInOutLineList().add(newLine);
+
+    return newLine;
+  }
+
+  /**
+   * Calls M_Inout_Post Database Function to complete the given Shipment/Receipt
+   * 
+   * @param shipmentReceipt
+   *          Shipment or Receipt to be completed
+   * @throws OBException
+   */
+  static void processShipmentReceipt(final ShipmentInOut shipmentReceipt) throws OBException {
+    final List<Object> parameters = new ArrayList<Object>();
+    parameters.add(null);
+    parameters.add(shipmentReceipt.getId());
+    final String procedureName = "m_inout_post";
+    CallStoredProcedure.getInstance().call(procedureName, parameters, null, true, false);
+  }
+
+  /**
+   * Calls the C_INVOICE_POST stored procedure
+   * 
+   * @param invoice
+   *          The Invoice.
+   * @throws Exception
+   */
+  public static void processInvoice(final Invoice invoice) throws Exception {
+    if (invoice != null) {
+      final List<Object> parameters = new ArrayList<>();
+      parameters.add(null); // Process Instance parameter
+      parameters.add(invoice.getId());
+      CallStoredProcedure.getInstance().call("C_INVOICE_POST", parameters, null, true, false);
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openbravo/common/actionhandler/InvoiceFromShipmentActionHandler.java	Wed Nov 14 08:52:36 2018 +0100
@@ -0,0 +1,106 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.1  (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) 2018 Openbravo SLU 
+ * All Rights Reserved. 
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+package org.openbravo.common.actionhandler;
+
+import java.util.Date;
+import java.util.Map;
+
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.openbravo.client.application.process.BaseProcessActionHandler;
+import org.openbravo.dal.service.OBDal;
+import org.openbravo.erpCommon.utility.OBMessageUtils;
+import org.openbravo.materialmgmt.InvoiceFromGoodsShipmentUtil;
+import org.openbravo.materialmgmt.InvoiceGeneratorFromGoodsShipment;
+import org.openbravo.model.common.invoice.Invoice;
+import org.openbravo.model.pricing.pricelist.PriceList;
+import org.openbravo.service.json.JsonUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Action handler to generate Invoice from Goods Shipment
+ * 
+ */
+public class InvoiceFromShipmentActionHandler extends BaseProcessActionHandler {
+  private static final Logger log = LoggerFactory.getLogger(InvoiceFromShipmentActionHandler.class);
+
+  private static final String TEXT = "text";
+  private static final String TITLE = "title";
+  private static final String SEVERITY = "severity";
+  private static final String MESSAGE = "message";
+
+  @Override
+  protected JSONObject doExecute(Map<String, Object> parameters, String content) {
+    final JSONObject message = new JSONObject();
+    try {
+      final JSONObject request = new JSONObject(content);
+      final JSONObject params = request.getJSONObject("_params");
+      final String shipmentId = request.getString("M_InOut_ID");
+      final String invoiceDateStr = params.getString("DateInvoiced");
+      final String priceListStr = params.getString("priceList");
+      boolean processInvoice = params.getBoolean("processInvoice");
+
+      final Date invoiceDate = JsonUtils.createDateFormat().parse(invoiceDateStr);
+      final PriceList priceList = OBDal.getInstance().getProxy(PriceList.class, priceListStr);
+
+      final Invoice invoice = new InvoiceGeneratorFromGoodsShipment(shipmentId, invoiceDate,
+          priceList).createInvoiceConsideringInvoiceTerms(processInvoice);
+      message.put(MESSAGE, getSuccessMessage(invoice));
+    } catch (Exception e) {
+      try {
+        message.put(MESSAGE, getErrorMessage(e));
+      } catch (JSONException e1) {
+        log.error(e.getMessage());
+      }
+    }
+
+    return message;
+  }
+
+  protected JSONObject getSuccessMessage(final Invoice invoice) {
+    final JSONObject successMessage = new JSONObject();
+    try {
+      successMessage.put(SEVERITY, "success");
+      successMessage.put(TITLE, OBMessageUtils.messageBD("Success"));
+      if (invoice != null) {
+        successMessage.put(TEXT, String.format(OBMessageUtils.messageBD("NewInvoiceGenerated"),
+            invoice.getDocumentNo(), InvoiceFromGoodsShipmentUtil.getInvoiceStatus(invoice)));
+      } else {
+        successMessage.put(TEXT, OBMessageUtils.messageBD("NoInvoiceGenerated"));
+      }
+    } catch (JSONException e) {
+      log.error(e.getMessage());
+    }
+    return successMessage;
+  }
+
+  private JSONObject getErrorMessage(final Exception e) {
+    final JSONObject errorMessage = new JSONObject();
+    try {
+      errorMessage.put(SEVERITY, "error");
+      errorMessage.put(TITLE, OBMessageUtils.messageBD("Error"));
+      errorMessage.put(TEXT, e.getMessage());
+    } catch (JSONException ex) {
+      log.error(e.getMessage());
+    }
+    return errorMessage;
+  }
+
+}
--- a/src/org/openbravo/erpCommon/ad_actionButton/DocAction.html	Tue Nov 13 12:08:14 2018 +0100
+++ b/src/org/openbravo/erpCommon/ad_actionButton/DocAction.html	Wed Nov 14 08:52:36 2018 +0100
@@ -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) 2001-2017 Openbravo SLU 
+* All portions are Copyright (C) 2001-2018 Openbravo SLU 
 * All Rights Reserved. 
 * Contributor(s):  ______________________________________.
 ************************************************************************
@@ -84,6 +84,8 @@
       setWindowElementFocus('firstElement');
 
       applyVoidDateDisplayLogic();
+      
+      applyInvoiceIfPossibleDisplayLogic();
     }
 
     function onResizeDo() {}
@@ -92,7 +94,8 @@
       var frm = document.frmMain,
           purchaseInvoiceWindow = '183',
           goodsReceiptWindow = '184',
-          displayVoidDates = (frm.inpdocaction.value === 'RC');
+          displayVoidDates = (frm.inpdocaction.value === 'RC'),
+          goodsShipmentWindow = '169';
       if (inputValue(frm.inpdocaction) == null || inputValue(frm.inpdocaction) == "") {
         setWindowElementFocus(frm.inpdocaction);
         showJSMessage(1);
@@ -131,6 +134,15 @@
           return false;
         }
       }
+      
+      if (goodsShipmentWindow === frm.inpwindowId.value && ((inputValue(frm.inpInvoiceDate) == null || inputValue(frm.inpInvoiceDate) == "") || 
+        !isValidDate(frm.inpInvoiceDate.value, frm.inpInvoiceDate.getAttribute("displayformat")))) {
+    	  
+        setWindowElementFocus(frm.inpInvoiceDate);
+        showJSMessage('InvalidDateFormat');        
+        return false;
+      }      
+      
       setProcessingMode('popup', true);
       return true;
     }
@@ -165,6 +177,19 @@
       displayLogicElement('voidedDocumentDateRow', displayVoidDates && (purchaseInvoiceWindow === currentWindowId || goodsReceiptWindow === currentWindowId));
       displayLogicElement('voidedDocumentDateAcctRow', displayVoidDates && (purchaseInvoiceWindow === currentWindowId || goodsReceiptWindow === currentWindowId));
     }
+    
+    function applyInvoiceIfPossibleDisplayLogic() {
+      var frm = document.frmMain,
+          goodsShipmentWindow = '169',
+          currentWindowId = frm.inpwindowId.value,
+          documentIsInDraftStatus = (frm.inpdocstatus.value === 'DR'),
+          isInvoiceIfPossibleChecked = frm.inpInvoiceIfPossible.checked;
+      
+      displayLogicElement('invoiceIfPossible', documentIsInDraftStatus && currentWindowId === goodsShipmentWindow);
+      displayLogicElement('processInvoice', isInvoiceIfPossibleChecked && documentIsInDraftStatus && currentWindowId === goodsShipmentWindow);
+      displayLogicElement('invoiceDateRow', isInvoiceIfPossibleChecked && documentIsInDraftStatus && currentWindowId === goodsShipmentWindow);
+      displayLogicElement('priceListRow', isInvoiceIfPossibleChecked && documentIsInDraftStatus && currentWindowId === goodsShipmentWindow);
+    }
     </script>
 </head>
 
@@ -440,7 +465,78 @@
                   </table>
                 </td>
               </tr>
-
+              
+              <tr id="invoiceIfPossible">
+              	<td class="TitleCell"><span id="lblInvoiceIfPossible" class="LabelText">Invoice if possible</span></td>
+              	<td class="Radio_Check_ContentCell">
+              	  <span class="Checkbox_container_NOT_Focused">
+              	    <input type="checkbox" id="paramInvoiceIfPossible" name="inpInvoiceIfPossible" onchange="applyInvoiceIfPossibleDisplayLogic();" value="Y">
+              	  </span>
+              	</td>
+              </tr>
+              
+              <tr id="invoiceDateRow">
+                <td class="TitleCell"><span id="lblInvoiceDate" class="LabelText">Invoice Date</span></td>
+                <td class="TextBox_btn_ContentCell">
+                  <table border="0" cellspacing="0" cellpadding="0" summary=""  style="padding-top: 0px;">
+                    <tr>
+                      <td class="TextBox_ContentCell">
+                        <table style="border: 0px none; border-collapse: collapse;">
+                          <tr><td style="padding-top: 0px;">
+                            <input type="text" id="paramInvoiceDate" name="inpInvoiceDate" onchange="validateDateTextBox(this.id); logChanges(this);return true;" onblur="expandDateYear(this.id);" oncontextmenu="changeToEditingMode('oncontextmenu');" onpaste="changeToEditingMode('onpaste');" oncut="changeToEditingMode('oncut');" onkeypress="changeToEditingMode('onkeypress');" onkeydown="changeToEditingMode('onkeydown');" onkeyup="autoCompleteDate(this);" maxlength="10" value="" required="true" class="dojoValidateValid required TextBox_btn_OneCell_width" displayFormat="xx" saveFormat="yy">
+                          </td></tr>
+                        </table>
+                        <span id="paramInvoiceDateinvalidSpan" style="display: none;" class="TextBox_MsgContainer_span">
+                          <table class="TextBox_MsgContainer_table">
+                            <tbody><tr class="TextBox_MsgContainer_tr"><td class="TextBox_MsgContainer_td"><div class="TextBox_MsgContainer_div"></div></td><td></td></tr>
+                            <tr><td class="invalid" colspan="2"><div name="invalidText" id="paramInvoiceDateinvalidSpanText" class="TextBox_MsgContainer_div2">* The value entered is not valid.</div></td></tr>
+                          </tbody></table>
+                        </span>
+                        <span id="paramInvoiceDatemissingSpan" style="display: none;" class="TextBox_MsgContainer_span">
+                          <table class="TextBox_MsgContainer_table">
+                            <tbody><tr class="TextBox_MsgContainer_tr">
+                              <td class="TextBox_MsgContainer_td"><div class="TextBox_MsgContainer_div"></div></td><td></td>
+                            </tr>
+                            <tr>
+                              <td class="missing" colspan="2"><div name="missingText" id="paramInvoiceDatemissingSpanText" class="TextBox_MsgContainer_div2">* This value is required.</div></td>
+                            </tr>
+                            </tbody></table>
+                        </span>
+                      </td>
+                      <td id="calendarIconInvoiceDate" class="FieldButton_ContentCell">
+                        <a class="FieldButtonLink" href="#" onfocus="setWindowElementFocus(this); window.status='Calendar'; return true;" onblur="window.status=''; return true;" onkeypress="this.className='FieldButtonLink_active'; return true;" onkeyup="this.className='FieldButtonLink_focus'; return true;" onclick="showCalendar('frmMain.inpInvoiceDate', document.frmMain.inpInvoiceDate.value, false);return false;">
+                          <table class="FieldButton"  onmouseout="this.className='FieldButton';window.status='';return true;" onmouseover="this.className='FieldButton_hover';window.status='Show calendar';return true;" onmousedown="this.className='FieldButton_active';return true;" onmouseup="this.className='FieldButton';return true;">
+                            <tr>
+                              <td class="FieldButton_bg">
+                                <img alt="Calendar" class="FieldButton_Icon FieldButton_Icon_Calendar" title="Calendar" src="../../../../../web/images/blank.gif" border="0"></img>
+                              </td>
+                            </tr>
+                          </table>
+                        </a>
+                      </td>
+                    </tr>
+                  </table>
+                </td>
+              </tr>
+              
+              <tr id="priceListRow">
+                <td class="TitleCell"><span class="LabelText">Price List</span></td>
+                <td class="Combo_ContentCell" colspan="2">
+                  <select name="inpPriceList" id="priceList" class="ComboKey Combo_TwoCells_width">
+                  </select>
+                </td>
+                <td></td>
+              </tr>
+              
+              <tr id="processInvoice">
+              	<td class="TitleCell"><span id="lblProcessInvoice" class="LabelText">Process Invoice</span></td>
+              	<td class="Radio_Check_ContentCell">
+              	  <span class="Checkbox_container_NOT_Focused">
+              	    <input type="checkbox" id="paramProcessInvoice" name="inpProcessInvoice" value="Y" checked>
+              	  </span>
+              	</td>
+              </tr>
+              
               <tr><td height="20px"></td></tr>
 
               <tr>
--- a/src/org/openbravo/erpCommon/ad_actionButton/DocAction.xml	Tue Nov 13 12:08:14 2018 +0100
+++ b/src/org/openbravo/erpCommon/ad_actionButton/DocAction.xml	Wed Nov 14 08:52:36 2018 +0100
@@ -58,9 +58,19 @@
   <PARAMETER id="documentAcctDate" name="documentAcctDate" attribute="value"/>
   <PARAMETER id="fieldCalendar" name="calendar" attribute="src" replace="es" default="en"/>
 
-	<PARAMETER id="docaction" name="docaction"/>
-	<SUBREPORT id="reportdocaction" name="reportdocaction" report="org/openbravo/erpCommon/reference/List">
-		<ARGUMENT name="parameterListSelected" withId="docaction"/>
-	</SUBREPORT>
-	<DISCARD id="discard"/>
+  <PARAMETER id="docaction" name="docaction"/>
+  <SUBREPORT id="reportdocaction" name="reportdocaction" report="org/openbravo/erpCommon/reference/List">
+	<ARGUMENT name="parameterListSelected" withId="docaction"/>
+  </SUBREPORT>
+  <DISCARD id="discard"/>
+
+  <PARAMETER id="paramInvoiceDate" name="invoiceDocumentDate" attribute="value"/>
+  <PARAMETER id="paramInvoiceDate" name="dateDisplayFormat" attribute="displayformat" replace="xx"/>
+  <PARAMETER id="paramInvoiceDate" name="dateDisplayFormat" attribute="saveformat" replace="yy"/>
+  
+  <PARAMETER id="selectedPriceList" name="selectedPriceList"/>
+  <SUBREPORT id="priceList" name="priceList" report="org/openbravo/erpCommon/reference/List">
+    <ARGUMENT name="parameterListSelected" withId="selectedPriceList"/>
+  </SUBREPORT>
+  
 </REPORT>
--- a/src/org/openbravo/erpCommon/ad_actionButton/ProcessGoods.java	Tue Nov 13 12:08:14 2018 +0100
+++ b/src/org/openbravo/erpCommon/ad_actionButton/ProcessGoods.java	Wed Nov 14 08:52:36 2018 +0100
@@ -46,19 +46,25 @@
 import org.openbravo.erpCommon.utility.FieldProviderFactory;
 import org.openbravo.erpCommon.utility.OBDateUtils;
 import org.openbravo.erpCommon.utility.OBError;
+import org.openbravo.erpCommon.utility.OBMessageUtils;
 import org.openbravo.erpCommon.utility.Utility;
 import org.openbravo.materialmgmt.InventoryCountProcess;
+import org.openbravo.materialmgmt.InvoiceFromGoodsShipmentUtil;
+import org.openbravo.materialmgmt.InvoiceGeneratorFromGoodsShipment;
 import org.openbravo.model.ad.process.ProcessInstance;
 import org.openbravo.model.ad.ui.Process;
+import org.openbravo.model.common.invoice.Invoice;
 import org.openbravo.model.materialmgmt.onhandquantity.StorageDetail;
 import org.openbravo.model.materialmgmt.transaction.InventoryCount;
 import org.openbravo.model.materialmgmt.transaction.InventoryCountLine;
 import org.openbravo.model.materialmgmt.transaction.ShipmentInOut;
 import org.openbravo.model.materialmgmt.transaction.ShipmentInOutLine;
+import org.openbravo.model.pricing.pricelist.PriceList;
 import org.openbravo.service.db.CallProcess;
 import org.openbravo.xmlEngine.XmlDocument;
 
 public class ProcessGoods extends HttpSecureAppServlet {
+  private static final String GOODS_SHIPMENT_WINDOW = "169";
   private static final long serialVersionUID = 1L;
   private static final String M_Inout_Post_ID = "109";
   private static final String M_Inout_Table_ID = "319";
@@ -158,6 +164,8 @@
     final String strTabId = vars.getGlobalVariable("inpTabId", "ProcessGoods|Tab_ID",
         IsIDFilter.instance);
     final String strM_Inout_ID = vars.getGlobalVariable("inpKey", strWindowId + "|M_Inout_ID", "");
+    final boolean invoiceIfPossible = StringUtils.equals(
+        vars.getStringParameter("inpInvoiceIfPossible"), "Y");
 
     OBError myMessage = null;
     try {
@@ -208,13 +216,20 @@
       log4j.debug(myMessage.getMessage());
       vars.setMessage(strTabId, myMessage);
 
+      if (invoiceIfPossible && GOODS_SHIPMENT_WINDOW.equals(strWindowId)
+          && !"Error".equalsIgnoreCase(myMessage.getType())) {
+        myMessage = createInvoice(vars, goods);
+        log4j.debug(myMessage.getMessage());
+        vars.setMessage(strTabId, myMessage);
+      }
+
       String strWindowPath = Utility.getTabURL(strTabId, "R", true);
       if (strWindowPath.equals("")) {
         strWindowPath = strDefaultServlet;
       }
       printPageClosePopUp(response, vars, strWindowPath);
 
-    } catch (ServletException ex) {
+    } catch (ServletException | ParseException ex) {
       myMessage = Utility.translateError(this, vars, vars.getLanguage(), ex.getMessage());
       if (!myMessage.isConnectionAvailable()) {
         bdErrorConnection(response);
@@ -225,6 +240,36 @@
     }
   }
 
+  private OBError createInvoice(final VariablesSecureApp vars, final ShipmentInOut goodShipment)
+      throws ParseException {
+    OBError myMessage;
+    final boolean processInvoice = StringUtils.equals(vars.getStringParameter("inpProcessInvoice"),
+        "Y");
+    final String invoiceDateStr = vars.getStringParameter("inpInvoiceDate");
+    final String priceListStr = vars.getStringParameter("inpPriceList");
+
+    final Date invoiceDate = OBDateUtils.getDate(invoiceDateStr);
+    final PriceList priceList = OBDal.getInstance().getProxy(PriceList.class, priceListStr);
+
+    final Invoice invoice = new InvoiceGeneratorFromGoodsShipment(goodShipment.getId(),
+        invoiceDate, priceList).createInvoiceConsideringInvoiceTerms(processInvoice);
+    myMessage = getResultMessage(invoice);
+    return myMessage;
+  }
+
+  private OBError getResultMessage(Invoice invoice) {
+    OBError message = new OBError();
+    message.setType("Success");
+    message.setTitle("Success");
+    if (invoice != null) {
+      message.setMessage(String.format(OBMessageUtils.messageBD("NewInvoiceGenerated"),
+          invoice.getDocumentNo(), InvoiceFromGoodsShipmentUtil.getInvoiceStatus(invoice)));
+    } else {
+      message.setMessage(OBMessageUtils.messageBD("NoInvoiceGenerated"));
+    }
+    return message;
+  }
+
   void printPageDocAction(HttpServletResponse response, VariablesSecureApp vars,
       String strM_Inout_ID, String strdocaction, String strProcessing, String strdocstatus,
       String stradTableId, String strWindowId) throws IOException, ServletException {
@@ -264,12 +309,12 @@
       OBContext.restorePreviousMode();
     }
 
+    ShipmentInOut shipmentInOut = (ShipmentInOut) OBDal.getInstance().getProxy(
+        ShipmentInOut.ENTITY_NAME, strM_Inout_ID);
     xmlDocument.setParameter("docstatus", strdocstatus);
     if (strWindowId.equals(Goods_Receipt_Window)) {
       // VOID action: Reverse goods receipt/shipment by default inherits the document date and
       // accounting date from the voided document
-      ShipmentInOut shipmentInOut = (ShipmentInOut) OBDal.getInstance().getProxy(
-          ShipmentInOut.ENTITY_NAME, strM_Inout_ID);
       String movementDate = OBDateUtils.formatDate(shipmentInOut.getMovementDate());
       String accountingDate = OBDateUtils.formatDate(shipmentInOut.getAccountingDate());
       xmlDocument.setParameter("voidedDocumentDate", movementDate);
@@ -299,6 +344,15 @@
       dact.append("var arrDocAction = null");
     xmlDocument.setParameter("array", dact.toString());
 
+    if (strWindowId.equals(GOODS_SHIPMENT_WINDOW)) {
+      xmlDocument.setParameter("invoiceDocumentDate",
+          OBDateUtils.formatDate(shipmentInOut.getMovementDate()));
+      final FieldProvider[] priceListsForSelector = getPriceListsForSelector(shipmentInOut);
+      xmlDocument.setParameter("selectedPriceList",
+          getSelectedPriceList(shipmentInOut, priceListsForSelector));
+      xmlDocument.setData("priceList", "liststructure", priceListsForSelector);
+    }
+
     out.println(xmlDocument.print());
     out.close();
 
@@ -439,7 +493,53 @@
     new InventoryCountProcess().processInventory(inv);
   }
 
+  @Override
   public String getServletInfo() {
     return "Servlet to Process Goods Shipment and Goods Receipt";
   }
+
+  private FieldProvider[] getPriceListsForSelector(final ShipmentInOut shipment) {
+    final List<PriceList> priceLists = getSalesPriceList(shipment);
+    return getFieldProviderFromPriceLists(priceLists);
+  }
+
+  private List<PriceList> getSalesPriceList(final ShipmentInOut shipment) {
+    if (InvoiceFromGoodsShipmentUtil.shipmentLinesFromOrdersWithSamePriceList(shipment)) {
+      return InvoiceFromGoodsShipmentUtil.getPriceListFromOrder(shipment);
+    }
+    return getAvailableSalesPriceList(shipment);
+  }
+
+  private List<PriceList> getAvailableSalesPriceList(final ShipmentInOut shipment) {
+    String hql = "from PricingPriceList pl" //
+        + " where pl.client.id = :clientId" //
+        + " and Ad_Isorgincluded(:shipmentOrgId, pl.organization.id, :clientId) <> -1 "//
+        + " and pl.salesPriceList = true";
+
+    Query<PriceList> query = OBDal.getInstance().getSession().createQuery(hql, PriceList.class);
+    query.setParameter("clientId", shipment.getClient().getId());
+    query.setParameter("shipmentOrgId", shipment.getOrganization().getId());
+
+    return query.list();
+  }
+
+  private FieldProvider[] getFieldProviderFromPriceLists(final List<PriceList> priceLists) {
+    FieldProvider[] data = FieldProviderFactory.getFieldProviderArray(priceLists);
+    for (int i = 0; i < data.length; i++) {
+      PriceList priceList = priceLists.get(i);
+      FieldProviderFactory.setField(data[i], "ID", priceList.getId());
+      FieldProviderFactory.setField(data[i], "NAME", priceList.getName());
+      FieldProviderFactory.setField(data[i], "DESCRIPTION", priceList.getName());
+    }
+    return data;
+  }
+
+  private String getSelectedPriceList(final ShipmentInOut shipment,
+      FieldProvider[] priceListDataForSelector) {
+    if (priceListDataForSelector.length == 1) {
+      return priceListDataForSelector[0].getField("ID");
+    }
+    return InvoiceFromGoodsShipmentUtil.getPriceListFromBusinessPartner(shipment);
+  }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openbravo/materialmgmt/InvoiceFromGoodsShipmentDefaultValueFilterExpression.java	Wed Nov 14 08:52:36 2018 +0100
@@ -0,0 +1,64 @@
+/*
+ *************************************************************************
+ * 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) 2018 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ *************************************************************************
+ */
+package org.openbravo.materialmgmt;
+
+import java.util.Map;
+
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.openbravo.base.exception.OBException;
+import org.openbravo.client.application.FilterExpression;
+import org.openbravo.dal.service.OBDal;
+import org.openbravo.model.materialmgmt.transaction.ShipmentInOut;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class to set the default value of priceList parameter in {@link InvoiceFromShipmentActionHandler}
+ * process definition
+ *
+ */
+public class InvoiceFromGoodsShipmentDefaultValueFilterExpression implements FilterExpression {
+
+  private static final Logger log = LoggerFactory
+      .getLogger(InvoiceFromGoodsShipmentDefaultValueFilterExpression.class);
+
+  @Override
+  public String getExpression(Map<String, String> requestMap) {
+    final ShipmentInOut shipment = getShipmentFromContextData(requestMap);
+    if (InvoiceFromGoodsShipmentUtil.shipmentLinesFromOrdersWithSamePriceList(shipment)) {
+      return InvoiceFromGoodsShipmentUtil.getPriceListFromOrder(shipment).get(0).getId();
+    }
+    return InvoiceFromGoodsShipmentUtil.getPriceListFromBusinessPartner(shipment);
+  }
+
+  private ShipmentInOut getShipmentFromContextData(Map<String, String> requestMap) {
+    ShipmentInOut shipment;
+    try {
+      JSONObject parameters = new JSONObject(requestMap.get("context"));
+      String shipmentId = parameters.getString("inpmInoutId");
+      shipment = OBDal.getInstance().getProxy(ShipmentInOut.class, shipmentId);
+    } catch (JSONException e) {
+      log.error("Error parsing JSON", e);
+      throw new OBException("Unable to get Shipment");
+    }
+    return shipment;
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openbravo/materialmgmt/InvoiceFromGoodsShipmentPriceListFilterExpression.java	Wed Nov 14 08:52:36 2018 +0100
@@ -0,0 +1,48 @@
+/*
+ *************************************************************************
+ * 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) 2018 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ ***/
+package org.openbravo.materialmgmt;
+
+import java.util.Map;
+
+import org.openbravo.client.application.FilterExpression;
+import org.openbravo.dal.service.OBDal;
+import org.openbravo.model.materialmgmt.transaction.ShipmentInOut;
+
+/**
+ * Class to filter the values in priceLists parameter in {@link InvoiceFromShipmentActionHandler}.
+ * Considers the price list used by the orders linked to shipment lines.
+ *
+ */
+public class InvoiceFromGoodsShipmentPriceListFilterExpression implements FilterExpression {
+
+  @Override
+  public String getExpression(Map<String, String> requestMap) {
+    ShipmentInOut shipment = getShipmentFromContextData(requestMap);
+    if (InvoiceFromGoodsShipmentUtil.shipmentLinesFromOrdersWithSamePriceList(shipment)) {
+      return " e.id='"
+          + InvoiceFromGoodsShipmentUtil.getPriceListFromOrder(shipment).get(0).getId() + "' ";
+    }
+    return " 1=1 ";
+  }
+
+  private ShipmentInOut getShipmentFromContextData(Map<String, String> requestMap) {
+    String shipmentId = requestMap.get("inpmInoutId");
+    return OBDal.getInstance().getProxy(ShipmentInOut.class, shipmentId);
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openbravo/materialmgmt/InvoiceFromGoodsShipmentUtil.java	Wed Nov 14 08:52:36 2018 +0100
@@ -0,0 +1,104 @@
+/*
+ *************************************************************************
+ * 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) 2018 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ *************************************************************************
+ */
+package org.openbravo.materialmgmt;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.hibernate.query.Query;
+import org.openbravo.dal.service.OBDal;
+import org.openbravo.erpCommon.utility.OBMessageUtils;
+import org.openbravo.model.common.invoice.Invoice;
+import org.openbravo.model.materialmgmt.transaction.ShipmentInOut;
+import org.openbravo.model.pricing.pricelist.PriceList;
+
+/**
+ * Helper class for generate invoice from goods shipment process
+ */
+public class InvoiceFromGoodsShipmentUtil {
+
+  private static final String STATUS_COMPLETED = "CO";
+
+  private InvoiceFromGoodsShipmentUtil() {
+    throw new UnsupportedOperationException("This class should not be instantiated");
+  }
+
+  /**
+   * Returns if all lines in Goods Shipment are linked to Sales Orders sharing the same Price List
+   * 
+   * @param shipment
+   *          The Goods Shipment
+   * @return True if all lines in Goods Shipment come from orders sharing the same Price List, false
+   *         otherwise
+   */
+  public static boolean shipmentLinesFromOrdersWithSamePriceList(final ShipmentInOut shipment) {
+    String hql = "select distinct coalesce(so.priceList.id, '0') "//
+        + " from MaterialMgmtShipmentInOutLine iol left join iol.salesOrderLine sol "//
+        + " left join sol.salesOrder so "//
+        + " where iol.shipmentReceipt.id = :shipmentId";
+
+    final Query<String> query = OBDal.getInstance().getSession().createQuery(hql, String.class);
+    query.setParameter("shipmentId", shipment.getId());
+    query.setMaxResults(2);
+    final List<String> priceLists = query.list();
+    return priceLists.size() == 1 && !priceLists.get(0).equals("0");
+  }
+
+  /**
+   * Returns the Price List used by the orders the shipment lines are linked to. Assumes all lines
+   * are linked to Sales Orders sharing the same Price List
+   * 
+   * @param shipment
+   *          The Goods Shipment
+   * @return The Price List
+   */
+  public static List<PriceList> getPriceListFromOrder(final ShipmentInOut shipment) {
+    return Arrays.asList(shipment.getMaterialMgmtShipmentInOutLineList().get(0).getSalesOrderLine()
+        .getSalesOrder().getPriceList());
+  }
+
+  /**
+   * Returns the Price List used by the Business Partner from the Goods Shipment
+   * 
+   * @param shipment
+   *          The Goods Shipment
+   * @return The Price List Id, if exists, empty string otherwise
+   */
+  public static String getPriceListFromBusinessPartner(final ShipmentInOut shipment) {
+    if (shipment.getBusinessPartner().getPriceList() != null) {
+      return shipment.getBusinessPartner().getPriceList().getId();
+    }
+    return StringUtils.EMPTY;
+  }
+
+  /**
+   * Returns the message based on invoice status
+   * 
+   * @param invoice
+   *          The Invoice
+   * @return The message
+   */
+  public static String getInvoiceStatus(final Invoice invoice) {
+    if (STATUS_COMPLETED.equals(invoice.getDocumentStatus())) {
+      return OBMessageUtils.messageBD("StatusCompleted");
+    }
+    return OBMessageUtils.messageBD("StatusDraft");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openbravo/materialmgmt/InvoiceGeneratorFromGoodsShipment.java	Wed Nov 14 08:52:36 2018 +0100
@@ -0,0 +1,428 @@
+/*
+ *************************************************************************
+ * 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) 2018 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ *************************************************************************
+ */
+package org.openbravo.materialmgmt;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.hibernate.ScrollMode;
+import org.hibernate.ScrollableResults;
+import org.hibernate.Session;
+import org.hibernate.criterion.Restrictions;
+import org.hibernate.query.Query;
+import org.openbravo.base.exception.OBException;
+import org.openbravo.base.model.Entity;
+import org.openbravo.base.model.ModelProvider;
+import org.openbravo.base.provider.OBProvider;
+import org.openbravo.base.util.Check;
+import org.openbravo.base.weld.WeldUtils;
+import org.openbravo.client.kernel.RequestContext;
+import org.openbravo.common.actionhandler.createlinesfromprocess.CreateInvoiceLinesFromProcess;
+import org.openbravo.dal.service.OBDal;
+import org.openbravo.dal.service.OBDao;
+import org.openbravo.erpCommon.utility.OBMessageUtils;
+import org.openbravo.erpCommon.utility.Utility;
+import org.openbravo.model.common.currency.Currency;
+import org.openbravo.model.common.enterprise.DocumentType;
+import org.openbravo.model.common.enterprise.Organization;
+import org.openbravo.model.common.invoice.Invoice;
+import org.openbravo.model.common.invoice.InvoiceLine;
+import org.openbravo.model.common.order.InvoiceCandidateV;
+import org.openbravo.model.common.order.Order;
+import org.openbravo.model.common.order.OrderLine;
+import org.openbravo.model.materialmgmt.transaction.ShipmentInOut;
+import org.openbravo.model.materialmgmt.transaction.ShipmentInOutLine;
+import org.openbravo.model.pricing.pricelist.PriceList;
+import org.openbravo.service.db.CallStoredProcedure;
+import org.openbravo.service.db.DalConnectionProvider;
+import org.openbravo.service.db.DbUtility;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class generates and processes Invoice from Goods Shipment. Only goods shipment lines not
+ * linked to a Sales Order, or from Sales Order with Invoice Term "After Delivery",
+ * "After Order Delivery" or "Immediate" are considered.
+ *
+ */
+public class InvoiceGeneratorFromGoodsShipment {
+  private static final Logger log = LoggerFactory
+      .getLogger(InvoiceGeneratorFromGoodsShipment.class);
+
+  private String shipmentId;
+  private Invoice invoice;
+  private CreateInvoiceLinesFromProcess createInvoiceLineProcess;
+  private Date invoiceDate;
+  private String priceListId;
+  private final Set<String> ordersWithAfterOrderDeliveryAlreadyInvoiced = new HashSet<>();
+
+  private enum InvoiceTerm {
+    IMMEDIATE("I"), AFTER_DELIVERY("D"), CUSTOMERSCHEDULE("S"), AFTER_ORDER_DELIVERY("O");
+
+    private static final List<String> CAN_INVOICE_ORDERLINE_INDIVIDUALLY = Arrays.asList(
+        InvoiceTerm.IMMEDIATE.getInvoiceTerm(), InvoiceTerm.AFTER_DELIVERY.getInvoiceTerm(),
+        CUSTOMERSCHEDULE.getInvoiceTerm());
+
+    private String invoiceTermId;
+
+    private InvoiceTerm(final String invoiceTermId) {
+      this.invoiceTermId = invoiceTermId;
+    }
+
+    private static boolean canInvoiceOrderLineIndividually(final String invoiceTerm) {
+      return CAN_INVOICE_ORDERLINE_INDIVIDUALLY.contains(invoiceTerm);
+    }
+
+    private String getInvoiceTerm() {
+      return invoiceTermId;
+    }
+  }
+
+  /**
+   * Creates an {@link InvoiceGeneratorFromGoodsShipment} based only on shipment Id. The invoice
+   * date is taken from the shipment movement date, and the invoice price list is taken from
+   * shipment business partner
+   * 
+   * @param shipmentId
+   *          The shipment Id
+   */
+  public InvoiceGeneratorFromGoodsShipment(final String shipmentId) {
+    this(shipmentId, null, null);
+  }
+
+  /**
+   * Creates an {@link InvoiceGeneratorFromGoodsShipment} based on shipment Id
+   * 
+   * @param shipmentId
+   *          The shipment Id
+   * @param invoiceDate
+   *          The invoice date. If null it takes the from the shipment movement date.
+   * @param priceList
+   *          The invoice price list. If null it takes the business partner default
+   */
+  public InvoiceGeneratorFromGoodsShipment(final String shipmentId, final Date invoiceDate,
+      final PriceList priceList) {
+    Check.isNotNull(shipmentId, "Parameter shipmentId can't be null");
+    this.shipmentId = shipmentId;
+    setInvoiceDate(invoiceDate);
+    setPriceListId(priceList);
+    this.createInvoiceLineProcess = WeldUtils
+        .getInstanceFromStaticBeanManager(CreateInvoiceLinesFromProcess.class);
+  }
+
+  private void setInvoiceDate(final Date date) {
+    this.invoiceDate = date == null ? getShipment().getMovementDate() : date;
+  }
+
+  private void setPriceListId(final PriceList priceList) {
+    try {
+      this.priceListId = priceList.getId();
+    } catch (NullPointerException noPriceListProvided) {
+      try {
+        this.priceListId = getShipment().getBusinessPartner().getPriceList().getId();
+      } catch (NullPointerException bpWithoutPriceList) {
+        throw new OBException(OBMessageUtils.messageBD("notnullpricelist"));
+      }
+    }
+  }
+
+  private ShipmentInOut getShipment() {
+    return OBDal.getInstance().getProxy(ShipmentInOut.class, shipmentId);
+  }
+
+  private Date getInvoiceDate() {
+    return this.invoiceDate;
+  }
+
+  private PriceList getPriceList() {
+    return OBDal.getInstance().getProxy(PriceList.class, priceListId);
+  }
+
+  /**
+   * Creates a Sales Invoice from Goods Shipment, considering the invoice terms of available orders
+   * linked to the shipment lines.
+   * 
+   * @param doProcessInvoice
+   *          if true the invoice will be automatically processed, otherwise it will remain in draft
+   *          status
+   * 
+   * @return The invoice created
+   */
+  public Invoice createInvoiceConsideringInvoiceTerms(boolean doProcessInvoice) {
+    try {
+      createInvoiceIfPossible();
+      if (doProcessInvoice && invoice != null) {
+        processInvoice();
+        OBDal.getInstance().refresh(invoice);
+      }
+    } catch (Exception e) {
+      OBDal.getInstance().rollbackAndClose();
+      Throwable ex = DbUtility.getUnderlyingSQLException(e);
+      throw new OBException(OBMessageUtils.translateError(ex.getMessage()).getMessage());
+    }
+
+    return invoice;
+  }
+
+  private Invoice createInvoiceIfPossible() {
+    try (ScrollableResults scrollShipmentLines = getShipmentLines()) {
+      while (scrollShipmentLines.next()) {
+        final ShipmentInOutLine shipmentLine = (ShipmentInOutLine) scrollShipmentLines.get(0);
+        final OrderLine orderLine = (OrderLine) scrollShipmentLines.get(1);
+        final Order order = orderLine == null ? null : orderLine.getSalesOrder();
+        if (orderLine == null) {
+          invoiceShipmentLineWithoutRelatedOrderLine(shipmentLine);
+        } else if (isOrderCandidateToBeInvoiced(order)) {
+          invoiceShipmentLineWithRelatedOrderLine(shipmentLine, orderLine, order);
+        }
+        evictObjects(shipmentLine, orderLine, order);
+      }
+      OBDal.getInstance().flush();
+    }
+    return invoice;
+  }
+
+  private ScrollableResults getShipmentLines() {
+    final String shipmentLinesHQLQuery = "select iol, ol " //
+        + "from " + ShipmentInOutLine.ENTITY_NAME + " iol " //
+        + "left join iol." + ShipmentInOutLine.PROPERTY_SALESORDERLINE + " ol " //
+        + "where iol." + ShipmentInOutLine.PROPERTY_SHIPMENTRECEIPT + ".id = :shipmentId ";
+    final Session session = OBDal.getInstance().getSession();
+    final Query<Object[]> query = session.createQuery(shipmentLinesHQLQuery, Object[].class);
+    query.setParameter("shipmentId", shipmentId);
+    return query.scroll(ScrollMode.FORWARD_ONLY);
+  }
+
+  private void invoiceShipmentLineWithoutRelatedOrderLine(final ShipmentInOutLine shipmentLine) {
+    final BigDecimal qtyToInvoice = shipmentLine.getMovementQuantity().subtract(
+        getTotalInvoicedForShipmentLine(shipmentLine));
+    invoicePendingQtyForShipmentLine(shipmentLine, qtyToInvoice);
+  }
+
+  private BigDecimal getTotalInvoicedForShipmentLine(final ShipmentInOutLine iol) {
+    final String invoiceLinesHqlQuery = "select coalesce(sum(il. "
+        + InvoiceLine.PROPERTY_INVOICEDQUANTITY + "), 0) " //
+        + "from " + InvoiceLine.ENTITY_NAME + " il " //
+        + "where il." + InvoiceLine.PROPERTY_GOODSSHIPMENTLINE + ".id = :shipmentLineId " //
+        + "and il.invoice." + Invoice.PROPERTY_DOCUMENTSTATUS + "= 'CO' ";
+
+    final Session sessionInvoiceLines = OBDal.getInstance().getSession();
+    final Query<BigDecimal> queryInvoiceLines = sessionInvoiceLines.createQuery(
+        invoiceLinesHqlQuery, BigDecimal.class);
+    queryInvoiceLines.setParameter("shipmentLineId", iol.getId());
+
+    return queryInvoiceLines.uniqueResult();
+  }
+
+  protected void invoicePendingQtyForShipmentLine(final ShipmentInOutLine shipmentLine,
+      final BigDecimal qtyToInvoice) {
+    if (BigDecimal.ZERO.compareTo(qtyToInvoice) != 0) {
+      createInvoiceLine(shipmentLine, qtyToInvoice);
+    }
+  }
+
+  private boolean isOrderCandidateToBeInvoiced(final Order order) {
+    return !OBDao
+        .getFilteredCriteria(InvoiceCandidateV.class,
+            Restrictions.eq(InvoiceCandidateV.PROPERTY_ID, order.getId())).setMaxResults(1).list()
+        .isEmpty();
+  }
+
+  private void invoiceShipmentLineWithRelatedOrderLine(final ShipmentInOutLine shipmentLine,
+      final OrderLine orderLine, final Order order) {
+    final String invoiceTerm = order.getInvoiceTerms();
+    if (InvoiceTerm.canInvoiceOrderLineIndividually(invoiceTerm)) {
+      final BigDecimal qtyToInvoice = orderLine.getOrderedQuantity()
+          .subtract(orderLine.getInvoicedQuantity()).min(shipmentLine.getMovementQuantity());
+      invoicePendingQtyForShipmentLine(shipmentLine, qtyToInvoice);
+    } else {
+      if (InvoiceTerm.AFTER_ORDER_DELIVERY.getInvoiceTerm().equals(invoiceTerm)) {
+        if (order.getDeliveryStatus() == 100
+            && !ordersWithAfterOrderDeliveryAlreadyInvoiced.contains(order.getId())) {
+          invoiceAllOrderLines(order);
+          ordersWithAfterOrderDeliveryAlreadyInvoiced.add(order.getId());
+        }
+      } else {
+        throw new OBException("Not supported Invoice Term: " + invoiceTerm);
+      }
+    }
+  }
+
+  private void invoiceAllOrderLines(final Order order) {
+    try (ScrollableResults scrollOrderShipmentLines = getAllShipmentLinesLinkedToOrder(order)) {
+      while (scrollOrderShipmentLines.next()) {
+        final ShipmentInOutLine iol = (ShipmentInOutLine) scrollOrderShipmentLines.get()[0];
+        final BigDecimal invoicedQuantity = getTotalInvoicedForShipmentLine(iol);
+        if (invoicedQuantity.compareTo(iol.getMovementQuantity()) != 0) {
+          createInvoiceLine(iol, iol.getMovementQuantity().subtract(invoicedQuantity));
+        }
+        OBDal.getInstance().getSession().evict(iol);
+      }
+    }
+  }
+
+  private ScrollableResults getAllShipmentLinesLinkedToOrder(final Order order) {
+    final String orderLinesHqlQuery = "select iol " //
+        + "from " + ShipmentInOutLine.ENTITY_NAME + " iol " //
+        + "join iol." + ShipmentInOutLine.PROPERTY_SALESORDERLINE + " ol " //
+        + "where ol." + OrderLine.PROPERTY_SALESORDER + ".id = :orderId ";
+
+    final Session sessionOrderLines = OBDal.getInstance().getSession();
+    final Query<ShipmentInOutLine> queryOrderLines = sessionOrderLines.createQuery(
+        orderLinesHqlQuery, ShipmentInOutLine.class);
+    queryOrderLines.setParameter("orderId", order.getId());
+
+    return queryOrderLines.scroll(ScrollMode.FORWARD_ONLY);
+  }
+
+  private void createInvoiceLine(final ShipmentInOutLine shipmentLine,
+      final BigDecimal invoicedQuantity) {
+    createInvoiceLineProcess.createInvoiceLinesFromDocumentLines(
+        formatShipmentLineToBeInvoiced(shipmentLine, invoicedQuantity), getInvoiceHeader(),
+        ShipmentInOutLine.class);
+  }
+
+  private JSONArray formatShipmentLineToBeInvoiced(final ShipmentInOutLine shipmentInOutLine,
+      final BigDecimal invoicedQuantity) {
+    final JSONArray lines = new JSONArray();
+    try {
+      final JSONObject line = new JSONObject();
+      line.put("uOM", shipmentInOutLine.getUOM().getId());
+      line.put("uOM$_identifier", shipmentInOutLine.getUOM().getIdentifier());
+      line.put("product", shipmentInOutLine.getProduct().getId());
+      line.put("product$_identifier", shipmentInOutLine.getProduct().getIdentifier());
+      line.put("lineNo", shipmentInOutLine.getLineNo());
+      line.put("movementQuantity", invoicedQuantity.toString());
+      line.put("operativeQuantity",
+          shipmentInOutLine.getOperativeQuantity() == null ? shipmentInOutLine
+              .getMovementQuantity().toString() : shipmentInOutLine.getOperativeQuantity()
+              .toString());
+      line.put("id", shipmentInOutLine.getId());
+      line.put("operativeUOM", shipmentInOutLine.getOperativeUOM() == null ? shipmentInOutLine
+          .getUOM().getId() : shipmentInOutLine.getOperativeUOM().getId());
+      line.put("operativeUOM$_identifier",
+          shipmentInOutLine.getOperativeUOM() == null ? shipmentInOutLine.getUOM().getIdentifier()
+              : shipmentInOutLine.getOperativeUOM().getIdentifier());
+      line.put("orderQuantity", "");
+      lines.put(line);
+    } catch (JSONException e) {
+      log.error(e.getMessage());
+    }
+    return lines;
+  }
+
+  private void evictObjects(final Object... objects) {
+    for (final Object object : objects) {
+      if (object != null) {
+        OBDal.getInstance().getSession().evict(object);
+      }
+    }
+  }
+
+  private Invoice getInvoiceHeader() {
+    if (invoice == null) {
+      invoice = createInvoiceHeader();
+    }
+    return invoice;
+  }
+
+  private Invoice createInvoiceHeader() {
+    final Entity invoiceEntity = ModelProvider.getInstance().getEntity(Invoice.class);
+    final Invoice newInvoice = OBProvider.getInstance().get(Invoice.class);
+    final ShipmentInOut shipment = getShipment();
+
+    newInvoice.setClient(shipment.getClient());
+    newInvoice.setOrganization(shipment.getOrganization());
+    final DocumentType invoiceDocumentType = getDocumentTypeForARI(getShipment().getOrganization());
+    newInvoice.setDocumentType(invoiceDocumentType);
+    newInvoice.setTransactionDocument(invoiceDocumentType);
+    String documentNo = Utility.getDocumentNo(OBDal.getInstance().getConnection(false),
+        new DalConnectionProvider(false), RequestContext.get().getVariablesSecureApp(), "",
+        invoiceEntity.getTableName(), newInvoice.getTransactionDocument() == null ? "" : newInvoice
+            .getTransactionDocument().getId(), newInvoice.getDocumentType() == null ? ""
+            : newInvoice.getDocumentType().getId(), false, true);
+    newInvoice.setDocumentNo(documentNo);
+    newInvoice.setDocumentAction("CO");
+    newInvoice.setDocumentStatus("DR");
+    newInvoice.setAccountingDate(getInvoiceDate());
+    newInvoice.setInvoiceDate(getInvoiceDate());
+    newInvoice.setTaxDate(getInvoiceDate());
+    newInvoice.setSalesTransaction(true);
+    newInvoice.setBusinessPartner(shipment.getBusinessPartner());
+    newInvoice.setPartnerAddress(shipment.getPartnerAddress());
+    newInvoice.setPriceList(getPriceList());
+    newInvoice.setCurrency(getCurrency());
+    newInvoice.setSummedLineAmount(BigDecimal.ZERO);
+    newInvoice.setGrandTotalAmount(BigDecimal.ZERO);
+    newInvoice.setWithholdingamount(BigDecimal.ZERO);
+    newInvoice.setPaymentMethod(shipment.getBusinessPartner().getPaymentMethod());
+    newInvoice.setPaymentTerms(shipment.getBusinessPartner().getPaymentTerms());
+
+    checkInvoiceHasAllMandatoryFields(newInvoice);
+
+    OBDal.getInstance().save(newInvoice);
+    return newInvoice;
+  }
+
+  private DocumentType getDocumentTypeForARI(final Organization org) {
+    final List<Object> parameters = new ArrayList<>(3);
+    parameters.add(org.getClient().getId());
+    parameters.add(org.getId());
+    parameters.add("ARI");
+    final String documentTypeId = (String) CallStoredProcedure.getInstance().call("AD_GET_DOCTYPE",
+        parameters, null, false);
+    try {
+      return OBDal.getInstance().get(DocumentType.class, documentTypeId);
+    } catch (Exception e) {
+      throw new OBException("There is no Document type for Sales Invoice defined");
+    }
+  }
+
+  private Currency getCurrency() {
+    return (getPriceList() == null) ? null : getPriceList().getCurrency();
+  }
+
+  private void checkInvoiceHasAllMandatoryFields(final Invoice newInvoice) {
+    Check.isNotNull(newInvoice.getInvoiceDate(), OBMessageUtils.messageBD("ParameterMissing") + " "
+        + OBMessageUtils.messageBD(Invoice.PROPERTY_INVOICEDATE));
+    Check.isNotNull(newInvoice.getPriceList(), OBMessageUtils.messageBD("notnullpricelist"));
+    Check.isNotNull(newInvoice.getCurrency(), OBMessageUtils.messageBD("ParameterMissing") + " "
+        + OBMessageUtils.messageBD(Invoice.PROPERTY_CURRENCY));
+    Check.isNotNull(newInvoice.getPaymentMethod(), newInvoice.getBusinessPartner().getIdentifier()
+        + " " + OBMessageUtils.messageBD("PayementMethodNotdefined"));
+    Check.isNotNull(newInvoice.getPaymentTerms(), OBMessageUtils.messageBD("notnullpaymentterm"));
+  }
+
+  private void processInvoice() {
+    if (invoice != null) {
+      final List<Object> parameters = new ArrayList<>(2);
+      parameters.add(null); // Process Instance parameter
+      parameters.add(invoice.getId());
+      CallStoredProcedure.getInstance().call("C_INVOICE_POST", parameters, null, false, false);
+    }
+  }
+}