104 lines
3.8 KiB
Python

from decimal import Decimal
from django.conf import settings
from django.core.validators import MinValueValidator, RegexValidator
from django.db import models
class ReportingEntry(models.Model):
"""Supplementary, documented facts absent from the operational sources.
Purchases and cash movements are not automatically expensed again in profit:
sales already carry their cost of goods. Corrections retain the audit trail.
"""
class Kind(models.TextChoices):
PRODUCTION = "production", "Выпуск продукции"
PURCHASE = "purchase", "Закупка для производства"
TAX = "tax", "Уплаченные налоги сотрудника"
OVERHEAD = "overhead", "Общие расходы"
CASH_IN = "cash_in", "Поступление денег"
CASH_OUT = "cash_out", "Выплата денег"
kind = models.CharField(max_length=16, choices=Kind.choices)
date = models.DateField("Дата факта", db_index=True)
reference = models.CharField("Документ / уникальный номер", max_length=200)
description = models.CharField("Описание", max_length=500, blank=True)
project = models.ForeignKey(
"commerce.ExternalProject", null=True, blank=True, on_delete=models.PROTECT
)
product = models.ForeignKey(
"commerce.Product", null=True, blank=True, on_delete=models.PROTECT
)
employee = models.ForeignKey(
settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.PROTECT
)
quantity = models.DecimalField(
max_digits=18,
decimal_places=4,
default=0,
validators=[MinValueValidator(Decimal("0"))],
)
amount = models.DecimalField(
max_digits=18,
decimal_places=2,
default=0,
validators=[MinValueValidator(Decimal("0"))],
)
currency = models.CharField(
max_length=3, default="RUB", validators=[RegexValidator(r"^[A-Z]{3}$")]
)
created_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.PROTECT,
related_name="reporting_entries_created",
)
created_at = models.DateTimeField(auto_now_add=True)
voided_at = models.DateTimeField(null=True, blank=True)
voided_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
null=True,
blank=True,
on_delete=models.PROTECT,
related_name="reporting_entries_voided",
)
class Meta:
ordering = ["-date", "-pk"]
constraints = [
models.UniqueConstraint(
fields=["kind", "reference"], name="reporting_entry_reference_unique"
),
models.CheckConstraint(
condition=models.Q(amount__gte=0, quantity__gte=0),
name="reporting_entry_nonnegative",
),
models.CheckConstraint(
condition=(
models.Q(
kind="production",
product__isnull=False,
employee__isnull=True,
quantity__gt=0,
amount=0,
)
| models.Q(kind="purchase", employee__isnull=True, amount__gt=0)
| models.Q(
kind="tax",
employee__isnull=False,
product__isnull=True,
amount__gt=0,
quantity=0,
)
| models.Q(
kind__in=["overhead", "cash_in", "cash_out"],
product__isnull=True,
employee__isnull=True,
amount__gt=0,
quantity=0,
)
),
name="reporting_entry_kind_fields",
),
]