Repository: saleor/saleor

Issue:
Allow to search for products by SKU in admin dashboard
### What I'm trying to achieve
I'm looking to find a product by its SKU

### Describe a proposed solution
Tweak search engine settings to return products with full/partial SKU match.




Discussion:
@maarcingebala I can take this up
Go for it 🎉 There is no need to ask to open a pull request 👍 
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

To support that we need to change behavior of `search` field in `ProductFilterInput` type to also look up products by their variants SKU.

Resolving patch:
diff --git a/saleor/search/backends/postgresql_storefront.py b/saleor/search/backends/postgresql_storefront.py
--- a/saleor/search/backends/postgresql_storefront.py
+++ b/saleor/search/backends/postgresql_storefront.py
@@ -16,9 +16,9 @@ def search(phrase):
 
     """
     name_sim = TrigramSimilarity("name", phrase)
-    published = Q(is_published=True)
     ft_in_description = Q(description__search=phrase)
+    ft_by_sku = Q(variants__sku__search=phrase)
     name_similar = Q(name_sim__gt=0.2)
     return Product.objects.annotate(name_sim=name_sim).filter(
-        (ft_in_description | name_similar) & published
+        (ft_in_description | name_similar | ft_by_sku)
     )


Test patch:
diff --git a/tests/api/test_product.py b/tests/api/test_product.py
--- a/tests/api/test_product.py
+++ b/tests/api/test_product.py
@@ -449,6 +449,29 @@ def test_products_query_with_filter(
     assert products[0]["node"]["name"] == second_product.name
 
 
+@pytest.mark.parametrize("is_published", [(True), (False)])
+def test_products_query_with_filter_search_by_sku(
+    is_published,
+    query_products_with_filter,
+    staff_api_client,
+    product_with_two_variants,
+    product_with_default_variant,
+    permission_manage_products,
+):
+    product_with_default_variant.is_published = is_published
+    product_with_default_variant.save(update_fields=["is_published"])
+    variables = {"filter": {"search": "1234"}}
+    staff_api_client.user.user_permissions.add(permission_manage_products)
+    response = staff_api_client.post_graphql(query_products_with_filter, variables)
+    content = get_graphql_content(response)
+    product_id = graphene.Node.to_global_id("Product", product_with_default_variant.id)
+    products = content["data"]["products"]["edges"]
+
+    assert len(products) == 1
+    assert products[0]["node"]["id"] == product_id
+    assert products[0]["node"]["name"] == product_with_default_variant.name
+
+
 def test_product_query_search(user_api_client, product_type, category):
     blue_product = Product.objects.create(
         name="Blue Paint",
diff --git a/tests/test_postgresql_search.py b/tests/test_postgresql_search.py
--- a/tests/test_postgresql_search.py
+++ b/tests/test_postgresql_search.py
@@ -61,13 +61,6 @@ def unpublish_product(product):
     prod_to_unpublish.save()
 
 
-@pytest.mark.integration
-@pytest.mark.django_db
-def test_storefront_filter_published_products(named_products):
-    unpublish_product(named_products[0])
-    assert not execute_search("Coffee")
-
-
 USERS = [
     ("Andreas", "Knop", "adreas.knop@example.com"),
     ("Euzebiusz", "Ziemniak", "euzeb.potato@cebula.pl"),