diff --git a/src-db/database/sourcedata/AD_MESSAGE.xml b/src-db/database/sourcedata/AD_MESSAGE.xml
--- a/src-db/database/sourcedata/AD_MESSAGE.xml
+++ b/src-db/database/sourcedata/AD_MESSAGE.xml
@@ -36,6 +36,18 @@
 <!--0745179AC41245D78FB81B40870633F9-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--0745179AC41245D78FB81B40870633F9--></AD_MESSAGE>
 
+<!--0B6A47E966604FF1B300CE726D60CE25--><AD_MESSAGE>
+<!--0B6A47E966604FF1B300CE726D60CE25-->  <AD_MESSAGE_ID><![CDATA[0B6A47E966604FF1B300CE726D60CE25]]></AD_MESSAGE_ID>
+<!--0B6A47E966604FF1B300CE726D60CE25-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--0B6A47E966604FF1B300CE726D60CE25-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--0B6A47E966604FF1B300CE726D60CE25-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--0B6A47E966604FF1B300CE726D60CE25-->  <VALUE><![CDATA[OBMOBC_FilterQueryBuilderErrEmptyValue]]></VALUE>
+<!--0B6A47E966604FF1B300CE726D60CE25-->  <MSGTEXT><![CDATA[Value must be not null]]></MSGTEXT>
+<!--0B6A47E966604FF1B300CE726D60CE25-->  <MSGTYPE><![CDATA[I]]></MSGTYPE>
+<!--0B6A47E966604FF1B300CE726D60CE25-->  <AD_MODULE_ID><![CDATA[08943B85ADF64E708797A753E5B6AAEE]]></AD_MODULE_ID>
+<!--0B6A47E966604FF1B300CE726D60CE25-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--0B6A47E966604FF1B300CE726D60CE25--></AD_MESSAGE>
+
 <!--0EE7DA62B0AE4F3CA99837B1CD8FD1F7--><AD_MESSAGE>
 <!--0EE7DA62B0AE4F3CA99837B1CD8FD1F7-->  <AD_MESSAGE_ID><![CDATA[0EE7DA62B0AE4F3CA99837B1CD8FD1F7]]></AD_MESSAGE_ID>
 <!--0EE7DA62B0AE4F3CA99837B1CD8FD1F7-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -168,6 +180,18 @@
 <!--32360CCD780547EB9E2610F3D38BE46E-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--32360CCD780547EB9E2610F3D38BE46E--></AD_MESSAGE>
 
+<!--35E2D9D431214A948815A5579076615C--><AD_MESSAGE>
+<!--35E2D9D431214A948815A5579076615C-->  <AD_MESSAGE_ID><![CDATA[35E2D9D431214A948815A5579076615C]]></AD_MESSAGE_ID>
+<!--35E2D9D431214A948815A5579076615C-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--35E2D9D431214A948815A5579076615C-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--35E2D9D431214A948815A5579076615C-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--35E2D9D431214A948815A5579076615C-->  <VALUE><![CDATA[OBMOBC_FilterQueryBuilderErrInvalidNumber]]></VALUE>
+<!--35E2D9D431214A948815A5579076615C-->  <MSGTEXT><![CDATA[Number format is not valid]]></MSGTEXT>
+<!--35E2D9D431214A948815A5579076615C-->  <MSGTYPE><![CDATA[I]]></MSGTYPE>
+<!--35E2D9D431214A948815A5579076615C-->  <AD_MODULE_ID><![CDATA[08943B85ADF64E708797A753E5B6AAEE]]></AD_MODULE_ID>
+<!--35E2D9D431214A948815A5579076615C-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--35E2D9D431214A948815A5579076615C--></AD_MESSAGE>
+
 <!--38DF240154074A9793BCCB93C3C7FC2F--><AD_MESSAGE>
 <!--38DF240154074A9793BCCB93C3C7FC2F-->  <AD_MESSAGE_ID><![CDATA[38DF240154074A9793BCCB93C3C7FC2F]]></AD_MESSAGE_ID>
 <!--38DF240154074A9793BCCB93C3C7FC2F-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -288,6 +312,18 @@
 <!--496D9E4AE9C042989AA2231E8CC21E10-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--496D9E4AE9C042989AA2231E8CC21E10--></AD_MESSAGE>
 
+<!--4ABC073A53CF495A979146B9538F12FE--><AD_MESSAGE>
+<!--4ABC073A53CF495A979146B9538F12FE-->  <AD_MESSAGE_ID><![CDATA[4ABC073A53CF495A979146B9538F12FE]]></AD_MESSAGE_ID>
+<!--4ABC073A53CF495A979146B9538F12FE-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--4ABC073A53CF495A979146B9538F12FE-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--4ABC073A53CF495A979146B9538F12FE-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--4ABC073A53CF495A979146B9538F12FE-->  <VALUE><![CDATA[OBMOBC_FilterQueryBuilderLessThan]]></VALUE>
+<!--4ABC073A53CF495A979146B9538F12FE-->  <MSGTEXT><![CDATA[Less than]]></MSGTEXT>
+<!--4ABC073A53CF495A979146B9538F12FE-->  <MSGTYPE><![CDATA[I]]></MSGTYPE>
+<!--4ABC073A53CF495A979146B9538F12FE-->  <AD_MODULE_ID><![CDATA[08943B85ADF64E708797A753E5B6AAEE]]></AD_MODULE_ID>
+<!--4ABC073A53CF495A979146B9538F12FE-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--4ABC073A53CF495A979146B9538F12FE--></AD_MESSAGE>
+
 <!--4BBC40BE821C40A39FF6229D01F27752--><AD_MESSAGE>
 <!--4BBC40BE821C40A39FF6229D01F27752-->  <AD_MESSAGE_ID><![CDATA[4BBC40BE821C40A39FF6229D01F27752]]></AD_MESSAGE_ID>
 <!--4BBC40BE821C40A39FF6229D01F27752-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -444,6 +480,18 @@
 <!--7000D29DD14C4784A60C4269B51C7556-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--7000D29DD14C4784A60C4269B51C7556--></AD_MESSAGE>
 
