Fixed issue 39617: Added new features
authorNono Carballo <nonofce@gmail.com>
Thu, 25 Oct 2018 15:40:15 -0400
changeset 34965 f2c342521137
parent 34964 a3bda4f3376a
child 34966 37ad45032da1
Fixed issue 39617: Added new features

- Three new fields were added to "Request Process" pop up window. The fields
are only visible in Goods Shipment window if the selected document is in
draft status. The fields hold the Invoice Date, the Price List and whether
the invoice generated will be processed or not.
- The ProcessGoods process was modified to consider the new fields added.
- The success message in Process Goods process shows the document number
of the generated invoice and its status.
- Three new parameters were added to Generate Invoice from Goods Shipment
process definition. The fields hold the Invoice Date, the Price List and
whether the invoice generated will be processed or not.
- The Generate Invoice from Goods Shipment action handler was modified to
consider the new fields added.
- Code was refactored. Some classes were renamed, java documentation was
improved.
- Automated test were updated
- Two new automated test were added
src-db/database/sourcedata/AD_MESSAGE.xml
src-db/database/sourcedata/AD_REFERENCE.xml
src-db/database/sourcedata/AD_TEXTINTERFACES.xml
src-db/database/sourcedata/OBUIAPP_PARAMETER.xml
src-db/database/sourcedata/OBUISEL_SELECTOR.xml
src-test/src/org/openbravo/test/materialMgmt/invoiceFromShipment/InvoiceFromShipmentTest.java
src/org/openbravo/common/actionhandler/InvoiceFromShipmentActionHandler.java
src/org/openbravo/erpCommon/ad_actionButton/DocAction.html
src/org/openbravo/erpCommon/ad_actionButton/DocAction.xml
src/org/openbravo/erpCommon/ad_actionButton/ProcessGoods.java
src/org/openbravo/materialmgmt/InvoiceFromGoodsShipmentDefaultValueFilterExpression.java
src/org/openbravo/materialmgmt/InvoiceFromGoodsShipmentPriceListFilterExpression.java
src/org/openbravo/materialmgmt/InvoiceFromGoodsShipmentUtil.java
src/org/openbravo/materialmgmt/InvoiceGeneratorFromGoodsShipment.java
src/org/openbravo/materialmgmt/ShipmentProcessor.java
--- a/src-db/database/sourcedata/AD_MESSAGE.xml	Thu Oct 04 15:59:12 2018 -0400
+++ b/src-db/database/sourcedata/AD_MESSAGE.xml	Thu Oct 25 15:40:15 2018 -0400
@@ -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>
@@ -20965,7 +20977,7 @@
 <!--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]]></MSGTEXT>
+<!--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>
@@ -25188,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>
--- a/src-db/database/sourcedata/AD_REFERENCE.xml	Thu Oct 04 15:59:12 2018 -0400
+++ b/src-db/database/sourcedata/AD_REFERENCE.xml	Thu Oct 25 15:40:15 2018 -0400
@@ -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	Thu Oct 04 15:59:12 2018 -0400
+++ b/src-db/database/sourcedata/AD_TEXTINTERFACES.xml	Thu Oct 25 15:40:15 2018 -0400
@@ -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>
@@ -21551,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	Thu Oct 04 15:59:12 2018 -0400
+++ b/src-db/database/sourcedata/OBUIAPP_PARAMETER.xml	Thu Oct 25 15:40:15 2018 -0400
@@ -884,6 +884,31 @@
 <!--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-->  <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-->  <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 +2303,30 @@
 <!--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-->  <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 +2376,30 @@
 <!--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-->  <SEQNO><![CDATA[10]]></SEQNO>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <AD_REFERENCE_ID><![CDATA[15]]></AD_REFERENCE_ID>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <COLUMNNAME><![CDATA[MovementDate]]></COLUMNNAME>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <ISCENTRALLYMAINTAINED><![CDATA[Y]]></ISCENTRALLYMAINTAINED>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <FIELDLENGTH><![CDATA[0]]></FIELDLENGTH>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <ISMANDATORY><![CDATA[Y]]></ISMANDATORY>
+<!--FA8CA39EA0374C31A426878F80A1E851-->  <DEFAULTVALUE><![CDATA[@MovementDate@]]></DEFAULTVALUE>
+<!--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/OBUISEL_SELECTOR.xml	Thu Oct 04 15:59:12 2018 -0400
+++ b/src-db/database/sourcedata/OBUISEL_SELECTOR.xml	Thu Oct 25 15:40:15 2018 -0400
@@ -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/materialMgmt/invoiceFromShipment/InvoiceFromShipmentTest.java	Thu Oct 04 15:59:12 2018 -0400
+++ b/src-test/src/org/openbravo/test/materialMgmt/invoiceFromShipment/InvoiceFromShipmentTest.java	Thu Oct 25 15:40:15 2018 -0400
@@ -23,6 +23,8 @@
 import static org.junit.Assert.assertThat;
 
 import java.math.BigDecimal;
