Source code for ferrosoft.apps.ferrobase.models.fields

#  Copyright (c) 2025 Ferrosoft GmbH. All rights reserved.
from decimal import Decimal

from django.db.models.fields import DecimalField


[docs] class CustomDecimalField(DecimalField): """Base decimal field that omits ``max_digits`` / ``decimal_places`` from migrations. Subclasses hard-code these parameters so migrations stay clean. The ``ROUND`` class attribute controls the quantization precision used by the ``round`` class method. """ ROUND = Decimal("1.00")
[docs] def deconstruct(self): name, path, args, kwargs = super().deconstruct() del kwargs["max_digits"] del kwargs["decimal_places"] if kwargs.get("default") == 0: del kwargs["default"] return name, path, args, kwargs
[docs] @classmethod def round(cls, value: Decimal) -> Decimal: return value.quantize(cls.ROUND)
[docs] class NormalDecimalField(CustomDecimalField): """DecimalField with max_digits and decimal_places useful for most cases.""" def __init__(self, *args, **kwargs): super().__init__( *args, max_digits=12, decimal_places=4, default=kwargs.pop("default", 0), **kwargs, )
[docs] class BigDecimalField(CustomDecimalField): """DecimalField with max_digits and decimal_places useful for big values.""" def __init__(self, *args, **kwargs): super().__init__( *args, max_digits=18, decimal_places=9, default=kwargs.pop("default", 0), **kwargs, )
[docs] class TonDecimalField(CustomDecimalField): """DecimalField with max_digits and decimal_places useful for tonnages not requiring any decimal places.""" ROUND = Decimal("1") def __init__(self, *args, **kwargs): super().__init__( *args, max_digits=9, decimal_places=0, default=kwargs.pop("default", 0), **kwargs, )
[docs] class BigMoneyField(CustomDecimalField): """DecimalField with max_digits and decimal_places useful for big money values.""" ROUND = Decimal("1.000") def __init__(self, *args, **kwargs): super().__init__( *args, max_digits=18, decimal_places=3, default=kwargs.pop("default", 0), **kwargs, )
[docs] class CoordinateDecimalField(CustomDecimalField): """DecimalField with max_digits and decimal_places useful for geographic coordinate.""" ROUND = Decimal("1.000000") def __init__(self, *args, **kwargs): super().__init__( *args, max_digits=9, decimal_places=6, default=kwargs.pop("default", 0), **kwargs, )