+<!--7767324DFA6247D6956E74E3943C1F2B--><AD_MESSAGE>
+<!--7767324DFA6247D6956E74E3943C1F2B-->  <AD_MESSAGE_ID><![CDATA[7767324DFA6247D6956E74E3943C1F2B]]></AD_MESSAGE_ID>
+<!--7767324DFA6247D6956E74E3943C1F2B-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--7767324DFA6247D6956E74E3943C1F2B-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--7767324DFA6247D6956E74E3943C1F2B-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--7767324DFA6247D6956E74E3943C1F2B-->  <VALUE><![CDATA[OBMOBC_FilterQueryBuilderErrInvalidDate]]></VALUE>
+<!--7767324DFA6247D6956E74E3943C1F2B-->  <MSGTEXT><![CDATA[Date format is not valid]]></MSGTEXT>
+<!--7767324DFA6247D6956E74E3943C1F2B-->  <MSGTYPE><![CDATA[I]]></MSGTYPE>
+<!--7767324DFA6247D6956E74E3943C1F2B-->  <AD_MODULE_ID><![CDATA[08943B85ADF64E708797A753E5B6AAEE]]></AD_MODULE_ID>
+<!--7767324DFA6247D6956E74E3943C1F2B-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--7767324DFA6247D6956E74E3943C1F2B--></AD_MESSAGE>
+
 <!--7DF82A98667E4F73B7ECD92C7F6D2020--><AD_MESSAGE>
 <!--7DF82A98667E4F73B7ECD92C7F6D2020-->  <AD_MESSAGE_ID><![CDATA[7DF82A98667E4F73B7ECD92C7F6D2020]]></AD_MESSAGE_ID>
 <!--7DF82A98667E4F73B7ECD92C7F6D2020-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -540,6 +588,18 @@
 <!--953E975B9193423983F3C371702147E6-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--953E975B9193423983F3C371702147E6--></AD_MESSAGE>
 
+<!--9925F9856B92417CA4119158FDA68B12--><AD_MESSAGE>
+<!--9925F9856B92417CA4119158FDA68B12-->  <AD_MESSAGE_ID><![CDATA[9925F9856B92417CA4119158FDA68B12]]></AD_MESSAGE_ID>
+<!--9925F9856B92417CA4119158FDA68B12-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--9925F9856B92417CA4119158FDA68B12-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--9925F9856B92417CA4119158FDA68B12-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--9925F9856B92417CA4119158FDA68B12-->  <VALUE><![CDATA[OBMOBC_FilterQueryBuilderMoreThan]]></VALUE>
+<!--9925F9856B92417CA4119158FDA68B12-->  <MSGTEXT><![CDATA[More than]]></MSGTEXT>
+<!--9925F9856B92417CA4119158FDA68B12-->  <MSGTYPE><![CDATA[I]]></MSGTYPE>
+<!--9925F9856B92417CA4119158FDA68B12-->  <AD_MODULE_ID><![CDATA[08943B85ADF64E708797A753E5B6AAEE]]></AD_MODULE_ID>
+<!--9925F9856B92417CA4119158FDA68B12-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--9925F9856B92417CA4119158FDA68B12--></AD_MESSAGE>
+
 <!--9D5F5B0449A44937BE7B50E69B4A98C1--><AD_MESSAGE>
 <!--9D5F5B0449A44937BE7B50E69B4A98C1-->  <AD_MESSAGE_ID><![CDATA[9D5F5B0449A44937BE7B50E69B4A98C1]]></AD_MESSAGE_ID>
 <!--9D5F5B0449A44937BE7B50E69B4A98C1-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -552,6 +612,30 @@
 <!--9D5F5B0449A44937BE7B50E69B4A98C1-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--9D5F5B0449A44937BE7B50E69B4A98C1--></AD_MESSAGE>
 
+<!--9E5068541823448FB0D4A09F898F10A1--><AD_MESSAGE>
+<!--9E5068541823448FB0D4A09F898F10A1-->  <AD_MESSAGE_ID><![CDATA[9E5068541823448FB0D4A09F898F10A1]]></AD_MESSAGE_ID>
+<!--9E5068541823448FB0D4A09F898F10A1-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--9E5068541823448FB0D4A09F898F10A1-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--9E5068541823448FB0D4A09F898F10A1-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--9E5068541823448FB0D4A09F898F10A1-->  <VALUE><![CDATA[OBMOBC_FilterQueryBuilderErrEmpty]]></VALUE>
+<!--9E5068541823448FB0D4A09F898F10A1-->  <MSGTEXT><![CDATA[Please select a filter condition]]></MSGTEXT>
+<!--9E5068541823448FB0D4A09F898F10A1-->  <MSGTYPE><![CDATA[I]]></MSGTYPE>
+<!--9E5068541823448FB0D4A09F898F10A1-->  <AD_MODULE_ID><![CDATA[08943B85ADF64E708797A753E5B6AAEE]]></AD_MODULE_ID>
+<!--9E5068541823448FB0D4A09F898F10A1-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--9E5068541823448FB0D4A09F898F10A1--></AD_MESSAGE>
+
+<!--9EC81DD2693B434183FA70E8E832955C--><AD_MESSAGE>
+<!--9EC81DD2693B434183FA70E8E832955C-->  <AD_MESSAGE_ID><![CDATA[9EC81DD2693B434183FA70E8E832955C]]></AD_MESSAGE_ID>
+<!--9EC81DD2693B434183FA70E8E832955C-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--9EC81DD2693B434183FA70E8E832955C-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--9EC81DD2693B434183FA70E8E832955C-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--9EC81DD2693B434183FA70E8E832955C-->  <VALUE><![CDATA[OBMOBC_FilterQueryBuilderEquals]]></VALUE>
+<!--9EC81DD2693B434183FA70E8E832955C-->  <MSGTEXT><![CDATA[Equals]]></MSGTEXT>
+<!--9EC81DD2693B434183FA70E8E832955C-->  <MSGTYPE><![CDATA[I]]></MSGTYPE>
+<!--9EC81DD2693B434183FA70E8E832955C-->  <AD_MODULE_ID><![CDATA[08943B85ADF64E708797A753E5B6AAEE]]></AD_MODULE_ID>
+<!--9EC81DD2693B434183FA70E8E832955C-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--9EC81DD2693B434183FA70E8E832955C--></AD_MESSAGE>
+
 <!--9F887189284B4BE1BD639088F1F2ABD7--><AD_MESSAGE>
 <!--9F887189284B4BE1BD639088F1F2ABD7-->  <AD_MESSAGE_ID><![CDATA[9F887189284B4BE1BD639088F1F2ABD7]]></AD_MESSAGE_ID>
 <!--9F887189284B4BE1BD639088F1F2ABD7-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -600,6 +684,18 @@
 <!--AD438F79E4B94354AC6323E944CE2452-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--AD438F79E4B94354AC6323E944CE2452--></AD_MESSAGE>
 
