Repository: saleor/saleor

Issue:
Bug: Creating PromotionRule with metadata fails
### What are you trying to achieve?

Creating `PromotionRule` with `metadata` is raising an error

[Sentry issue](https://saleor.sentry.io/issues/4853378415/?alert_rule_id=5529758&alert_type=issue&notification_uuid=b9337834-45f3-4477-b59e-3d9dfdd47e72&project=5381657&referrer=slack)

### Steps to reproduce the problem

```
{
"operationName": "MyMutation", 
"query": 
"mutation MyMutation {
  promotionRuleCreate(
    input: {promotion: "UHJvbW90aW9uOmI0NDA2Y2NhLTlmMjMtNDA1Yy05M2RlLTE5MzUxYWE1NGJjNA==", cataloguePredicate: {variantPredicate: {metadata: {key: "tst", value: "tst"}}}, rewardValue: "2", rewardValueType: PERCENTAGE}
  ) {
    errors {
      code
      field
      message
    }
  }
}"
}
```

### What did you expect to happen?

An error shouldn't be raised

### Logs

_No response_

### Environment

Saleor version: …
OS and version: …



Discussion:

Resolving patch:
diff --git a/saleor/graphql/core/filters.py b/saleor/graphql/core/filters.py
--- a/saleor/graphql/core/filters.py
+++ b/saleor/graphql/core/filters.py
@@ -92,10 +92,12 @@ def filter_status(qs, _, value):
 
 def filter_metadata(qs, _, value):
     for metadata_item in value:
-        if metadata_item.value:
-            qs = qs.filter(metadata__contains={metadata_item.key: metadata_item.value})
+        metadata_value = metadata_item.get("value")
+        metadata_key = metadata_item.get("key")
+        if metadata_value:
+            qs = qs.filter(metadata__contains={metadata_key: metadata_value})
         else:
-            qs = qs.filter(metadata__has_key=metadata_item.key)
+            qs = qs.filter(metadata__has_key=metadata_key)
     return qs
 
 


Test patch:
diff --git a/saleor/graphql/discount/tests/mutations/test_promotion_rule_create.py b/saleor/graphql/discount/tests/mutations/test_promotion_rule_create.py
--- a/saleor/graphql/discount/tests/mutations/test_promotion_rule_create.py
+++ b/saleor/graphql/discount/tests/mutations/test_promotion_rule_create.py
@@ -932,3 +932,53 @@ def test_promotion_rule_create_serializable_decimal_in_predicate(
     data = content["data"]["promotionRuleCreate"]
     assert not data["errors"]
     assert data["promotionRule"]["cataloguePredicate"] == catalogue_predicate
+
+
+def test_promotion_rule_create_with_metadata(
+    staff_api_client,
+    permission_group_manage_discounts,
+    description_json,
+    channel_USD,
+    channel_PLN,
+    variant,
+    product,
+    collection,
+    category,
+    promotion,
+):
+    # given
+    permission_group_manage_discounts.user_set.add(staff_api_client.user)
+
+    channel_ids = [
+        graphene.Node.to_global_id("Channel", channel.pk)
+        for channel in [channel_USD, channel_PLN]
+    ]
+    catalogue_predicate = {
+        "OR": [{"variantPredicate": {"metadata": [{"key": "test", "value": "test"}]}}]
+    }
+    name = "test promotion rule"
+    reward_value = Decimal("10")
+    reward_value_type = RewardValueTypeEnum.PERCENTAGE.name
+    promotion_id = graphene.Node.to_global_id("Promotion", promotion.id)
+
+    variables = {
+        "input": {
+            "name": name,
+            "promotion": promotion_id,
+            "description": description_json,
+            "channels": channel_ids,
+            "rewardValueType": reward_value_type,
+            "rewardValue": reward_value,
+            "cataloguePredicate": catalogue_predicate,
+        }
+    }
+
+    # when
+    response = staff_api_client.post_graphql(PROMOTION_RULE_CREATE_MUTATION, variables)
+
+    # then
+    content = get_graphql_content(response)
+    data = content["data"]["promotionRuleCreate"]
+
+    assert not data["errors"]
+    assert data["promotionRule"]