+import java.util.Calendar;
+import java.util.Date;
 
 import org.codehaus.jettison.json.JSONArray;
 import org.codehaus.jettison.json.JSONException;
@@ -44,7 +46,7 @@
 import org.openbravo.dal.service.OBQuery;
 import org.openbravo.erpCommon.utility.SequenceIdData;
 import org.openbravo.erpCommon.utility.Utility;
-import org.openbravo.materialmgmt.ShipmentProcessor;
+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;
@@ -52,6 +54,7 @@
 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;
@@ -78,6 +81,7 @@
   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() {
@@ -125,7 +129,7 @@
       TestUtils.processShipmentReceipt(shipment);
       OBDal.getInstance().commitAndClose();
 
-      final Invoice invoice = new ShipmentProcessor(shipment.getId())
+      final Invoice invoice = new InvoiceGeneratorFromGoodsShipment(shipment.getId())
           .createAndProcessInvoiceConsideringInvoiceTerms();
       assertGeneratedInvoiceLine(invoice, product, new BigDecimal(12));
 
@@ -183,7 +187,7 @@
       OBDal.getInstance().flush();
       OBDal.getInstance().commitAndClose();
 
-      final Invoice invoice = new ShipmentProcessor(shipment.getId())
+      final Invoice invoice = new InvoiceGeneratorFromGoodsShipment(shipment.getId())
           .createAndProcessInvoiceConsideringInvoiceTerms();
       assertNoInvoiceWasGenerated(invoice);
 
@@ -196,7 +200,7 @@
       TestUtils.processShipmentReceipt(secondShipment);
       OBDal.getInstance().commitAndClose();
 
-      final Invoice secondInvoice = new ShipmentProcessor(secondShipment.getId())
+      final Invoice secondInvoice = new InvoiceGeneratorFromGoodsShipment(secondShipment.getId())
           .createAndProcessInvoiceConsideringInvoiceTerms();
       assertGeneratedInvoiceLine(secondInvoice, productOne, new BigDecimal(12));
       assertGeneratedInvoiceLine(secondInvoice, productTwo, new BigDecimal(12));
@@ -240,7 +244,7 @@
       TestUtils.processShipmentReceipt(shipment);
       OBDal.getInstance().commitAndClose();
 
-      final Invoice invoice = new ShipmentProcessor(shipment.getId())
+      final Invoice invoice = new InvoiceGeneratorFromGoodsShipment(shipment.getId())
           .createAndProcessInvoiceConsideringInvoiceTerms();
       assertGeneratedInvoiceLine(invoice, productOne, new BigDecimal(12));
       assertGeneratedInvoiceLine(invoice, productTwo, new BigDecimal(12));
@@ -321,7 +325,7 @@
       TestUtils.processShipmentReceipt(shipment);
       OBDal.getInstance().commitAndClose();
 
-      final Invoice invoice = new ShipmentProcessor(shipment.getId())
+      final Invoice invoice = new InvoiceGeneratorFromGoodsShipment(shipment.getId())
           .createAndProcessInvoiceConsideringInvoiceTerms();
       assertInvoiceLineNumber(invoice, 2);
       assertGeneratedInvoiceLine(invoice, productOne, new BigDecimal(12));
@@ -337,7 +341,7 @@
       TestUtils.processShipmentReceipt(secondShipment);
       OBDal.getInstance().commitAndClose();
 
-      final Invoice secondInvoice = new ShipmentProcessor(secondShipment.getId())
+      final Invoice secondInvoice = new InvoiceGeneratorFromGoodsShipment(secondShipment.getId())
           .createAndProcessInvoiceConsideringInvoiceTerms();
       assertInvoiceLineNumber(secondInvoice, 2);
       assertGeneratedInvoiceLine(secondInvoice, productTwo, new BigDecimal(12));
@@ -405,7 +409,7 @@
       TestUtils.processShipmentReceipt(shipment);
       OBDal.getInstance().commitAndClose();
 
-      final Invoice invoice = new ShipmentProcessor(shipment.getId())
+      final Invoice invoice = new InvoiceGeneratorFromGoodsShipment(shipment.getId())
           .createAndProcessInvoiceConsideringInvoiceTerms();
       assertInvoiceLineNumber(invoice, 1);
       assertGeneratedInvoiceLine(invoice, productOne, BigDecimal.TEN);
@@ -470,7 +474,7 @@
       TestUtils.processShipmentReceipt(shipment);
       OBDal.getInstance().commitAndClose();
 
-      final Invoice invoice = new ShipmentProcessor(shipment.getId())
+      final Invoice invoice = new InvoiceGeneratorFromGoodsShipment(shipment.getId())
           .createAndProcessInvoiceConsideringInvoiceTerms();
       assertInvoiceLineNumber(invoice, 1);
       assertGeneratedInvoiceLine(invoice, productOne, new BigDecimal(12));
@@ -552,7 +556,7 @@
       TestUtils.processShipmentReceipt(secondShipment);
       OBDal.getInstance().commitAndClose();
 
-      final Invoice secondInvoice = new ShipmentProcessor(secondShipment.getId())
+      final Invoice secondInvoice = new InvoiceGeneratorFromGoodsShipment(secondShipment.getId())
           .createAndProcessInvoiceConsideringInvoiceTerms();
       assertInvoiceLineNumber(secondInvoice, 2);
       assertGeneratedInvoiceLine(secondInvoice, productOne, new BigDecimal(2));
@@ -604,12 +608,12 @@
       TestUtils.processShipmentReceipt(shipment);
       OBDal.getInstance().commitAndClose();
 
-      final Invoice invoice = new ShipmentProcessor(shipment.getId())
+      final Invoice invoice = new InvoiceGeneratorFromGoodsShipment(shipment.getId())
           .createAndProcessInvoiceConsideringInvoiceTerms();
       assertInvoiceLineNumber(invoice, 1);
       assertGeneratedInvoiceLine(invoice, product, new BigDecimal(12));
 
-      final Invoice secondIinvoice = new ShipmentProcessor(shipment.getId())
+      final Invoice secondIinvoice = new InvoiceGeneratorFromGoodsShipment(shipment.getId())
           .createAndProcessInvoiceConsideringInvoiceTerms();
       assertNoInvoiceWasGenerated(secondIinvoice);
 
@@ -621,6 +625,118 @@
     }
   }
 