+<!--B0530864634940E5B7E40FF43CA12F99--><AD_MESSAGE>
+<!--B0530864634940E5B7E40FF43CA12F99-->  <AD_MESSAGE_ID><![CDATA[B0530864634940E5B7E40FF43CA12F99]]></AD_MESSAGE_ID>
+<!--B0530864634940E5B7E40FF43CA12F99-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--B0530864634940E5B7E40FF43CA12F99-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--B0530864634940E5B7E40FF43CA12F99-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--B0530864634940E5B7E40FF43CA12F99-->  <VALUE><![CDATA[OBMOBC_FilterQueryBuilderNotContains]]></VALUE>
+<!--B0530864634940E5B7E40FF43CA12F99-->  <MSGTEXT><![CDATA[Not contains]]></MSGTEXT>
+<!--B0530864634940E5B7E40FF43CA12F99-->  <MSGTYPE><![CDATA[I]]></MSGTYPE>
+<!--B0530864634940E5B7E40FF43CA12F99-->  <AD_MODULE_ID><![CDATA[08943B85ADF64E708797A753E5B6AAEE]]></AD_MODULE_ID>
+<!--B0530864634940E5B7E40FF43CA12F99-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--B0530864634940E5B7E40FF43CA12F99--></AD_MESSAGE>
+
 <!--B543382DDA8142F09E03CC2340EF2E1C--><AD_MESSAGE>
 <!--B543382DDA8142F09E03CC2340EF2E1C-->  <AD_MESSAGE_ID><![CDATA[B543382DDA8142F09E03CC2340EF2E1C]]></AD_MESSAGE_ID>
 <!--B543382DDA8142F09E03CC2340EF2E1C-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -756,6 +852,18 @@
 <!--CDC4A54D6EBE43219A800CB88798485D-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--CDC4A54D6EBE43219A800CB88798485D--></AD_MESSAGE>
 
+<!--CF0EB9854CF34F33BD45294955A92EBF--><AD_MESSAGE>
+<!--CF0EB9854CF34F33BD45294955A92EBF-->  <AD_MESSAGE_ID><![CDATA[CF0EB9854CF34F33BD45294955A92EBF]]></AD_MESSAGE_ID>
+<!--CF0EB9854CF34F33BD45294955A92EBF-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--CF0EB9854CF34F33BD45294955A92EBF-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--CF0EB9854CF34F33BD45294955A92EBF-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--CF0EB9854CF34F33BD45294955A92EBF-->  <VALUE><![CDATA[OBMOBC_FilterQueryBuilderNotEquals]]></VALUE>
+<!--CF0EB9854CF34F33BD45294955A92EBF-->  <MSGTEXT><![CDATA[Not equals]]></MSGTEXT>
+<!--CF0EB9854CF34F33BD45294955A92EBF-->  <MSGTYPE><![CDATA[I]]></MSGTYPE>
+<!--CF0EB9854CF34F33BD45294955A92EBF-->  <AD_MODULE_ID><![CDATA[08943B85ADF64E708797A753E5B6AAEE]]></AD_MODULE_ID>
+<!--CF0EB9854CF34F33BD45294955A92EBF-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--CF0EB9854CF34F33BD45294955A92EBF--></AD_MESSAGE>
+
 <!--D05E4639FF9047308378499422EDE5AD--><AD_MESSAGE>
 <!--D05E4639FF9047308378499422EDE5AD-->  <AD_MESSAGE_ID><![CDATA[D05E4639FF9047308378499422EDE5AD]]></AD_MESSAGE_ID>
 <!--D05E4639FF9047308378499422EDE5AD-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -780,6 +888,18 @@
 <!--D39F57009CF5428888584DB84382EE84-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--D39F57009CF5428888584DB84382EE84--></AD_MESSAGE>
 
