62 lines
2.2 KiB
Python
62 lines
2.2 KiB
Python
import uuid
|
||
from decimal import Decimal
|
||
|
||
from django.db import models
|
||
|
||
|
||
class StockSnapshot(models.Model):
|
||
"""Point-in-time stock observation supplied by a source system."""
|
||
|
||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||
product = models.ForeignKey(
|
||
"commerce.Product",
|
||
on_delete=models.CASCADE,
|
||
related_name="stock_snapshots",
|
||
verbose_name="Товар",
|
||
)
|
||
source = models.ForeignKey(
|
||
"commerce.SourceSystem",
|
||
on_delete=models.PROTECT,
|
||
related_name="stock_snapshots",
|
||
verbose_name="Источник",
|
||
)
|
||
warehouse_external_id = models.CharField("ID склада", max_length=255)
|
||
warehouse_name = models.CharField("Склад", max_length=255, blank=True)
|
||
quantity = models.DecimalField(
|
||
"Остаток", max_digits=18, decimal_places=4, default=Decimal("0")
|
||
)
|
||
reserved = models.DecimalField(
|
||
"Резерв", max_digits=18, decimal_places=4, default=Decimal("0")
|
||
)
|
||
in_transit = models.DecimalField(
|
||
"В пути", max_digits=18, decimal_places=4, default=Decimal("0")
|
||
)
|
||
captured_at = models.DateTimeField("Дата снимка", db_index=True)
|
||
metadata = models.JSONField("Дополнительные данные", default=dict, blank=True)
|
||
created_at = models.DateTimeField("Создано", auto_now_add=True)
|
||
|
||
class Meta:
|
||
verbose_name = "Снимок остатка"
|
||
verbose_name_plural = "Снимки остатков"
|
||
ordering = ["-captured_at"]
|
||
constraints = [
|
||
models.UniqueConstraint(
|
||
fields=["product", "source", "warehouse_external_id", "captured_at"],
|
||
name="commerce_stock_snapshot_identity",
|
||
)
|
||
]
|
||
indexes = [
|
||
models.Index(
|
||
fields=["product", "source", "warehouse_external_id", "-captured_at"],
|
||
name="commerce_stock_latest",
|
||
)
|
||
]
|
||
|
||
@property
|
||
def available(self):
|
||
return self.quantity - self.reserved
|
||
|
||
def __str__(self):
|
||
warehouse = self.warehouse_name or self.warehouse_external_id
|
||
return f"{self.product.sku} · {warehouse} · {self.quantity}"
|