+  /**
+   * 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);
+      OBDal.getInstance().flush();
+      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);
+      OBDal.getInstance().flush();
+      TestUtils.processShipmentReceipt(shipment);
+      OBDal.getInstance().commitAndClose();
+
+      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).createAndProcessInvoiceConsideringInvoiceTerms();
+      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);
+      OBDal.getInstance().flush();
+      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);
+      OBDal.getInstance().flush();
+      TestUtils.processShipmentReceipt(shipment);
+      OBDal.getInstance().commitAndClose();
+
+      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();
+      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);
@@ -793,4 +909,14 @@
     return lines;
   }
 
+  private void assertInvoiceDatePriceListAndStatus(Invoice invoice, Date invoiceDate,
+      PriceList priceList, String status) {
+    assertThat("Invoice status should have been " + status, invoice.getDocumentStatus(),
+        equalTo(status));
+    assertThat("Invoice date should have been " + invoiceDate, invoice.getInvoiceDate().getTime(),
+        equalTo(invoiceDate.getTime()));
+    assertThat("Price List should have been " + priceList, invoice.getPriceList().getName(),
+        equalTo(priceList.getName()));
+  }
+
 }
--- a/src/org/openbravo/common/actionhandler/InvoiceFromShipmentActionHandler.java	Thu Oct 04 15:59:12 2018 -0400
+++ b/src/org/openbravo/common/actionhandler/InvoiceFromShipmentActionHandler.java	Thu Oct 25 15:40:15 2018 -0400
@@ -18,14 +18,21 @@
  */
 package org.openbravo.common.actionhandler;
 
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+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.ShipmentProcessor;
+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.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -41,12 +48,26 @@
   protected JSONObject doExecute(Map<String, Object> parameters, String content) {
 
     Invoice invoice;
-    JSONObject message = new JSONObject();
+    final JSONObject message = new JSONObject();
     try {
-      JSONObject request = new JSONObject(content);
-      String shipmentId = request.getString("M_InOut_ID");
+      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("MovementDate");
+      final String priceListStr = params.getString("priceList");
+      boolean processInvoice = params.getBoolean("processInvoice");
 
-      invoice = new ShipmentProcessor(shipmentId).createAndProcessInvoiceConsideringInvoiceTerms();
+      final Date invoiceDate = getInvoiceDate(invoiceDateStr);
+      final PriceList priceList = OBDal.getInstance().getProxy(PriceList.class, priceListStr);
+
+      if (processInvoice) {
+        invoice = new InvoiceGeneratorFromGoodsShipment(shipmentId, invoiceDate, priceList)
+            .createAndProcessInvoiceConsideringInvoiceTerms();
+      } else {
+        invoice = new InvoiceGeneratorFromGoodsShipment(shipmentId, invoiceDate, priceList)
+            .createInvoiceConsideringInvoiceTerms();
+      }
+
       message.put(MESSAGE, getSuccessMessage(invoice));
 
     } catch (Exception e) {
@@ -60,8 +81,36 @@
     return message;
   }
 
-  private JSONObject getErrorMessage(Exception e) {
-    JSONObject errorMessage = new JSONObject();
+  private Date getInvoiceDate(final String invoiceDateStr) {
+    Date invoiceDate = Calendar.getInstance().getTime();
+    try {
+      final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
+      invoiceDate = dateFormatter.parse(invoiceDateStr);
+    } catch (ParseException e) {
+      log.error("Not possible to parse the following date: " + invoiceDateStr, e);
+    }
+    return invoiceDate;
+  }
+
+  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"));
@@ -72,24 +121,4 @@
     return errorMessage;
   }
 
-  protected JSONObject getSuccessMessage(Invoice invoice) {
-    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()));
-      } else {
-        successMessage.put(TEXT, OBMessageUtils.messageBD("NoInvoiceGenerated"));
-      }
-    } catch (JSONException e) {
-      log.error(e.getMessage());
-    }
-    return successMessage;
-  }
-
 }