+<!--D53AD9FEC79E444D925DB1AA9983BD0C--><AD_MESSAGE>
+<!--D53AD9FEC79E444D925DB1AA9983BD0C-->  <AD_MESSAGE_ID><![CDATA[D53AD9FEC79E444D925DB1AA9983BD0C]]></AD_MESSAGE_ID>
+<!--D53AD9FEC79E444D925DB1AA9983BD0C-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--D53AD9FEC79E444D925DB1AA9983BD0C-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--D53AD9FEC79E444D925DB1AA9983BD0C-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--D53AD9FEC79E444D925DB1AA9983BD0C-->  <VALUE><![CDATA[OBMOBC_FilterQueryBuilderContains]]></VALUE>
+<!--D53AD9FEC79E444D925DB1AA9983BD0C-->  <MSGTEXT><![CDATA[Contains]]></MSGTEXT>
+<!--D53AD9FEC79E444D925DB1AA9983BD0C-->  <MSGTYPE><![CDATA[I]]></MSGTYPE>
+<!--D53AD9FEC79E444D925DB1AA9983BD0C-->  <AD_MODULE_ID><![CDATA[08943B85ADF64E708797A753E5B6AAEE]]></AD_MODULE_ID>
+<!--D53AD9FEC79E444D925DB1AA9983BD0C-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--D53AD9FEC79E444D925DB1AA9983BD0C--></AD_MESSAGE>
+
 <!--D5601AF50A844F23A48582665F10FF99--><AD_MESSAGE>
 <!--D5601AF50A844F23A48582665F10FF99-->  <AD_MESSAGE_ID><![CDATA[D5601AF50A844F23A48582665F10FF99]]></AD_MESSAGE_ID>
 <!--D5601AF50A844F23A48582665F10FF99-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
diff --git a/src/org/openbravo/mobile/core/MobileCoreComponentProvider.java b/src/org/openbravo/mobile/core/MobileCoreComponentProvider.java
--- a/src/org/openbravo/mobile/core/MobileCoreComponentProvider.java
+++ b/src/org/openbravo/mobile/core/MobileCoreComponentProvider.java
@@ -112,6 +112,7 @@
 
     final ArrayList<String> jsRetailDependency = new ArrayList<String>();
     jsRetailDependency.add("component/ob-retail-product-browser");
+    jsRetailDependency.add("component/ob-retail-filterbuilder");
     jsRetailDependency.add("component/ob-retail-searchproducts");
     jsRetailDependency.add("component/ob-retail-searchproductcharacteristic");
 
diff --git a/web/org.openbravo.mobile.core/assets/css/ob-standard.css b/web/org.openbravo.mobile.core/assets/css/ob-standard.css
--- a/web/org.openbravo.mobile.core/assets/css/ob-standard.css
+++ b/web/org.openbravo.mobile.core/assets/css/ob-standard.css
@@ -750,6 +750,9 @@
 .btn-icon-search {
   background-image: url('./../img/iconSearch.png');
 }
+.btn-icon-add {
+  background-image: url('./../img/iconAdd.png');
+}
 .btn-icon-clear {
   background-image: url('./../img/iconClear.png');
 }
diff --git a/web/org.openbravo.mobile.core/assets/img/iconAdd.png b/web/org.openbravo.mobile.core/assets/img/iconAdd.png
new file mode 100644
index 0000000000000000000000000000000000000000..7ccd97d6978b43658929e6d3e8d19a5824f73eb7
GIT binary patch
literal 1691
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

