We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Bug in validate_price_precision
### What I'm trying to achieve
Get sane validation obviously.

### Steps to reproduce the problem
1. Try to create a voucher with the minimum order amount set to `2000`
2. It will throw an error.

### What I expected to happen
It shouldn't throw an error.

### Observation
Upon normalizing it converts the zeros to exponents.

```python
def validate_price_precision(value: Optional["Decimal"], currency: str = None):
    """Validate if price amount does not have too many decimal places.

    Price amount can't have more decimal places than currency allows to.
    Works only with decimal created from a string.
    """

    # check no needed when there is no value
    if not value:
        return

    currency_fraction = get_currency_fraction(currency or settings.DEFAULT_CURRENCY)
    value = value.normalize()
    if abs(value.as_tuple().exponent) > currency_fraction:
        raise ValidationError(
            f"Value cannot have more than {currency_fraction} decimal places."
        )
```
should be:

```python
def validate_price_precision(value: Optional["Decimal"], currency: str = None):
    """Validate if price amount does not have too many decimal places.

    Price amount can't have more decimal places than currency allows to.
    Works only with decimal created from a string.
    """

    # check no needed when there is no value
    if not value:
        return

    currency_fraction = get_currency_fraction(currency or settings.DEFAULT_CURRENCY)
    value = value.normalize()
    exp = value.as_tuple().exponent
    if exp < 0 and abs(value.as_tuple().exponent) > currency_fraction:
        raise ValidationError(
            f"Value cannot have more than {currency_fraction} decimal places."
        )
```
So that it doesn't misinterpret zeros from the right as values after decimal places.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `saleor/graphql/core/validators.py`
Content:
```
1 from typing import TYPE_CHECKING, Optional
2 
3 from django.conf import settings
4 from django.core.exceptions import ValidationError
5 from django_prices.utils.formatting import get_currency_fraction
6 from graphql.error import GraphQLError
7 
8 if TYPE_CHECKING:
9     from decimal import Decimal
10 
11 
12 def validate_one_of_args_is_in_query(*args):
13     # split args into a list with 2-element tuples:
14     # [(arg1_name, arg1_value), (arg2_name, arg2_value), ...]
15     splitted_args = [args[i : i + 2] for i in range(0, len(args), 2)]  # noqa: E203
16     # filter trueish values from each tuple
17     filter_args = list(filter(lambda item: bool(item[1]) is True, splitted_args))
18 
19     if len(filter_args) > 1:
20         rest_args = ", ".join([f"'{item[0]}'" for item in filter_args[1:]])
21         raise GraphQLError(
22             f"Argument '{filter_args[0][0]}' cannot be combined with {rest_args}"
23         )
24 
25     if not filter_args:
26         required_args = ", ".join([f"'{item[0]}'" for item in splitted_args])
27         raise GraphQLError(f"At least one of arguments is required: {required_args}.")
28 
29 
30 def validate_price_precision(value: Optional["Decimal"], currency: str = None):
31     """Validate if price amount does not have too many decimal places.
32 
33     Price amount can't have more decimal places than currency allow to.
34     Works only with decimal created from a string.
35     """
36 
37     # check no needed when there is no value
38     if not value:
39         return
40 
41     currency_fraction = get_currency_fraction(currency or settings.DEFAULT_CURRENCY)
42     value = value.normalize()
43     if abs(value.as_tuple().exponent) > currency_fraction:
44         raise ValidationError(
45             f"Value cannot have more than {currency_fraction} decimal places."
46         )
47
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/saleor/graphql/core/validators.py b/saleor/graphql/core/validators.py
--- a/saleor/graphql/core/validators.py
+++ b/saleor/graphql/core/validators.py
@@ -40,7 +40,7 @@
 
     currency_fraction = get_currency_fraction(currency or settings.DEFAULT_CURRENCY)
     value = value.normalize()
-    if abs(value.as_tuple().exponent) > currency_fraction:
+    if value.as_tuple().exponent < -currency_fraction:
         raise ValidationError(
             f"Value cannot have more than {currency_fraction} decimal places."
         )

{"golden_diff": "diff --git a/saleor/graphql/core/validators.py b/saleor/graphql/core/validators.py\n--- a/saleor/graphql/core/validators.py\n+++ b/saleor/graphql/core/validators.py\n@@ -40,7 +40,7 @@\n \n     currency_fraction = get_currency_fraction(currency or settings.DEFAULT_CURRENCY)\n     value = value.normalize()\n-    if abs(value.as_tuple().exponent) > currency_fraction:\n+    if value.as_tuple().exponent < -currency_fraction:\n         raise ValidationError(\n             f\"Value cannot have more than {currency_fraction} decimal places.\"\n         )\n", "issue": "Bug in validate_price_precision\n### What I'm trying to achieve\r\nGet sane validation obviously.\r\n\r\n### Steps to reproduce the problem\r\n1. Try to create a voucher with the minimum order amount set to `2000`\r\n2. It will throw an error.\r\n\r\n### What I expected to happen\r\nIt shouldn't throw an error.\r\n\r\n### Observation\r\nUpon normalizing it converts the zeros to exponents.\r\n\r\n```python\r\ndef validate_price_precision(value: Optional[\"Decimal\"], currency: str = None):\r\n    \"\"\"Validate if price amount does not have too many decimal places.\r\n\r\n    Price amount can't have more decimal places than currency allows to.\r\n    Works only with decimal created from a string.\r\n    \"\"\"\r\n\r\n    # check no needed when there is no value\r\n    if not value:\r\n        return\r\n\r\n    currency_fraction = get_currency_fraction(currency or settings.DEFAULT_CURRENCY)\r\n    value = value.normalize()\r\n    if abs(value.as_tuple().exponent) > currency_fraction:\r\n        raise ValidationError(\r\n            f\"Value cannot have more than {currency_fraction} decimal places.\"\r\n        )\r\n```\r\nshould be:\r\n\r\n```python\r\ndef validate_price_precision(value: Optional[\"Decimal\"], currency: str = None):\r\n    \"\"\"Validate if price amount does not have too many decimal places.\r\n\r\n    Price amount can't have more decimal places than currency allows to.\r\n    Works only with decimal created from a string.\r\n    \"\"\"\r\n\r\n    # check no needed when there is no value\r\n    if not value:\r\n        return\r\n\r\n    currency_fraction = get_currency_fraction(currency or settings.DEFAULT_CURRENCY)\r\n    value = value.normalize()\r\n    exp = value.as_tuple().exponent\r\n    if exp < 0 and abs(value.as_tuple().exponent) > currency_fraction:\r\n        raise ValidationError(\r\n            f\"Value cannot have more than {currency_fraction} decimal places.\"\r\n        )\r\n```\r\nSo that it doesn't misinterpret zeros from the right as values after decimal places.\r\n\n", "before_files": [{"content": "from typing import TYPE_CHECKING, Optional\n\nfrom django.conf import settings\nfrom django.core.exceptions import ValidationError\nfrom django_prices.utils.formatting import get_currency_fraction\nfrom graphql.error import GraphQLError\n\nif TYPE_CHECKING:\n    from decimal import Decimal\n\n\ndef validate_one_of_args_is_in_query(*args):\n    # split args into a list with 2-element tuples:\n    # [(arg1_name, arg1_value), (arg2_name, arg2_value), ...]\n    splitted_args = [args[i : i + 2] for i in range(0, len(args), 2)]  # noqa: E203\n    # filter trueish values from each tuple\n    filter_args = list(filter(lambda item: bool(item[1]) is True, splitted_args))\n\n    if len(filter_args) > 1:\n        rest_args = \", \".join([f\"'{item[0]}'\" for item in filter_args[1:]])\n        raise GraphQLError(\n            f\"Argument '{filter_args[0][0]}' cannot be combined with {rest_args}\"\n        )\n\n    if not filter_args:\n        required_args = \", \".join([f\"'{item[0]}'\" for item in splitted_args])\n        raise GraphQLError(f\"At least one of arguments is required: {required_args}.\")\n\n\ndef validate_price_precision(value: Optional[\"Decimal\"], currency: str = None):\n    \"\"\"Validate if price amount does not have too many decimal places.\n\n    Price amount can't have more decimal places than currency allow to.\n    Works only with decimal created from a string.\n    \"\"\"\n\n    # check no needed when there is no value\n    if not value:\n        return\n\n    currency_fraction = get_currency_fraction(currency or settings.DEFAULT_CURRENCY)\n    value = value.normalize()\n    if abs(value.as_tuple().exponent) > currency_fraction:\n        raise ValidationError(\n            f\"Value cannot have more than {currency_fraction} decimal places.\"\n        )\n", "path": "saleor/graphql/core/validators.py"}], "after_files": [{"content": "from typing import TYPE_CHECKING, Optional\n\nfrom django.conf import settings\nfrom django.core.exceptions import ValidationError\nfrom django_prices.utils.formatting import get_currency_fraction\nfrom graphql.error import GraphQLError\n\nif TYPE_CHECKING:\n    from decimal import Decimal\n\n\ndef validate_one_of_args_is_in_query(*args):\n    # split args into a list with 2-element tuples:\n    # [(arg1_name, arg1_value), (arg2_name, arg2_value), ...]\n    splitted_args = [args[i : i + 2] for i in range(0, len(args), 2)]  # noqa: E203\n    # filter trueish values from each tuple\n    filter_args = list(filter(lambda item: bool(item[1]) is True, splitted_args))\n\n    if len(filter_args) > 1:\n        rest_args = \", \".join([f\"'{item[0]}'\" for item in filter_args[1:]])\n        raise GraphQLError(\n            f\"Argument '{filter_args[0][0]}' cannot be combined with {rest_args}\"\n        )\n\n    if not filter_args:\n        required_args = \", \".join([f\"'{item[0]}'\" for item in splitted_args])\n        raise GraphQLError(f\"At least one of arguments is required: {required_args}.\")\n\n\ndef validate_price_precision(value: Optional[\"Decimal\"], currency: str = None):\n    \"\"\"Validate if price amount does not have too many decimal places.\n\n    Price amount can't have more decimal places than currency allow to.\n    Works only with decimal created from a string.\n    \"\"\"\n\n    # check no needed when there is no value\n    if not value:\n        return\n\n    currency_fraction = get_currency_fraction(currency or settings.DEFAULT_CURRENCY)\n    value = value.normalize()\n    if value.as_tuple().exponent < -currency_fraction:\n        raise ValidationError(\n            f\"Value cannot have more than {currency_fraction} decimal places.\"\n        )\n", "path": "saleor/graphql/core/validators.py"}]}