--- a/src/org/openbravo/erpCommon/ad_actionButton/DocAction.html	Thu Oct 04 15:59:12 2018 -0400
+++ b/src/org/openbravo/erpCommon/ad_actionButton/DocAction.html	Thu Oct 25 15:40:15 2018 -0400
@@ -94,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);
@@ -133,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;
     }
@@ -175,6 +185,9 @@
           documentIsInDraftStatus = (frm.inpdocstatus.value === 'DR');
       
       displayLogicElement('invoiceIfPossible', documentIsInDraftStatus && currentWindowId === goodsShipmentWindow);
+      displayLogicElement('processInvoice', documentIsInDraftStatus && currentWindowId === goodsShipmentWindow);
+      displayLogicElement('invoiceDateRow', documentIsInDraftStatus && currentWindowId === goodsShipmentWindow);
+      displayLogicElement('priceListRow', documentIsInDraftStatus && currentWindowId === goodsShipmentWindow);
     }
     </script>
 </head>
@@ -460,7 +473,69 @@
               	  </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" checked>
+              	  </span>
+              	</td>
+              </tr>
+              
               <tr><td height="20px"></td></tr>
 
               <tr>
--- a/src/org/openbravo/erpCommon/ad_actionButton/DocAction.xml	Thu Oct 04 15:59:12 2018 -0400
+++ b/src/org/openbravo/erpCommon/ad_actionButton/DocAction.xml	Thu Oct 25 15:40:15 2018 -0400
@@ -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	Thu Oct 04 15:59:12 2018 -0400
+++ b/src/org/openbravo/erpCommon/ad_actionButton/ProcessGoods.java	Thu Oct 25 15:40:15 2018 -0400
@@ -23,6 +23,7 @@
 import java.io.PrintWriter;
 import java.math.BigDecimal;
 import java.text.ParseException;
+import java.util.Calendar;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
@@ -47,20 +48,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.ShipmentProcessor;
+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";
@@ -212,8 +218,27 @@
       log4j.debug(myMessage.getMessage());
       vars.setMessage(strTabId, myMessage);
 
-      if (invoiceIfPossible && !"Error".equalsIgnoreCase(myMessage.getType())) {
-        new ShipmentProcessor(goods.getId()).createAndProcessInvoiceConsideringInvoiceTerms();
+      if (GOODS_SHIPMENT_WINDOW.equals(strWindowId) && invoiceIfPossible
+          && !"Error".equalsIgnoreCase(myMessage.getType())) {
+
+        final boolean processInvoice = StringUtils.equalsIgnoreCase(
+            vars.getStringParameter("inpProcessInvoice"), "on");
+        final String invoiceDateStr = vars.getStringParameter("inpInvoiceDate");
+        final String priceListStr = vars.getStringParameter("inpPriceList");
+
+        Date invoiceDate = getInvoiceDate(invoiceDateStr);
+        final PriceList priceList = OBDal.getInstance().getProxy(PriceList.class, priceListStr);
+
+        Invoice invoice;
+        if (processInvoice) {
+          invoice = new InvoiceGeneratorFromGoodsShipment(goods.getId(), invoiceDate, priceList)
+              .createAndProcessInvoiceConsideringInvoiceTerms();
+        } else {
+          invoice = new InvoiceGeneratorFromGoodsShipment(goods.getId(), invoiceDate, priceList)
+              .createInvoiceConsideringInvoiceTerms();
+        }
+        myMessage = getResultMessage(invoice);
+        vars.setMessage(strTabId, myMessage);
       }
 
       String strWindowPath = Utility.getTabURL(strTabId, "R", true);
@@ -240,6 +265,29 @@
     }
   }
 
+  private Date getInvoiceDate(final String invoiceDateStr) {
+    Date invoiceDate = Calendar.getInstance().getTime();
+    try {
+      invoiceDate = OBDateUtils.getDate(invoiceDateStr);
+    } catch (ParseException e) {
+      log4j.error("Not possible to parse the following date: " + invoiceDateStr, e);
+    }
+    return invoiceDate;
+  }
+
+  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 {
@@ -279,12 +327,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);
@@ -314,6 +362,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();
 