diff --git a/web/org.openbravo.mobile.core/source/retail/component/ob-retail-filterbuilder.js b/web/org.openbravo.mobile.core/source/retail/component/ob-retail-filterbuilder.js
new file mode 100644
--- /dev/null
+++ b/web/org.openbravo.mobile.core/source/retail/component/ob-retail-filterbuilder.js
@@ -0,0 +1,289 @@
+/*
+ *************************************************************************
+ * 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) 2012-2014 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+
+/*global enyo, _, Backbone */
+
+// Create a new client model for FilterBuilderOption
+var FilterBuilderOption = Backbone.Model.extend({
+  defaults: {
+    id: '',
+    name: ''
+  }
+});
+
+var FilterBuilderOptionList = Backbone.Collection.extend({
+  model: FilterBuilderOption
+});
+
+//Create a new client model for FilterBuilderOption
+var FilterBuilderRow = Backbone.Model.extend({
+  defaults: {
+    id: '',
+    selected: true,
+    fieldType: ''
+  }
+});
+
+var FilterBuilderRowList = Backbone.Collection.extend({
+  model: FilterBuilderRow
+});
+
+
+/*
+ * Dialog Header
+ */
+enyo.kind({
+  name: 'OB.UI.ModalSearchFilterBuilderTopHeader',
+  kind: 'OB.UI.ScrollableTableHeader',
+  events: {
+    onHideThisPopup: '',
+    onSelectFilter: '',
+    onSearchAction: ''
+  },
+  components: [{
+    style: 'display: table;',
+    components: [{
+      style: 'display: table-cell; width: 100%;',
+      components: [{
+        name: 'title',
+        style: 'text-align: center; vertical-align: middle'
+      }]
+    }, {
+      style: 'display: table-cell;',
+      components: [{
+        name: 'doneBrandButton',
+        kind: 'OB.UI.SmallButton',
+        ontap: 'doneAction'
+      }]
+    }, {
+      style: 'display: table-cell;',
+      components: [{
+        classes: 'btnlink-gray',
+        name: 'cancelBrandButton',
+        kind: 'OB.UI.SmallButton',
+        ontap: 'cancelAction'
+      }]
+    }]
+  }],
+  initComponents: function () {
+    this.inherited(arguments);
+    this.$.doneBrandButton.setContent(OB.I18N.getLabel('OBMOBC_LblDone'));
+    this.$.cancelBrandButton.setContent(OB.I18N.getLabel('OBMOBC_LblCancel'));
+  },
+  doneAction: function () {
+    var filter = this.parent.parent.parent.filter,
+        renderInfo = filter.renderInfo(),
+        filters = [],
+        hasError = false;
+    if (renderInfo) {
+      filters = renderInfo.getFilterCondition();
+    } else {
+      var conditions = this.parent.parent.parent.$.body.$.standardBuilderConditions.$.tbody.controls;
+      // Check filters conditions
+      conditions.forEach(function (item) {
+        var row = item.$.modalSearchFilterBuilderRow.$;
+        if (row.filterCheckBox.checked) {
+          var value = row.filterValue.getValue(),
+              sqlBuilder = filter.sqlBuilder();
+          if (sqlBuilder.fieldType.toUpperCase() === "STRING" && !value && !value.trim()) {
+            OB.UTIL.showAlert.display(OB.I18N.getLabel('OBMOBC_FilterQueryBuilderErrEmptyValue'), "Error", "alert-error", false);
+            hasError = true;
+          }
+          if (sqlBuilder.fieldType.toUpperCase() === "NUMBER") {
+            var error = true;
+            if (value.match(/^\d*\.{0,1}\d*$/) !== null || value.match(/^\d*\,{0,1}\d*$/) !== null) {
+              value = value.replace(',', '.');
+              error = false;
+            }
+            if (error || isNaN(parseFloat(value))) {
+              OB.UTIL.showAlert.display(OB.I18N.getLabel('OBMOBC_FilterQueryBuilderErrInvalidNumber'), "Error", "alert-error", false);
+              hasError = true;
+            }
+          }
+          filters.push({
+            condition: row.filterCondition.getValue(),
+            value: sqlBuilder.fieldType.toUpperCase() === "NUMBER" ? parseFloat(value) : value
+          });
+        }
+      });
+    }
+    if (!hasError) {
+      filter.conditions = filters;
+      this.doSelectFilter({
+        filter: filter
+      });
+      this.doHideThisPopup();
+    }
+  },
+  cancelAction: function () {
+    this.doHideThisPopup();
+  }
+});
+
+/**
+ * Filter condition
+ */
+enyo.kind({
+  name: 'OB.UI.ModalSearchFilterBuilderRow',
+  style: 'display: table;  width: 100%;',
+  components: [{
+    name: 'filterCheckBox',
+    kind: 'OB.UI.CheckboxButton',
+    tag: 'div',
+    style: 'display: table-cell; width: 50px;'
+  }, {
+    style: 'display: table-cell; width: 180px; padding-top: 5px;',
+    components: [{
+      kind: 'OB.UI.List',
+      name: 'filterCondition',
+      classes: 'combo',
+      style: 'width: 90%',
+      renderEmpty: 'enyo.Control',
+      renderLine: enyo.kind({
+        kind: 'enyo.Option',
+        initComponents: function () {
+          this.inherited(arguments);
+          this.setValue(this.model.get('id'));
+          this.setContent(this.model.get('name'));
+        }
+      })
+    }]
+  }, {
+    style: 'display: table-cell; width: 120px;',
+    kind: 'OB.UI.SearchInput',
+    name: 'filterValue'
+  }],
+  initComponents: function () {
+    this.inherited(arguments);
+    var cond = this.model.get("condition"),
+        items = new FilterBuilderOptionList();
+    this.$.filterCondition.setCollection(items);
+    items.add(new FilterBuilderOption({
+      id: 'MORE_THAN',
+      name: OB.I18N.getLabel('OBMOBC_FilterQueryBuilderMoreThan')
+    }));
+    items.add(new FilterBuilderOption({
+      id: 'LESS_THAN',
+      name: OB.I18N.getLabel('OBMOBC_FilterQueryBuilderLessThan')
+    }));
+    items.add(new FilterBuilderOption({
+      id: 'EQUALS',
+      name: OB.I18N.getLabel('OBMOBC_FilterQueryBuilderEquals')
+    }));
+    items.add(new FilterBuilderOption({
+      id: 'NOT_EQUALS',
+      name: OB.I18N.getLabel('OBMOBC_FilterQueryBuilderNotEquals')
+    }));
+    if (this.model.get("fieldType").toUpperCase() === "STRING") {
+      items.add(new FilterBuilderOption({
+        id: 'CONTAINS',
+        name: OB.I18N.getLabel('OBMOBC_FilterQueryBuilderContains')
+      }));
+      items.add(new FilterBuilderOption({
+        id: 'NOT_CONTAINS',
+        name: OB.I18N.getLabel('OBMOBC_FilterQueryBuilderNotContains')
+      }));
+    }
+    this.$.filterCheckBox.check();
+    this.$.filterCondition.setSelected(cond === 'MORE_THAN' ? 0 : cond === 'LESS_THAN' ? 1 : cond === 'EQUALS' ? 2 : cond === 'NOT_EQUALS' ? 3 : cond === 'CONTAINS' ? 4 : 5);
+    this.$.filterValue.setValue(this.model.get("value"));
+  }
+});
+
+/*
+ * Modal definition
+ */
+enyo.kind({
+  name: 'OB.UI.ModalSearchFilterBuilder',
+  topPosition: '170px',
+  kind: 'OB.UI.Modal',
+  published: {
+    characteristic: null
+  },
+  executeOnShow: function (args) {
+    this.filter = this.args.filter;
+    var me = this,
+        renderInfo = this.filter.renderInfo();
+    this.sqlBuilder = this.filter.sqlBuilder();
+    this.$.header.parent.addStyles('padding: 0px; border-bottom: 1px solid #cccccc');
+    this.$.header.$.modalSearchFilterBuilderTopHeader.$.title.setContent(this.filter.getCaption());
+    if (renderInfo) {
+      this.$.body.$.standardBuilder.hide();
+      this.$.body.$.customBuilder.show();
+      this.$.body.$.customBuilder.createComponent(renderInfo);
+    } else {
+      this.filterRows = new FilterBuilderRowList();
+      if (this.filter.conditions && _.isArray(this.filter.conditions) && this.filter.conditions.length > 0) {
+        this.filter.conditions.forEach(function (cond) {
+          me.addFilterRow(cond.condition, cond.value);
+        });
+      } else if (this.filter.defaults && _.isArray(this.filter.defaults) && this.filter.defaults.length > 0) {
+        this.filter.defaults.forEach(function (cond) {
+          me.addFilterRow(cond.condition, cond.value);
+        });
+      } else {
+        this.addFilterRow('MORE_THAN', '');
+      }
+      this.$.body.$.customBuilder.hide();
+      this.$.body.$.standardBuilder.show();
+      this.$.body.$.standardBuilderConditions.setCollection(this.filterRows);
+    }
+  },
+  addFilterRow: function (condition, value) {
+    this.filterRows.add(new FilterBuilderRow({
+      id: OB.Dal.get_uuid(),
+      selected: true,
+      fieldType: this.sqlBuilder.fieldType,
+      condition: condition,
+      value: value
+    }));
+  },
+  i18nHeader: '',
+  body: {
+    components: [{
+      name: 'standardBuilder',
+      components: [{
+        kind: 'OB.UI.ScrollableTable',
+        name: 'standardBuilderConditions',
+        scrollAreaMaxHeight: '300px',
+        renderEmpty: 'OB.UI.RenderEmptyCh',
+        renderLine: 'OB.UI.ModalSearchFilterBuilderRow'
+      }, {
+        kind: 'Image',
+        src: '../org.openbravo.mobile.core/assets/img/iconAdd.png',
+        sizing: "cover",
+        width: 42,
+        height: 42,
+        tap: function () {
+          this.owner.owner.addFilterRow('MORE_THAN', '');
+        }
+      }]
+    }, {
+      name: 'customBuilder'
+    }]
+  },
+  initComponents: function () {
+    this.inherited(arguments);
+    this.$.closebutton.hide();
+    this.$.header.createComponent({
+      kind: 'OB.UI.ModalSearchFilterBuilderTopHeader',
+      style: 'border-bottom: 0px'
+    });
+  }
+});
\ No newline at end of file
diff --git a/web/org.openbravo.mobile.core/source/retail/component/ob-retail-searchproductcharacteristic.js b/web/org.openbravo.mobile.core/source/retail/component/ob-retail-searchproductcharacteristic.js
--- a/web/org.openbravo.mobile.core/source/retail/component/ob-retail-searchproductcharacteristic.js
+++ b/web/org.openbravo.mobile.core/source/retail/component/ob-retail-searchproductcharacteristic.js
@@ -1,10 +1,20 @@
 /*
- ************************************************************************************
- * Copyright (C) 2012-2013 Openbravo S.L.U.
- * Licensed under the Openbravo Commercial License version 1.0
- * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html
- * or in the legal folder of this module distribution.
- ************************************************************************************
+ *************************************************************************
+ * 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) 2012-2014 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
  */
 
 /*global enyo, _ */
