diff --git a/web/org.openbravo.mobile.core/source/data/ob-dal.js b/web/org.openbravo.mobile.core/source/data/ob-dal.js
--- a/web/org.openbravo.mobile.core/source/data/ob-dal.js
+++ b/web/org.openbravo.mobile.core/source/data/ob-dal.js
@@ -16,6 +16,8 @@
   OB.Dal.REMOTE_DATALIMIT = 100;
   OB.Dal.EQ = '=';
   OB.Dal.NEQ = '!=';
+  OB.Dal.ISNULL = 'isNull';
+  OB.Dal.ISNOTNULL = 'isNotNull';
   OB.Dal.CONTAINS = 'contains';
   OB.Dal.USESCONTAINS = '_usesContains';
   OB.Dal.STARTSWITH = 'startsWith';
@@ -228,10 +230,11 @@
 
           sql = sql + (firstParam ? '' : orAnd) + ' ' + colName + ' ';
 
-          if (value === null) {
+          if (value === null || operator === OB.Dal.ISNULL) {
             sql = sql + ' IS null ';
+          } else if (operator === OB.Dal.ISNOTNULL) {
+            sql = sql + ' IS NOT null ';
           } else {
-
             if (operator === OB.Dal.EQ) {
               sql = sql + ' = ? ';
             } else if (operator === OB.Dal.NEQ) {
diff --git a/web/org.openbravo.mobile.core/source/retail/component/ob-retail-product-browser.js b/web/org.openbravo.mobile.core/source/retail/component/ob-retail-product-browser.js
--- a/web/org.openbravo.mobile.core/source/retail/component/ob-retail-product-browser.js
+++ b/web/org.openbravo.mobile.core/source/retail/component/ob-retail-product-browser.js
@@ -600,7 +600,8 @@
     if (OB.MobileApp.model.hasPermission('OBPOS_remote.product', true)) {
       return;
     }
-    var criteria, me = this;
+    var criteria = {},
+        me = this;
 
     function errorCallback(tx, error) {
       OB.UTIL.showError("OBDAL error: " + error);
@@ -625,40 +626,67 @@
 
     if (category) {
       this.currentCategory = category;
-      var where = "where ";
-      if (category.get('id') === 'OBPOS_bestsellercategory') {
-        criteria = {
-          'bestseller': 'true'
-        };
-        where += "p.bestseller = ?";
+      var isBestSellerCategory = category.get('id') === 'OBPOS_bestsellercategory';
+      var queryToBeExecuted = "",
+          selectProperties = "",
+          fromEntities = "",
+          whereClause = "",
+          orderByClause = "",
+          paramsQuery = [],
+          limit = null;
+
+      // Check if OBPOS_productLimit is defined to use it as limit for queries
+      if (OB.MobileApp.model.hasPermission('OBPOS_productLimit', true)) {
+        limit = OB.DEC.abs(OB.MobileApp.model.hasPermission('OBPOS_productLimit', true));
+      }
+
+      if (OB.MobileApp.model.hasPermission('EnableMultiPriceList', true) && this.currentPriceList && this.currentPriceList !== OB.MobileApp.model.get('terminal').priceList) {
+        // Multipricelist scenario with current pricelist different from default erminal pricelist
+        selectProperties = "p.*, pp.pricestd as currentStandardPrice ";
+        fromEntities = "m_product p inner join m_productprice pp on p.m_product_id = pp.m_product_id and pp.m_pricelist_id = ? ";
+        if (isBestSellerCategory) {
+          // Multipricelist with bestsellers
+          whereClause = "p.bestseller = ? ";
+        } else {
+          // Multipricelist with other categories
+          whereClause = "p.m_product_category_id = ?  ";
+        }
+        whereClause += "and (pp.pricestd is not null or p.listPrice is not null or p.ispack = 'true') ";
+        orderByClause = "upper(p._identifier) asc ";
+        paramsQuery = [this.currentPriceList, isBestSellerCategory ? 'true' : category.get('id')];
+      } else if (isBestSellerCategory) {
+        // Best seller category scenario
         if (this.useCharacteristics) {
-          criteria.generic_product_id = null;
+          selectProperties = "p.* ";
+          fromEntities = "m_product p ";
+          whereClause = "(p.bestseller = 'true' and p.generic_product_id is null and p.listPrice is not null) or (p.isGeneric = 'true' and exists (select 1 from m_product gp where gp.bestseller = 'true' and gp.generic_product_id = p.m_product_id) and p.listPrice is not null) ";
+          orderByClause = "upper(p._identifier) asc ";
+          paramsQuery = [];
+        } else {
+          selectProperties = "p.* ";
+          fromEntities = "m_product p ";
+          whereClause = "p.bestseller = 'true' and p.listPrice is not null ";
+          orderByClause = "upper(p._identifier) asc ";
+          paramsQuery = [];
         }
       } else {
-        criteria = {
-          'productCategory': category.get('id')
-        };
-        where += "p.m_product_category_id = ?";
+        // Other scenarios
+        selectProperties = "p.* ";
+        fromEntities = "m_product p ";
+        whereClause = "p.m_product_category_id = ? and (p.listPrice is not null or p.ispack = 'true') ";
         if (this.useCharacteristics) {
-          criteria.generic_product_id = null;
+          whereClause += "and p.generic_product_id is null ";
         }
+        orderByClause = "upper(p._identifier) asc ";
+        paramsQuery = [category.get('id')];
       }
-      criteria._orderByClause = 'upper(_identifier) asc';
-      if (OB.MobileApp.model.hasPermission('OBPOS_productLimit', true)) {
-        criteria._limit = OB.DEC.abs(OB.MobileApp.model.hasPermission('OBPOS_productLimit', true));
-      }
-      if (OB.MobileApp.model.hasPermission('EnableMultiPriceList', true) && this.currentPriceList && this.currentPriceList !== OB.MobileApp.model.get('terminal').priceList) {
-        var select = "select p.*, pp.pricestd as currentStandardPrice " //
-        + "from m_product p inner join m_productprice pp on p.m_product_id = pp.m_product_id and pp.m_pricelist_id = ? " //
-        + where;
-        var limit = null;
-        if (OB.MobileApp.model.hasPermission('OBPOS_productLimit', true)) {
-          limit = OB.DEC.abs(OB.MobileApp.model.hasPermission('OBPOS_productLimit', true));
-        }
-        OB.Dal.query(OB.Model.Product, select, [this.currentPriceList, category.get('id') === 'OBPOS_bestsellercategory' ? 'true' : category.get('id')], successCallbackProducts, errorCallback, null, null, limit);
-      } else {
-        OB.Dal.find(OB.Model.Product, criteria, successCallbackProducts, errorCallback);
-      }
+
+      // Create final query and execute it
+      queryToBeExecuted = "select " + selectProperties //
+      + "from " + fromEntities //
+      + "where " + whereClause //
+      + "order by " + orderByClause;
+      OB.Dal.query(OB.Model.Product, queryToBeExecuted, paramsQuery, successCallbackProducts, errorCallback, null, null, limit);
     } else {
       this.products.reset();
       this.$.productTable.getHeader().setHeader(OB.I18N.getLabel('OBMOBC_LblNoCategory'));
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
@@ -1722,12 +1722,14 @@
           if (OB.MobileApp.model.hasPermission('EnableMultiPriceList', true) && me.currentPriceList && me.currentPriceList !== OB.MobileApp.model.get('terminal').priceList) {
             var select = "select product. * , pp.pricestd as currentStandardPrice " //
             + " from m_product product join m_productprice pp on product.m_product_id = pp.m_product_id and pp.m_pricelist_id = '" + me.currentPriceList + "'" //
-            + me.whereClause + filterWhereClause;
+            + me.whereClause //
+            + " and (pp.pricestd is not null or product.listPrice is not null or product.ispack = 'true') " //
+            + filterWhereClause;
             OB.Dal.query(OB.Model.Product, select, customParams, function (dataProducts) {
               successCallbackProducts(dataProducts, false);
             }, errorCallbackProducts, me, null, limit);
           } else {
-            OB.Dal.query(OB.Model.Product, 'select * from m_product as product' + me.whereClause + filterWhereClause, customParams, function (dataProducts) {
+            OB.Dal.query(OB.Model.Product, 'select * from m_product as product' + me.whereClause + " and (product.listPrice is not null or product.ispack = 'true') " + filterWhereClause, customParams, function (dataProducts) {
               successCallbackProducts(dataProducts, false);
             }, errorCallbackProducts, me, null, limit);
           }