@@ -454,7 +511,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	Thu Oct 25 15:40:15 2018 -0400
@@ -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	Thu Oct 25 15:40:15 2018 -0400
@@ -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	Thu Oct 25 15:40:15 2018 -0400
@@ -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	Thu Oct 25 15:40:15 2018 -0400
@@ -0,0 +1,383 @@
+/*
+ *************************************************************************
+ * 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.Date;
+import java.util.HashSet;
+import java.util.List;
+
+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.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.weld.WeldUtils;
+import org.openbravo.client.kernel.RequestContext;
+import org.openbravo.common.actionhandler.createlinesfromprocess.CreateInvoiceLinesFromProcess;
+import org.openbravo.dal.service.OBDal;
+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.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.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 String C_INVOICE_TABLE_ID = "318";
+  private static final Logger log = LoggerFactory
+      .getLogger(InvoiceGeneratorFromGoodsShipment.class);
+  private ShipmentInOut shipment;
+  private Invoice invoice;
+  private CreateInvoiceLinesFromProcess createInvoiceLineProcess;
+  private Date invoiceDate;
+  private PriceList priceList;
+
+  private static final String AFTER_ORDER_DELIVERY = "O";
+  private static final String AFTER_DELIVERY = "D";
+  private static final String IMMEDIATE = "I";
+
+  /**
+   * Creates an {@link InvoiceGeneratorFromGoodsShipment} based shipment Id
+   * 
+   * @param shipmentId
+   *          The shipment Id
+   * @param invoiceDate
+   *          The invoice date.
+   * @param priceList
+   *          The invoice price list
+   */
+  public InvoiceGeneratorFromGoodsShipment(final String shipmentId, final Date invoiceDate,
+      final PriceList priceList) {
+    this.shipment = OBDal.getInstance().get(ShipmentInOut.class, shipmentId);
+    this.createInvoiceLineProcess = WeldUtils
+        .getInstanceFromStaticBeanManager(CreateInvoiceLinesFromProcess.class);
+    this.invoiceDate = invoiceDate;
+    this.priceList = priceList;
+  }
+
+  /**
+   * 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 and process an Invoice from Goods Shipment, considering the invoice terms of orders
+   * linked to shipment lines.
+   * 
+   * @return The invoice created
+   */
+  public Invoice createAndProcessInvoiceConsideringInvoiceTerms() {
+    try {
+
+      createInvoiceConsideringInvoiceTerms();
+      if (invoice != null) {
+        processInvoice();
+        OBDal.getInstance().refresh(invoice);
+      }
+    } catch (OBException e) {
+      executeRollBack();
+      throw new OBException(e.getMessage());
+    } catch (Exception e1) {
+      executeRollBack();
+      Throwable e3 = DbUtility.getUnderlyingSQLException(e1);
+      throw new OBException(e3);
+    }
+
+    return invoice;
+  }
+
+  /**
+   * Creates an Invoice from Goods Shipment, considering the invoice terms of orders linked to
+   * shipment lines. The invoice is in status 'DR'
+   * 
+   * @return The invoice created
+   */
+  public Invoice createInvoiceConsideringInvoiceTerms() {
+    try {
+
+      createInvoice();
+
+    } catch (OBException e) {
+      executeRollBack();
+      throw new OBException(e.getMessage());
+    }
+
+    return invoice;
+  }
+
+  private Invoice createInvoice() {
+    HashSet<String> ordersAlreadyInvoiced = new HashSet<>();
+    try (ScrollableResults scrollShipmentLines = getShipmentLines()) {
+      while (scrollShipmentLines.next()) {
+        final ShipmentInOutLine shipmentLine = OBDal.getInstance().get(ShipmentInOutLine.class,
+            scrollShipmentLines.get()[0]);
+
+        final OrderLine orderLine = shipmentLine.getSalesOrderLine();
+        boolean shipmentLineIsLinkedToSalesOrderLine = orderLine != null;
+        final Order order = shipmentLineIsLinkedToSalesOrderLine ? orderLine.getSalesOrder() : null;
+        final String invoiceTerms = order != null ? order.getInvoiceTerms() : null;
+        final Long deliveryStatus = order != null ? order.getDeliveryStatus() : null;
+
+        if (AFTER_DELIVERY.equals(invoiceTerms) || IMMEDIATE.equals(invoiceTerms)
+            || !shipmentLineIsLinkedToSalesOrderLine) {
+          invoiceShimpentLineIfNotYetInvoiced(shipmentLine);
+
+        } else if (AFTER_ORDER_DELIVERY.equals(invoiceTerms) && deliveryStatus == 100
+            && !ordersAlreadyInvoiced.contains(order.getId())) {
+
+          inovoiceAllShipmentLinesNotFullyInvoicedLinkedToOrder(order);
+          ordersAlreadyInvoiced.add(order.getId());
+        }
+      }
+      OBDal.getInstance().flush();
+    }
+    return invoice;
+  }
+
+  private ScrollableResults getShipmentLines() {
+    final String shipmentLinesHQLQuery = "select iol.id " //
+        + "from " + ShipmentInOutLine.ENTITY_NAME + " iol " //
+        + "where " + ShipmentInOutLine.PROPERTY_SHIPMENTRECEIPT + ".id = :shipmentId ";
+
+    final Session session = OBDal.getInstance().getSession();
+    final Query<String> query = session.createQuery(shipmentLinesHQLQuery, String.class);
+    query.setParameter("shipmentId", shipment.getId());
+
+    return query.scroll(ScrollMode.FORWARD_ONLY);
+  }
+
+  protected void invoiceShimpentLineIfNotYetInvoiced(final ShipmentInOutLine shipmentLine) {
+    final BigDecimal totalInvoiced = getTotalInvoicedForShipmentLine(shipmentLine);
+    if (totalInvoiced.compareTo(shipmentLine.getMovementQuantity()) != 0) {
+      invoiceShipmentLine(shipmentLine);
+    }
+  }
+
+  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 ";
+
+    final Session sessionInvoiceLines = OBDal.getInstance().getSession();
+    final Query<BigDecimal> queryInvoiceLines = sessionInvoiceLines.createQuery(
+        invoiceLinesHqlQuery, BigDecimal.class);
+    queryInvoiceLines.setParameter("shipmentLineId", iol.getId());
+
+    return queryInvoiceLines.uniqueResult();
+  }
+
+  private void invoiceShipmentLine(final ShipmentInOutLine shipmentLine) {
+    createInvoiceShipmentLine(shipmentLine, shipmentLine.getMovementQuantity());
+
+  }
+
+  private void createInvoiceShipmentLine(final ShipmentInOutLine shipmentLine,
+      final BigDecimal invoicedQuantity) {
+    createInvoiceLineProcess.createInvoiceLinesFromDocumentLines(
+        getShipmentLineToBeInvoiced(shipmentLine, invoicedQuantity), getInvoiceHeader(),
+        ShipmentInOutLine.class);
+  }
+
+  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 inovoiceAllShipmentLinesNotFullyInvoicedLinkedToOrder(final Order order) {
+    try (ScrollableResults scrollOrderShipmentLines = getShipmentLinesLinkedToASalesOrder(order)) {
+      while (scrollOrderShipmentLines.next()) {
+
+        final ShipmentInOutLine iol = OBDal.getInstance().get(ShipmentInOutLine.class,
+            (String) scrollOrderShipmentLines.get()[0]);
+        final BigDecimal invoicedQuantity = getTotalInvoicedForShipmentLine(iol);
+        if (invoicedQuantity.compareTo(iol.getMovementQuantity()) != 0) {
+          createInvoiceShipmentLine(iol, iol.getMovementQuantity().subtract(invoicedQuantity));
+        }
+      }
+    }
+  }
+
+  private ScrollableResults getShipmentLinesLinkedToASalesOrder(final Order order) {
+    final String orderLinesHqlQuery = "select iol.id " //
+        + "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<String> queryOrderLines = sessionOrderLines.createQuery(orderLinesHqlQuery,
+        String.class);
+    queryOrderLines.setParameter("orderId", order.getId());
+
+    return queryOrderLines.scroll(ScrollMode.FORWARD_ONLY);
+  }
+
+  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);
+
+    newInvoice.setClient(shipment.getClient());
+    newInvoice.setOrganization(shipment.getOrganization());
+    final DocumentType invoiceDocumentType = getInvoiceDocumentType();
+    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());
+    OBDal.getInstance().save(newInvoice);
+    return newInvoice;
+  }
+
+  private DocumentType getInvoiceDocumentType() {
+    String hql = "from DocumentType dt where dt.salesTransaction = true" //
+        + " and dt.default = true and dt.table.id = :cInvoiceTableId" //
+        + " and Ad_Isorgincluded(:invoiceOrgId, dt.organization.id, :clientId) <> -1";
+
+    final Query<DocumentType> query = OBDal.getInstance().getSession()
+        .createQuery(hql.toString(), DocumentType.class);
+    query.setParameter("cInvoiceTableId", C_INVOICE_TABLE_ID);
+    query.setParameter("invoiceOrgId", this.shipment.getOrganization().getId());
+    query.setParameter("clientId", this.shipment.getClient().getId());
+    query.setMaxResults(1);
+
+    final DocumentType invoiceDocumentType = query.uniqueResult();
+
+    if (invoiceDocumentType == null) {
+      throw new OBException("There is no Document type for Sales Invoice defined");
+    }
+    return invoiceDocumentType;
+  }
+
+  private Date getInvoiceDate() {
+    if (this.invoiceDate != null) {
+      return this.invoiceDate;
+    }
+    return this.shipment.getMovementDate();
+  }
+
+  private PriceList getPriceList() {
+    if (this.priceList != null) {
+      return this.priceList;
+    }
+    return this.shipment.getBusinessPartner().getPriceList();
+  }
+
+  private Currency getCurrency() {
+    return (getPriceList() == null) ? null : getPriceList().getCurrency();
+  }
+
+  private void processInvoice() 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, false, false);
+    }
+  }
+
+  protected void executeRollBack() {
+    try {
+      log.error("Error executing creating Invoice");
+      OBDal.getInstance().rollbackAndClose();
+    } catch (Exception e2) {
+      log.error("An error happened when rollback was executed.", e2);
+    }
+  }
+}
--- a/src/org/openbravo/materialmgmt/ShipmentProcessor.java	Thu Oct 04 15:59:12 2018 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,313 +0,0 @@
-/*
- *************************************************************************
- * 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.HashSet;
-import java.util.List;
-
-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.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.weld.WeldUtils;
-import org.openbravo.client.kernel.RequestContext;
-import org.openbravo.common.actionhandler.createlinesfromprocess.CreateInvoiceLinesFromProcess;
-import org.openbravo.dal.service.OBDal;
-import org.openbravo.erpCommon.utility.Utility;
-import org.openbravo.model.common.enterprise.DocumentType;
-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.materialmgmt.transaction.ShipmentInOut;
-import org.openbravo.model.materialmgmt.transaction.ShipmentInOutLine;
-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;
-
-/**
- * Class to process Goods Shipments
- *
- */
-public class ShipmentProcessor {
-
-  private static final String C_INVOICE_TABLE_ID = "318";
-  private static final Logger log = LoggerFactory.getLogger(ShipmentProcessor.class);
-  private ShipmentInOut shipment;
-  Invoice invoice;
-  private CreateInvoiceLinesFromProcess createInvoiceLineProcess;
-
-  private static final String AFTER_ORDER_DELIVERY = "O";
-  private static final String AFTER_DELIVERY = "D";
-  private static final String IMMEDIATE = "I";
-
-  public ShipmentProcessor(String shipmentId) {
-    this.shipment = OBDal.getInstance().get(ShipmentInOut.class, shipmentId);
-    this.createInvoiceLineProcess = WeldUtils
-        .getInstanceFromStaticBeanManager(CreateInvoiceLinesFromProcess.class);
-  }
-
-  /**
-   * Creates and process an Invoice from Goods Shipment, considering the invoice terms of orders
-   * linked to shipment lines.
-   * 
-   * @return The invoice created
-   */
-  public Invoice createAndProcessInvoiceConsideringInvoiceTerms() {
-    try {
-      createInvoiceConsideringInvoiceTerms();
-      if (invoice != null) {
-        processInvoice();
-      }
-
-    } catch (OBException e) {
-      executeRollBack();
-      throw new OBException(e.getMessage());
-    } catch (Exception e1) {
-      executeRollBack();
-      Throwable e3 = DbUtility.getUnderlyingSQLException(e1);
-      throw new OBException(e3);
-    }
-
-    return invoice;
-  }
-
-  private Invoice createInvoiceConsideringInvoiceTerms() {
-    HashSet<String> ordersAlreadyInvoiced = new HashSet<>();
-    try (ScrollableResults scrollShipmentLines = getShipmentLines()) {
-      while (scrollShipmentLines.next()) {
-        final ShipmentInOutLine shipmentLine = OBDal.getInstance().get(ShipmentInOutLine.class,
-            scrollShipmentLines.get()[0]);
-
-        final OrderLine orderLine = shipmentLine.getSalesOrderLine();
-        boolean shipmentLineIsLinkedToSalesOrderLine = orderLine != null;
-        final Order order = shipmentLineIsLinkedToSalesOrderLine ? orderLine.getSalesOrder() : null;
-        final String invoiceTerms = order != null ? order.getInvoiceTerms() : null;
-        final Long deliveryStatus = order != null ? order.getDeliveryStatus() : null;
-
-        if (AFTER_DELIVERY.equals(invoiceTerms) || IMMEDIATE.equals(invoiceTerms)
-            || !shipmentLineIsLinkedToSalesOrderLine) {
-          invoiceShimpentLineIfNotYetInvoiced(shipmentLine);
-
-        } else if (AFTER_ORDER_DELIVERY.equals(invoiceTerms) && deliveryStatus == 100
-            && !ordersAlreadyInvoiced.contains(order.getId())) {
-
-          inovoiceAllShipmentLinesNotFullyInvoicedLinkedToOrder(order);
-          ordersAlreadyInvoiced.add(order.getId());
-        }
-      }
-      OBDal.getInstance().flush();
-    }
-    return invoice;
-  }
-
-  private ScrollableResults getShipmentLines() {
-    final String shipmentLinesHQLQuery = "select iol.id " //
-        + "from " + ShipmentInOutLine.ENTITY_NAME + " iol " //
-        + "where " + ShipmentInOutLine.PROPERTY_SHIPMENTRECEIPT + ".id = :shipmentId ";
-
-    final Session session = OBDal.getInstance().getSession();
-    final Query<String> query = session.createQuery(shipmentLinesHQLQuery, String.class);
-    query.setParameter("shipmentId", shipment.getId());
-
-    return query.scroll(ScrollMode.FORWARD_ONLY);
-  }
-
-  protected void invoiceShimpentLineIfNotYetInvoiced(final ShipmentInOutLine shipmentLine) {
-    final BigDecimal totalInvoiced = getTotalInvoicedForShipmentLine(shipmentLine);
-    if (totalInvoiced.compareTo(shipmentLine.getMovementQuantity()) != 0) {
-      invoiceShipmentLine(shipmentLine);
-    }
-  }
-
-  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 ";
-
-    final Session sessionInvoiceLines = OBDal.getInstance().getSession();
-    final Query<BigDecimal> queryInvoiceLines = sessionInvoiceLines.createQuery(
-        invoiceLinesHqlQuery, BigDecimal.class);
-    queryInvoiceLines.setParameter("shipmentLineId", iol.getId());
-
-    return queryInvoiceLines.uniqueResult();
-  }
-
-  private void invoiceShipmentLine(final ShipmentInOutLine shipmentLine) {
-    createInvoiceShipmentLine(shipmentLine, shipmentLine.getMovementQuantity());
-
-  }
-
-  private void createInvoiceShipmentLine(final ShipmentInOutLine shipmentLine,
-      final BigDecimal invoicedQuantity) {
-    createInvoiceLineProcess.createInvoiceLinesFromDocumentLines(
-        getShipmentLineToBeInvoiced(shipmentLine, invoicedQuantity), getInvoiceHeader(),
-        ShipmentInOutLine.class);
-  }
-
-  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 inovoiceAllShipmentLinesNotFullyInvoicedLinkedToOrder(final Order order) {
-    try (ScrollableResults scrollOrderShipmentLines = getShipmentLinesLinkedToASalesOrder(order)) {
-      while (scrollOrderShipmentLines.next()) {
-
-        final ShipmentInOutLine iol = OBDal.getInstance().get(ShipmentInOutLine.class,
-            (String) scrollOrderShipmentLines.get()[0]);
-        final BigDecimal invoicedQuantity = getTotalInvoicedForShipmentLine(iol);
-        if (invoicedQuantity.compareTo(iol.getMovementQuantity()) != 0) {
-          createInvoiceShipmentLine(iol, iol.getMovementQuantity().subtract(invoicedQuantity));
-        }
-      }
-    }
-  }
-
-  private ScrollableResults getShipmentLinesLinkedToASalesOrder(final Order order) {
-    final String orderLinesHqlQuery = "select iol.id " //
-        + "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<String> queryOrderLines = sessionOrderLines.createQuery(orderLinesHqlQuery,
-        String.class);
-    queryOrderLines.setParameter("orderId", order.getId());
-
-    return queryOrderLines.scroll(ScrollMode.FORWARD_ONLY);
-  }
-
-  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);
-
-    newInvoice.setClient(shipment.getClient());
-    newInvoice.setOrganization(shipment.getOrganization());
-    final DocumentType invoiceDocumentType = getInvoiceDocumentType();
-    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(shipment.getAccountingDate());
-    newInvoice.setInvoiceDate(shipment.getMovementDate());
-    newInvoice.setTaxDate(shipment.getMovementDate());
-    newInvoice.setSalesTransaction(true);
-    newInvoice.setBusinessPartner(shipment.getBusinessPartner());
-    newInvoice.setPartnerAddress(shipment.getPartnerAddress());
-    newInvoice.setPriceList(shipment.getBusinessPartner().getPriceList());
-    newInvoice.setCurrency((shipment.getBusinessPartner().getPriceList() == null) ? null : shipment
-        .getBusinessPartner().getPriceList().getCurrency());
-    newInvoice.setSummedLineAmount(BigDecimal.ZERO);
-    newInvoice.setGrandTotalAmount(BigDecimal.ZERO);
-    newInvoice.setWithholdingamount(BigDecimal.ZERO);
-    newInvoice.setPaymentMethod(shipment.getBusinessPartner().getPaymentMethod());
-    newInvoice.setPaymentTerms(shipment.getBusinessPartner().getPaymentTerms());
-    OBDal.getInstance().save(newInvoice);
-    return newInvoice;
-  }
-
-  private DocumentType getInvoiceDocumentType() {
-    String hql = "from DocumentType dt where dt.salesTransaction = true" //
-        + " and dt.default = true and dt.table.id = :cInvoiceTableId" //
-        + " and Ad_Isorgincluded(:invoiceOrgId, dt.organization.id, :clientId) <> -1";
-
-    final Query<DocumentType> query = OBDal.getInstance().getSession()
-        .createQuery(hql.toString(), DocumentType.class);
-    query.setParameter("cInvoiceTableId", C_INVOICE_TABLE_ID);
-    query.setParameter("invoiceOrgId", this.shipment.getOrganization().getId());
-    query.setParameter("clientId", this.shipment.getClient().getId());
-    query.setMaxResults(1);
-
-    final DocumentType invoiceDocumentType = query.uniqueResult();
-
-    if (invoiceDocumentType == null) {
-      throw new OBException("There is no Document type for Sales Invoice defined");
-    }
-    return invoiceDocumentType;
-  }
-
-  private void processInvoice() 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, false, false);
-    }
-  }
-
-  protected void executeRollBack() {
-    try {
-      log.error("Error executing creating Invoice");
-      OBDal.getInstance().rollbackAndClose();
-    } catch (Exception e2) {
-      log.error("An error happened when rollback was executed.", e2);
-    }
-  }
-}