Repository: marcosschroh/dataclasses-avroschema

Issue:
ModelGenerator's output raises NameError for decimal fields
**Describe the bug**
Code generated by the `ModelGenerator` for schemas containing a decimal logical type field cannot run due to a missing import.

**To Reproduce**
```py
import dataclasses_avroschema

schema = {
    "type": "record",
    "name": "demo",
    "fields": [
        {
            "name": "foo",
            "type": {
                "type": "bytes",
                "logicalType": "decimal",
                "precision": 10,
                "scale": 3
            }
        }
    ]
}
code = dataclasses_avroschema.ModelGenerator().render(schema=schema)

with open("/tmp/generated_code.py", "w") as f:
    print(code, file=f)
```
```sh
python3 /tmp/generated_code.py
```
```
Traceback (most recent call last):
  File "/tmp/generated_code.py", line 7, in <module>
    class Demo(AvroModel):
  File "/tmp/generated_code.py", line 8, in Demo
    foo: decimal.Decimal = types.Decimal(scale=3, precision=10)
                           ^^^^^
NameError: name 'types' is not defined. Did you mean: 'type'?
```

**Expected behavior**
Loadable code without the `NameError`.


Comments:

Patch:
diff --git a/dataclasses_avroschema/model_generator/generator.py b/dataclasses_avroschema/model_generator/generator.py
index 3c9326c..8a5b4ee 100644
--- a/dataclasses_avroschema/model_generator/generator.py
+++ b/dataclasses_avroschema/model_generator/generator.py
@@ -253,8 +253,9 @@ class ModelGenerator:
             return field_repr
         return avro_to_python_utils.AVRO_TYPE_TO_PYTHON[logical_type]
 
-    @staticmethod
-    def _parse_decimal(*, field: JsonDict) -> str:
+    def _parse_decimal(self, *, field: JsonDict) -> str:
+        self.imports.add("from dataclasses_avroschema import types")
+
         schema: JsonDict = field["type"]
         precision = schema["precision"]
         scale = schema["scale"]
@@ -295,11 +296,6 @@ class ModelGenerator:
                 language_types = self.parse_union(field_types=field_types[1:], model_name=model_name)
             elif isinstance(field_types[1], dict):
                 # TODO: check what happens with more than 2 complex types
-                # it is a complex type like array, dict, enum, fixed or record
-                # it needs to be render
-                # if self._is_logical_type(field_type=field_types[1]):
-                #     language_types = self.parse_logical_type(field=field_types[1])
-                # else:
                 language_types = self.render_field(field=field_types[1], model_name=model_name)
             else:
                 language_types = ", ".join(


Test patch:
diff --git a/tests/model_generator/conftest.py b/tests/model_generator/conftest.py
index a9b7af6..f3f75cc 100644
--- a/tests/model_generator/conftest.py
+++ b/tests/model_generator/conftest.py
@@ -313,6 +313,15 @@ def schema_one_to_self_relationship() -> JsonDict:
     }
 
 
+@pytest.fixture
+def schema_with_decimal_field() -> JsonDict:
+    return {
+        "type": "record",
+        "name": "demo",
+        "fields": [{"name": "foo", "type": {"type": "bytes", "logicalType": "decimal", "precision": 10, "scale": 3}}],
+    }
+
+
 @pytest.fixture
 def schema_with_logical_types() -> JsonDict:
     return {
diff --git a/tests/model_generator/test_model_generator.py b/tests/model_generator/test_model_generator.py
index 36b46e7..4864b5a 100644
--- a/tests/model_generator/test_model_generator.py
+++ b/tests/model_generator/test_model_generator.py
@@ -1,5 +1,4 @@
-from dataclasses_avroschema import ModelGenerator, types, field_utils
-
+from dataclasses_avroschema import ModelGenerator, field_utils, types
 from dataclasses_avroschema.model_generator.avro_to_python_utils import render_datetime
 
 
@@ -282,6 +281,23 @@ class User(AvroModel):
     assert result.strip() == expected_result.strip()
 
 
+def test_decimal_field(schema_with_decimal_field: types.JsonDict) -> None:
+    expected_result = """
+from dataclasses_avroschema import AvroModel
+from dataclasses_avroschema import types
+import dataclasses
+import decimal
+
+
+@dataclasses.dataclass
+class Demo(AvroModel):
+    foo: decimal.Decimal = types.Decimal(scale=3, precision=10)
+"""
+    model_generator = ModelGenerator()
+    result = model_generator.render(schema=schema_with_decimal_field)
+    assert result.strip() == expected_result.strip()
+
+
 def test_schema_logical_types(schema_with_logical_types: types.JsonDict) -> None:
     release_datetime = render_datetime(value=1570903062000, format=field_utils.TIMESTAMP_MILLIS)
     release_datetime_micro = render_datetime(value=1570903062000000, format=field_utils.TIMESTAMP_MICROS)