@@ -31,6 +41,149 @@
 });
 
 enyo.kind({
+  name: 'OB.UI.SearchProductCharacteristicFilterPanel',
+  style: 'display: table; margin-bottom: 3px; margin-right: 3px; border:2px solid #ccc; background-color: yellow',
+  events: {
+    onRemoveCustomFilter: ''
+  },
+  components: [{
+    name: 'infoPanel',
+    style: 'display: table-cell; width: 100%; padding-left: 0.5em; '
+  }, {
+    classes: 'btnlink-gray btn-icon-small btn-icon-clear',
+    style: 'display: table-cell; width: 30px; float: right;',
+    ontap: 'removeCustomFilter'
+  }],
+  removeCustomFilter: function () {
+    this.doRemoveCustomFilter({
+      index: this.index
+    });
+  },
+  initComponents: function () {
+    this.inherited(arguments);
+    if (this.customContent === null) {
+      this.$.infoPanel.setContent(this.caption + " » " + this.text);
+    } else {
+      this.$.infoPanel.createComponent(this.customContent);
+    }
+  }
+});
+
+enyo.kind({
+  name: 'OB.UI.SearchProductCharacteristicFilter',
+  published: {
+    type: 'PANEL',
+    caption: '',
+    text: null
+  },
+  events: {
+    onAddProduct: ''
+  },
+  conditions: null,
+
+  // List of default filters
+  defaults: [],
+
+  // Get component to filter render 
+  renderInfo: function () {
+    return null;
+    // Example: 
+    // return {
+    //   kind: 'FilterExample',
+    //     getFilterCondition: function () {
+    //       return [{
+    //         condition: 'EQUALS',
+    //         value: 2
+    //       }];
+    //   }
+    // };
+  },
+
+  // Get SQL filter
+  sqlFilter: function () {
+    if (this.type === 'BUTTON' && this.conditions && _.isArray(this.conditions) && this.conditions.length > 0) {
+      // Standard behavior for filter with type BUTTON
+      var where = "",
+          filters = [],
+          sqlBuilderInfo = this.sqlBuilder();
+      this.conditions.forEach(function (cond) {
+        var condValue = cond.value;
+        if (where !== "") {
+          where = where + " and ";
+        }
+        where = where + sqlBuilderInfo.field;
+        if (cond.condition === 'MORE_THAN') {
+          where = where + " > ?";
+        }
+        if (cond.condition === 'LESS_THAN') {
+          where = where + " < ?";
+        }
+        if (cond.condition === 'EQUALS') {
+          where = where + " = ?";
+        }
+        if (cond.condition === 'NOT_EQUALS') {
+          where = where + " <> ?";
+        }
+        if (cond.condition === 'CONTAINS') {
+          where = where + " like ?";
+          condValue = "%" + cond.value + "%";
+        }
+        if (cond.condition === 'NOT_CONTAINS') {
+          where = where + " not like ?";
+          condValue = "%" + cond.value + "%";
+        }
+        filters.push(condValue);
+      });
+      return {
+        where: " and (" + where + ")",
+        filters: filters
+      };
+    } else {
+      // Default behavior
+      return {
+        where: null,
+        filters: []
+      };
+    }
+  },
+
+  // Get SQL Build logic
+  sqlBuilder: function () {
+    return {
+      field: '',
+      fieldType: '' // Number, String, Date
+    };
+  },
+
+  // Get extra attributes for order line
+  lineAttributes: function () {
+    return null;
+  },
+
+  // Function to post process filtered collection 
+  //
+  // function (collection, callback);
+  //	collection: Collection of filtered items
+  //    callback: Callback function to be called when post processing finish
+  postProcess: null,
+
+  // Add attributes to show 
+  addItemAttributes: function (item, attr) {
+    var filterAttr = item.get("filterAttr");
+    if (!filterAttr) {
+      item.set("filterAttr", []);
+      filterAttr = item.get("filterAttr");
+    }
+    filterAttr.push({
+      value: attr,
+      separator: this.attributesSeparator
+    });
+  },
+
+  attributesSeparator: ', '
+});
+
+enyo.kind({
   name: 'OB.UI.SearchProductCharacteristicHeader',
   kind: 'OB.UI.ScrollableTableHeader',
   events: {
@@ -43,6 +196,9 @@
   components: [{
     style: 'padding: 10px 10px 5px 10px;',
     components: [{
+      style: 'margin: 5px 0px 0px 0px; width: 100%',
+      name: 'filterpanel'
+    }, {
       style: 'display: table;  width: 100%;',
       components: [{
         style: 'display: table-cell; width: 100%;',
@@ -115,6 +271,11 @@
     this.$.productcategory.setSelected(0);
     this.$.filteringBy.setContent('');
     this.parent.$.brandButton.removeClass('btnlink-yellow-bold');
+    var buttons = this.parent.$.filterButtons.getComponents();
+    buttons.forEach(function (btn) {
+      btn.removeClass('btnlink-yellow-bold');
+    });
+    this.parent.filterCustomClearConditions();
     this.parent.model.set('filter', []);
     this.parent.model.set('brandFilter', []);
     this.parent.genericParent = null;
@@ -170,7 +331,9 @@
     onSearchAction: 'searchAction',
     onClearAction: 'clearAction',
     onUpdateFilter: 'filterUpdate',
-    onUpdateBrandFilter: 'brandFilterUpdate'
+    onUpdateBrandFilter: 'brandFilterUpdate',
+    onRemoveCustomFilter: 'removeCustomFilter',
+    onCustomFilterUpdate: 'customFilterUpdate'
   },
   events: {
     onAddProduct: '',
@@ -178,6 +341,122 @@
     onClearAction: '',
     onTabChange: ''
   },
+  // List of custom filters ('OB.UI.SearchProductCharacteristicFilter')
+  customFilters: [],
+  postProcessCustomFilters: [],
+  // Clear custom filters
+  filtersCustomClear: function () {
+    var i = 0;
+    while (i < this.customFilters.length) {
+      if (this.customFilters[i].type === 'PANEL') {
+        this.customFilters.splice(i, 1);
+      } else if (this.customFilters[i].type === 'BUTTON') {
+        this.customFilters[i].conditions = null;
+        this.filtersCustomCopyDefaults(this.customFilters[i]);
+        i++;
+      }
+    }
+    this.filtersCustomBuildPostProcess();
+  },
+  // Clear filter conditions
+  filterCustomClearConditions: function () {
+    this.customFilters.forEach(function (filter) {
+      if (filter.type === 'BUTTON') {
+        filter.conditions = [];
+      }
+    });
+  },
+  // Copy default filters conditions
+  filtersCustomCopyDefaults: function (filter) {
+    if (filter.defaults && _.isArray(filter.defaults) && filter.defaults.length > 0) {
+      filter.conditions = [];
+      filter.defaults.forEach(function (item) {
+        filter.conditions.push(item);
+      });
+    }
+  },
+  // Build post process filters
+  filtersCustomBuildPostProcess: function () {
+    var me = this;
+    this.postProcessCustomFilters = [];
+    this.customFilters.forEach(function (filter) {
+      if (filter.postProcess && typeof (filter.postProcess) === "function") {
+        me.postProcessCustomFilters.push(filter);
+      }
+    });
+  },
+  // Add a new custom filter
+  filtersCustomAdd: function (filter) {
+    this.customFilters.push(filter);
+    if (filter.postProcess && typeof (filter.postProcess) === "function") {
+      this.postProcessCustomFilters.push(filter);
+    }
+  },
+  // Render custom filters 
+  filtersCustomRender: function () {
+    var index = 0,
+        me = this,
+        filtersPanels = this.$.searchProductCharacteristicHeader.$.filterpanel.getComponents(),
+        filtersButtons = this.$.filterButtons.getComponents();
+    // Remove visual components
+    filtersPanels.forEach(function (item) {
+      item.destroy();
+    });
+    filtersButtons.forEach(function (item) {
+      item.destroy();
+    });
+    // Insert visual component of filter
+    this.customFilters.forEach(function (filter) {
+      filter.index = index;
+      if (filter.type === 'PANEL') {
+        me.$.searchProductCharacteristicHeader.$.filterpanel.createComponent({
+          kind: 'OB.UI.SearchProductCharacteristicFilterPanel',
+          text: filter.getText(),
+          caption: filter.getCaption(),
+          index: index++,
+          customContent: filter.renderInfo()
+        });
+      }
+      if (filter.type === 'BUTTON') {
+        me.$.filterButtons.createComponent({
+          kind: 'OB.UI.SmallButton',
+          style: 'width: 86%; padding: 0px;',
+          classes: 'btnlink-white-simple',
+          content: filter.getText(),
+          index: index++,
+          customContent: filter.renderInfo(),
+          filter: filter,
+          events: {
+            onShowPopup: ''
+          },
+          tap: function () {
+            this.bubble('onShowPopup', {
+              popup: 'modalsearchfilterbuilder',
+              args: {
+                filter: this.filter
+              }
+            });
+          }
+        });
+      }
+    });
+    this.$.searchProductCharacteristicHeader.$.filterpanel.render();
+    this.$.filterButtons.render();
+  },
+  // Process remove filter event
+  removeCustomFilter: function (inSender, inEvent) {
+    this.customFilters.splice(inEvent.index, 1);
+    this.filtersCustomBuildPostProcess();
+    this.filtersCustomRender();
+    this.doSearchAction({
+      productCat: this.$.searchProductCharacteristicHeader.$.productcategory.getValue(),
+      productName: this.$.searchProductCharacteristicHeader.$.productname.getValue(),
+      filter: this.model.get('filter'),
+      skipProduct: false,
+      skipProductCharacteristic: false
+    });
+  },
+
   filterUpdate: function (inSender, inEvent) {
     var i, j, valuesIds, index, chValue = inEvent.value.value;
     valuesIds = this.model.get('filter').map(function (e) {
@@ -257,6 +536,28 @@
     });
     return true;
   },
+  customFilterUpdate: function (inSender, inEvent) {
+    if (inEvent.filter && inEvent.filter.index !== undefined) {
+      var buttons = this.$.filterButtons.getComponents();
+      buttons.forEach(function (btn) {
+        if (btn.index === inEvent.filter.index) {
+          if (inEvent.filter.conditions && _.isArray(inEvent.filter.conditions) && inEvent.filter.conditions.length > 0) {
+            btn.addClass('btnlink-yellow-bold');
+          } else {
+            btn.removeClass('btnlink-yellow-bold');
+          }
+        }
+      });
+    }
+    this.doSearchAction({
+      productCat: this.$.searchProductCharacteristicHeader.$.productcategory.getValue(),
+      productName: this.$.searchProductCharacteristicHeader.$.productname.getValue(),
+      filter: this.model.get('filter'),
+      skipProduct: false,
+      skipProductCharacteristic: false
+    });
+    return true;
+  },
   filteringBy: function () {
     var filteringBy = OB.I18N.getLabel('OBMOBC_FilteringBy'),
         selectedItems, i;
@@ -290,6 +591,7 @@
     this.$.searchProductCharacteristicHeader.$.filteringBy.setContent(filteringBy);
   },
   executeOnShow: function (model) {
+    this.filtersCustomRender();
     var me = this,
         criteria = {};
     this.doClearAction();
@@ -298,7 +600,8 @@
       productCat: this.$.searchProductCharacteristicHeader.$.productcategory.getValue(),
       productName: this.$.searchProductCharacteristicHeader.$.productname.getValue(),
       filter: this.model.get('filter'),
-      skipProduct: !this.genericParent,
+      skipProduct: true,
+      //!this.genericParent,
       skipProductCharacteristic: false
     });
     this.filteringBy();
@@ -320,6 +623,9 @@
           kind: 'OB.UI.BrandButton',
           name: 'brandButton'
         }, {
+                name: 'filterButtons',
+                classes: 'row-fluid'
+              }, {
           kind: 'OB.UI.ScrollableTable',
           name: 'productsCh',
           scrollAreaMaxHeight: '415px',
@@ -378,8 +684,26 @@
 
     this.products.on('click', function (model) {
       if (!model.get('isGeneric')) {
+        // Include filters line attributes
+        var attrs = {};
+        this.customFilters.forEach(function (filter) {
+          var filterAttr = filter.lineAttributes();
+          if (filterAttr) {
+            _.each(_.keys(filterAttr), function (key) {
+              attrs[key] = filterAttr[key];
+            });
+          }
+        });
+        // Add product to order
         me.doAddProduct({
-          product: model
+          product: model,
+          attrs: _.keys(attrs).length === 0 ? undefined : attrs
+        });
+        // Notify to filters 
+        this.customFilters.forEach(function (filter) {
+          filter.doAddProduct({
+            product: model
+          });
         });
       } else {
         me.doTabChange({
@@ -432,7 +756,7 @@
 
     // Initializing combo of categories without filtering
 
-    function successCallbackProducts(dataProducts) {
+    function showProducts(dataProducts) {
       if (dataProducts && dataProducts.length > 0) {
         me.products.reset(dataProducts.models);
         me.products.trigger('reset');
@@ -442,6 +766,20 @@
       }
     }
 
+    function postProccessFilters(index, dataProducts) {
+      if (index < me.postProcessCustomFilters.length) {
+        me.postProcessCustomFilters[index].postProcess(dataProducts, function () {
+          postProccessFilters(++index, dataProducts);
+        });
+      } else {
+        showProducts(dataProducts);
+      }
+    }
+
+    function successCallbackProducts(dataProducts) {
+      postProccessFilters(0, dataProducts);
+    }
+
     function successCallbackProductCh(dataProductCh, me) {
       if (dataProductCh && dataProductCh.length > 0) {
         for (i = 0; i < dataProductCh.length; i++) {
@@ -491,7 +829,24 @@
       filterWhereClause = filterWhereClause + ' and product.brand in (' + brandString + ')';
     }
     if (!inEvent.skipProduct) {
-      OB.Dal.query(OB.Model.Product, 'select * from m_product as product' + this.whereClause + filterWhereClause, this.params, successCallbackProducts, errorCallback, this);
+      // Add custom parameters
+      var customParams = [];
+      this.params.forEach(function (param) {
+        customParams.push(param);
+      });
+      // Add custom filters
+      this.customFilters.forEach(function (filter) {
+        var sqlFilter = filter.sqlFilter();
+        if (sqlFilter && sqlFilter.where) {
+          filterWhereClause = filterWhereClause + sqlFilter.where;
+          if (sqlFilter.filters && sqlFilter.filters.length > 0) {
+            sqlFilter.filters.forEach(function (item) {
+              customParams.push(item);
+            });
+          }
+        }
+      });
+      OB.Dal.query(OB.Model.Product, 'select * from m_product as product' + this.whereClause + filterWhereClause, customParams, successCallbackProducts, errorCallback, this);
     }
     if (!inEvent.skipProductCharacteristic) {
       if (this.model.get('filter').length > 0) {
