Repository: saleor/saleor

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.



Discussion:
Hi @uroybd, thank you for reporting the issue. The problem is already known and solved on master (#6572). I suppose you are using `Saleor 2.11`, so we will apply those changes to `2.11` as soon as possible.

Resolving patch:
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 @@ def validate_price_precision(value: Optional["Decimal"], currency: str = None):
 
     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."
         )


Test patch:
diff --git a/saleor/graphql/core/tests/test_validators.py b/saleor/graphql/core/tests/test_validators.py
--- a/saleor/graphql/core/tests/test_validators.py
+++ b/saleor/graphql/core/tests/test_validators.py
@@ -16,6 +16,7 @@
         (Decimal("1"), "ISK"),
         (Decimal("1.00"), "ISK"),
         (Decimal("5.12"), None),
+        (Decimal("1000"), "USD"),
     ],
 )
 def test_validate_price_precision(value, currency):