104 lines
3.6 KiB
Python
104 lines
3.6 KiB
Python
"""
|
|
This module contains Pydantic/Database Models that map database tables validate
|
|
and serialize api responses.
|
|
|
|
If the logic is identical -> SQLModel is used to do both.
|
|
Otherwise pydantic - for api responses
|
|
And SQLAlchemy is used for db data validation.
|
|
|
|
TODO:
|
|
Mapping & validation for:
|
|
- Clients, Suppliers, Products, payments
|
|
|
|
Done:
|
|
* Table mappings
|
|
"""
|
|
from sqlmodel import SQLModel, Field, UniqueConstraint
|
|
from datetime import datetime
|
|
from sqlalchemy import Column, DateTime, func, Enum as SQLEnum
|
|
from enum import Enum
|
|
from typing import Optional
|
|
|
|
|
|
class TradeType(str, Enum):
|
|
BUY = "Buy"
|
|
SELL = "Sell"
|
|
|
|
|
|
class Client(SQLModel, table=True):
|
|
"""Clients table mapping, api response validation and serialisation"""
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
tin_number: int = Field(nullable=False, unique=True)
|
|
names: str = Field(max_length=100, nullable=False)
|
|
phone_number: str = Field(max_length=10, nullable=False)
|
|
|
|
|
|
class Supplier(SQLModel, table=True):
|
|
"""Supplier table mapping, api response validation and serialisation"""
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
tin_number: int = Field(nullable=False, unique=True)
|
|
names: str = Field(max_length=100, nullable=False)
|
|
phone_number: str = Field(max_length=10, nullable=False)
|
|
|
|
|
|
class Product(SQLModel, table=True):
|
|
"""Products table mapping, api response validation and serialisation
|
|
|
|
NOTE: purchase price should update every time a supplier credits us goods
|
|
and price has changed
|
|
"""
|
|
__table_args__ = (UniqueConstraint("product_code"),)
|
|
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
product_code: str = Field(max_length=10, nullable=False)
|
|
product_name: str = Field(max_length=20, nullable=False, unique=True)
|
|
purchase_price: int = Field(nullable=False)
|
|
date_modified: datetime = Field(
|
|
default=None,
|
|
sa_column=Column(DateTime,
|
|
server_default=func.now(),
|
|
server_onupdate=func.now())
|
|
)
|
|
|
|
|
|
class Payment(SQLModel, table=True):
|
|
"""
|
|
Payments table mapping, api response validation and serialisation
|
|
|
|
Include both payments to suppliers and from clients
|
|
"""
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
payment_type: TradeType = Field(
|
|
sa_column=Column(SQLEnum(TradeType), nullable=False)
|
|
)
|
|
product_code: str = Field(nullable=False, foreign_key="product.product_code")
|
|
client_id: Optional[int] = Field(nullable=False, foreign_key="client.id")
|
|
|
|
supplier_id: Optional[int] = Field(nullable=False, foreign_key="supplier.id")
|
|
amount: int = Field(nullable=False)
|
|
payment_method: str = Field(max_length=24, nullable=False)
|
|
date: datetime = Field(
|
|
default=None,
|
|
sa_column=Column(DateTime, server_default=func.now())
|
|
)
|
|
|
|
|
|
class Credit(SQLModel, table=True):
|
|
"""Credit table mapping, api response validation and serialisation
|
|
|
|
Include both credit from suppliers and to clients
|
|
"""
|
|
id: Optional[int] = Field(default=None, primary_key=True)
|
|
transcation_type: TradeType = Field(
|
|
sa_column=Column(SQLEnum(TradeType), nullable=False)
|
|
)
|
|
product_code: str = Field(nullable=False, foreign_key="product.product_code")
|
|
client_id: Optional[int] = Field(nullable=False, foreign_key="client.id")
|
|
supplier_id: Optional[int] = Field(nullable=False, foreign_key="supplier.id")
|
|
qty: int = Field(nullable=False)
|
|
amount: int = Field(nullable=False)
|
|
date: datetime = Field(
|
|
default=None,
|
|
sa_column=Column(DateTime, server_default=func.now())
|
|
)
|