brewman/brewman/brewman/models/inventory.py

68 lines
2.3 KiB
Python

import uuid
from decimal import Decimal
from typing import TYPE_CHECKING, Optional
from sqlalchemy import Column, ForeignKey, Numeric, UniqueConstraint
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import Mapped, relationship
from .meta import Base
if TYPE_CHECKING:
# if the target of the relationship is in another module
# that cannot normally be imported at runtime
from .batch import Batch
from .voucher import Voucher
class Inventory(Base):
__tablename__ = "inventories"
__table_args__ = (UniqueConstraint("voucher_id", "batch_id"),)
id: uuid.UUID = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
voucher_id: uuid.UUID = Column(
"voucher_id",
UUID(as_uuid=True),
ForeignKey("vouchers.id"),
nullable=False,
index=True,
)
batch_id: uuid.UUID = Column("batch_id", UUID(as_uuid=True), ForeignKey("batches.id"), nullable=False)
quantity: Decimal = Column("quantity", Numeric(precision=15, scale=2), nullable=False)
rate: Decimal = Column("rate", Numeric(precision=15, scale=2), nullable=False)
tax: Decimal = Column("tax", Numeric(precision=15, scale=5), nullable=False)
discount: Decimal = Column("discount", Numeric(precision=15, scale=5), nullable=False)
voucher: Mapped["Voucher"] = relationship("Voucher", back_populates="inventories")
batch: Mapped["Batch"] = relationship("Batch", back_populates="inventories")
def __init__(
self,
quantity: Decimal,
rate: Decimal,
tax: Decimal,
discount: Decimal,
batch: "Batch",
voucher_id: Optional[uuid.UUID] = None,
id_: Optional[uuid.UUID] = None,
) -> None:
self.batch = batch
self.quantity = quantity
self.rate = rate
self.tax = tax
self.discount = discount
if id_ is not None:
self.id = id_
if voucher_id is not None:
self.voucher_id = voucher_id
@hybrid_property
def amount(self) -> Decimal:
return self.quantity * self.rate * (1 + self.tax) * (1 - self.discount)
@amount.expression # type: ignore[no-redef]
def amount(cls) -> Decimal:
return cls.quantity * cls.rate * (1 + cls.tax) * (1 - cls.discount)