feat: Implement Sales API with GET endpoint ✅ (auto-linted)
This commit is contained in:
parent
fb7c39f819
commit
dacdeb7945
34
alembic/versions/20250430_101955_cc017186_update_sale.py
Normal file
34
alembic/versions/20250430_101955_cc017186_update_sale.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
"""create table for sales
|
||||||
|
Revision ID: 2f9d3b7c8a4a
|
||||||
|
Revises: 0001
|
||||||
|
Create Date: 2023-05-25 12:34:56
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.sql import func
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '2f9d3b7c8a4a'
|
||||||
|
down_revision = '0001'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
op.create_table(
|
||||||
|
'sales',
|
||||||
|
sa.Column('id', sa.String(36), primary_key=True, default=lambda: str(uuid.uuid4())),
|
||||||
|
sa.Column('customer_id', sa.String(36), nullable=False),
|
||||||
|
sa.Column('product_id', sa.String(36), nullable=False),
|
||||||
|
sa.Column('quantity', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('price', sa.Float(), nullable=False),
|
||||||
|
sa.Column('total_amount', sa.Float(), nullable=False),
|
||||||
|
sa.Column('created_at', sa.DateTime(), server_default=func.now()),
|
||||||
|
sa.Column('updated_at', sa.DateTime(), server_default=func.now(), onupdate=func.now()),
|
||||||
|
sa.ForeignKeyConstraint(['customer_id'], ['customers.id']),
|
||||||
|
sa.ForeignKeyConstraint(['product_id'], ['products.id'])
|
||||||
|
)
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
op.drop_table('sales')
|
@ -0,0 +1,13 @@
|
|||||||
|
from fastapi import APIRouter, Depends
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
from typing import List
|
||||||
|
from core.database import get_db
|
||||||
|
from schemas.sale import SaleSchema
|
||||||
|
from helpers.sale_helpers import get_all_sales
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
@router.get("/Sales", status_code=200, response_model=List[SaleSchema])
|
||||||
|
async def get_sales(db: Session = Depends(get_db)):
|
||||||
|
sales = get_all_sales(db)
|
||||||
|
return sales
|
91
helpers/sale_helpers.py
Normal file
91
helpers/sale_helpers.py
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import uuid
|
||||||
|
from typing import List, Optional
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
from models.sale import Sale
|
||||||
|
from schemas.sale import SaleCreate, SaleUpdate
|
||||||
|
|
||||||
|
def get_all_sales(db: Session) -> List[Sale]:
|
||||||
|
"""
|
||||||
|
Retrieves all sales from the database.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db (Session): The database session.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[Sale]: A list of all sale objects.
|
||||||
|
"""
|
||||||
|
return db.query(Sale).all()
|
||||||
|
|
||||||
|
def get_sale_by_id(db: Session, sale_id: uuid.UUID) -> Optional[Sale]:
|
||||||
|
"""
|
||||||
|
Retrieves a single sale by its ID.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db (Session): The database session.
|
||||||
|
sale_id (UUID): The ID of the sale to retrieve.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Optional[Sale]: The sale object if found, otherwise None.
|
||||||
|
"""
|
||||||
|
return db.query(Sale).filter(Sale.id == sale_id).first()
|
||||||
|
|
||||||
|
def create_sale(db: Session, sale_data: SaleCreate) -> Sale:
|
||||||
|
"""
|
||||||
|
Creates a new sale in the database.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db (Session): The database session.
|
||||||
|
sale_data (SaleCreate): The data for the sale to create.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Sale: The newly created sale object.
|
||||||
|
"""
|
||||||
|
db_sale = Sale(**sale_data.dict())
|
||||||
|
db.add(db_sale)
|
||||||
|
db.commit()
|
||||||
|
db.refresh(db_sale)
|
||||||
|
return db_sale
|
||||||
|
|
||||||
|
def update_sale(db: Session, sale_id: uuid.UUID, sale_data: SaleUpdate) -> Optional[Sale]:
|
||||||
|
"""
|
||||||
|
Updates an existing sale in the database.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db (Session): The database session.
|
||||||
|
sale_id (UUID): The ID of the sale to update.
|
||||||
|
sale_data (SaleUpdate): The updated data for the sale.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Optional[Sale]: The updated sale object if found, otherwise None.
|
||||||
|
"""
|
||||||
|
db_sale = db.query(Sale).filter(Sale.id == sale_id).first()
|
||||||
|
if not db_sale:
|
||||||
|
return None
|
||||||
|
|
||||||
|
update_data = sale_data.dict(exclude_unset=True)
|
||||||
|
for key, value in update_data.items():
|
||||||
|
setattr(db_sale, key, value)
|
||||||
|
|
||||||
|
db.add(db_sale)
|
||||||
|
db.commit()
|
||||||
|
db.refresh(db_sale)
|
||||||
|
return db_sale
|
||||||
|
|
||||||
|
def delete_sale(db: Session, sale_id: uuid.UUID) -> bool:
|
||||||
|
"""
|
||||||
|
Deletes a sale from the database.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db (Session): The database session.
|
||||||
|
sale_id (UUID): The ID of the sale to delete.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if the sale was deleted, False otherwise.
|
||||||
|
"""
|
||||||
|
db_sale = db.query(Sale).filter(Sale.id == sale_id).first()
|
||||||
|
if not db_sale:
|
||||||
|
return False
|
||||||
|
|
||||||
|
db.delete(db_sale)
|
||||||
|
db.commit()
|
||||||
|
return True
|
21
models/sale.py
Normal file
21
models/sale.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
from sqlalchemy import Column, Integer, Float, DateTime, ForeignKey
|
||||||
|
from sqlalchemy.dialects.postgresql import UUID
|
||||||
|
from sqlalchemy.orm import relationship
|
||||||
|
from sqlalchemy.sql import func
|
||||||
|
from core.database import Base
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
class Sale(Base):
|
||||||
|
__tablename__ = "sales"
|
||||||
|
|
||||||
|
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
|
customer_id = Column(UUID(as_uuid=True), ForeignKey("customers.id"), nullable=False)
|
||||||
|
product_id = Column(UUID(as_uuid=True), ForeignKey("products.id"), nullable=False)
|
||||||
|
quantity = Column(Integer, nullable=False)
|
||||||
|
price = Column(Float, nullable=False)
|
||||||
|
total_amount = Column(Float, nullable=False)
|
||||||
|
created_at = Column(DateTime, default=func.now())
|
||||||
|
updated_at = Column(DateTime, default=func.now(), onupdate=func.now())
|
||||||
|
|
||||||
|
customer = relationship("Customer", back_populates="sales")
|
||||||
|
product = relationship("Product", back_populates="sales")
|
@ -7,3 +7,6 @@ sqlalchemy>=1.4.0
|
|||||||
python-dotenv>=0.19.0
|
python-dotenv>=0.19.0
|
||||||
bcrypt>=3.2.0
|
bcrypt>=3.2.0
|
||||||
alembic>=1.13.1
|
alembic>=1.13.1
|
||||||
|
jose
|
||||||
|
passlib
|
||||||
|
pydantic
|
||||||
|
27
schemas/sale.py
Normal file
27
schemas/sale.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
from pydantic import BaseModel, Field
|
||||||
|
from typing import Optional
|
||||||
|
from datetime import datetime
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
|
class SaleBase(BaseModel):
|
||||||
|
customer_id: UUID = Field(..., description="The ID of the customer")
|
||||||
|
product_id: UUID = Field(..., description="The ID of the product")
|
||||||
|
quantity: int = Field(..., gt=0, description="The quantity of the product sold")
|
||||||
|
price: float = Field(..., gt=0, description="The price of the product")
|
||||||
|
total_amount: float = Field(..., gt=0, description="The total amount of the sale")
|
||||||
|
|
||||||
|
class SaleCreate(SaleBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class SaleUpdate(SaleBase):
|
||||||
|
quantity: Optional[int] = Field(None, gt=0, description="The quantity of the product sold")
|
||||||
|
price: Optional[float] = Field(None, gt=0, description="The price of the product")
|
||||||
|
total_amount: Optional[float] = Field(None, gt=0, description="The total amount of the sale")
|
||||||
|
|
||||||
|
class SaleSchema(SaleBase):
|
||||||
|
id: UUID
|
||||||
|
created_at: datetime
|
||||||
|
updated_at: datetime
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
orm_mode = True
|
Loading…
x
Reference in New Issue
Block a user