c086f64363
- Add 7 core API endpoints: users, transactions, partners, products, inventory, payments, credit - Implement role-based authentication (admin/write/read-only access) - Add comprehensive database models with proper relationships - Include full test coverage for all endpoints and business logic - Set up Alembic migrations and Docker configuration - Configure FastAPI app with CORS and database integration
211 lines
4.7 KiB
Python
211 lines
4.7 KiB
Python
"""
|
|
Custom validation schema
|
|
"""
|
|
from sqlmodel import SQLModel
|
|
from app.schemas.base import UserRole, PartnerType, PaymentMethod
|
|
from typing import Optional
|
|
from datetime import datetime, date
|
|
from .base import TransactionType, TransactionStatus
|
|
|
|
|
|
######################################################
|
|
# Users
|
|
class UserCreate(SQLModel):
|
|
username: str
|
|
password: str
|
|
role: UserRole = UserRole.READ_ONLY
|
|
|
|
|
|
class UserUpdate(SQLModel):
|
|
username: Optional[str] = None
|
|
password: Optional[str] = None
|
|
role: Optional[UserRole] = None
|
|
|
|
|
|
class UserLogin(SQLModel):
|
|
username: str
|
|
password: str
|
|
|
|
|
|
class UserResponse(SQLModel):
|
|
id: Optional[int] = None
|
|
username: str
|
|
role: UserRole
|
|
|
|
|
|
class Token(SQLModel):
|
|
access_token: str
|
|
token_type: str
|
|
expires_in: int
|
|
user: UserResponse
|
|
|
|
|
|
class TokenData(SQLModel):
|
|
username: Optional[str] = None
|
|
user_id: Optional[int] = None
|
|
role: Optional[UserRole] = None
|
|
|
|
|
|
##################################################
|
|
# Transactions
|
|
class TransactionBase(SQLModel):
|
|
partner_id: int
|
|
transcation_type: TransactionType = TransactionType.SALE
|
|
transaction_status: TransactionStatus = TransactionStatus.UNPAID
|
|
total_amount: int
|
|
|
|
class TransactionCreate(TransactionBase):
|
|
pass
|
|
|
|
class TransactionUpdate(SQLModel):
|
|
partner_id: Optional[int] = None
|
|
transcation_type: Optional[TransactionType] = None
|
|
transaction_status: Optional[TransactionStatus] = None
|
|
total_amount: Optional[int] = None
|
|
|
|
class TransactionResponse(TransactionBase):
|
|
id: int
|
|
created_by: int
|
|
updated_by: int
|
|
created_on: datetime
|
|
updated_on: datetime
|
|
|
|
|
|
##################################################
|
|
# Partners
|
|
class PartnerBase(SQLModel):
|
|
tin_number: int
|
|
names: str
|
|
type: PartnerType = PartnerType.CLIENT
|
|
phone_number: Optional[str] = None
|
|
|
|
class PartnerCreate(PartnerBase):
|
|
pass
|
|
|
|
class PartnerUpdate(SQLModel):
|
|
tin_number: Optional[int] = None
|
|
names: Optional[str] = None
|
|
type: Optional[PartnerType] = None
|
|
phone_number: Optional[str] = None
|
|
|
|
class PartnerResponse(PartnerBase):
|
|
id: int
|
|
|
|
|
|
##################################################
|
|
# Products
|
|
class ProductBase(SQLModel):
|
|
product_code: str
|
|
product_name: str
|
|
purchase_price: int
|
|
selling_price: int
|
|
|
|
class ProductCreate(ProductBase):
|
|
pass
|
|
|
|
class ProductUpdate(SQLModel):
|
|
product_code: Optional[str] = None
|
|
product_name: Optional[str] = None
|
|
purchase_price: Optional[int] = None
|
|
selling_price: Optional[int] = None
|
|
|
|
class ProductResponse(ProductBase):
|
|
id: int
|
|
date_modified: datetime
|
|
|
|
|
|
##################################################
|
|
# Transaction Details
|
|
class TransactionDetailsBase(SQLModel):
|
|
partner_id: int
|
|
product_id: int
|
|
qty: int
|
|
selling_price: int
|
|
total_value: int
|
|
|
|
class TransactionDetailsCreate(TransactionDetailsBase):
|
|
pass
|
|
|
|
class TransactionDetailsUpdate(SQLModel):
|
|
partner_id: Optional[int] = None
|
|
product_id: Optional[int] = None
|
|
qty: Optional[int] = None
|
|
selling_price: Optional[int] = None
|
|
total_value: Optional[int] = None
|
|
|
|
class TransactionDetailsResponse(TransactionDetailsBase):
|
|
id: int
|
|
created_by: int
|
|
updated_by: int
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
|
|
##################################################
|
|
# Payments
|
|
class PaymentBase(SQLModel):
|
|
transaction_id: int
|
|
payment_method: PaymentMethod = PaymentMethod.CASH
|
|
paid_amount: int
|
|
payment_date: date
|
|
|
|
class PaymentCreate(PaymentBase):
|
|
pass
|
|
|
|
class PaymentUpdate(SQLModel):
|
|
transaction_id: Optional[int] = None
|
|
payment_method: Optional[PaymentMethod] = None
|
|
paid_amount: Optional[int] = None
|
|
payment_date: Optional[date] = None
|
|
|
|
class PaymentResponse(PaymentBase):
|
|
id: int
|
|
created_by: int
|
|
updated_by: int
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
|
|
##################################################
|
|
# Credit
|
|
class CreditBase(SQLModel):
|
|
partner_id: int
|
|
transaction_id: int
|
|
credit_amount: int
|
|
credit_limit: int
|
|
balance: int
|
|
|
|
class CreditCreate(CreditBase):
|
|
pass
|
|
|
|
class CreditUpdate(SQLModel):
|
|
partner_id: Optional[int] = None
|
|
transaction_id: Optional[int] = None
|
|
credit_amount: Optional[int] = None
|
|
credit_limit: Optional[int] = None
|
|
balance: Optional[int] = None
|
|
|
|
class CreditResponse(CreditBase):
|
|
id: int
|
|
created_by: int
|
|
updated_by: int
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
|
|
##################################################
|
|
# Inventory
|
|
class InventoryBase(SQLModel):
|
|
product_id: int
|
|
total_qty: int
|
|
|
|
class InventoryCreate(InventoryBase):
|
|
pass
|
|
|
|
class InventoryUpdate(SQLModel):
|
|
product_id: Optional[int] = None
|
|
total_qty: Optional[int] = None
|
|
|
|
class InventoryResponse(InventoryBase):
|
|
id: int
|