|
from fastapi import APIRouter, Depends, HTTPException, status |
|
from sqlalchemy.orm import Session |
|
from typing import List |
|
from datetime import datetime, timezone |
|
|
|
from ..database import get_db, LoyaltyProgram as LoyaltyProgramModel |
|
from ..models.loyalty import LoyaltyProgram, LoyaltyProgramCreate, LoyaltyProgramUpdate |
|
|
|
router = APIRouter( |
|
prefix="/loyalty", |
|
tags=["loyalty"], |
|
responses={404: {"description": "Not found"}}, |
|
) |
|
|
|
|
|
|
|
@router.get("/", response_model=List[LoyaltyProgram]) |
|
def get_all_loyalty_tiers(db: Session = Depends(get_db)): |
|
return db.query(LoyaltyProgramModel).order_by(LoyaltyProgramModel.visit_count).all() |
|
|
|
|
|
|
|
@router.get("/active", response_model=List[LoyaltyProgram]) |
|
def get_active_loyalty_tiers(db: Session = Depends(get_db)): |
|
return ( |
|
db.query(LoyaltyProgramModel) |
|
.filter(LoyaltyProgramModel.is_active == True) |
|
.order_by(LoyaltyProgramModel.visit_count) |
|
.all() |
|
) |
|
|
|
|
|
|
|
@router.get("/{tier_id}", response_model=LoyaltyProgram) |
|
def get_loyalty_tier(tier_id: int, db: Session = Depends(get_db)): |
|
db_tier = ( |
|
db.query(LoyaltyProgramModel).filter(LoyaltyProgramModel.id == tier_id).first() |
|
) |
|
if not db_tier: |
|
raise HTTPException(status_code=404, detail="Loyalty tier not found") |
|
return db_tier |
|
|
|
|
|
|
|
@router.post("/", response_model=LoyaltyProgram) |
|
def create_loyalty_tier(tier: LoyaltyProgramCreate, db: Session = Depends(get_db)): |
|
|
|
existing_tier = ( |
|
db.query(LoyaltyProgramModel) |
|
.filter(LoyaltyProgramModel.visit_count == tier.visit_count) |
|
.first() |
|
) |
|
if existing_tier: |
|
raise HTTPException( |
|
status_code=400, |
|
detail=f"Loyalty tier with visit count {tier.visit_count} already exists", |
|
) |
|
|
|
|
|
db_tier = LoyaltyProgramModel( |
|
visit_count=tier.visit_count, |
|
discount_percentage=tier.discount_percentage, |
|
is_active=tier.is_active, |
|
created_at=datetime.now(timezone.utc), |
|
updated_at=datetime.now(timezone.utc), |
|
) |
|
db.add(db_tier) |
|
db.commit() |
|
db.refresh(db_tier) |
|
return db_tier |
|
|
|
|
|
|
|
@router.put("/{tier_id}", response_model=LoyaltyProgram) |
|
def update_loyalty_tier( |
|
tier_id: int, tier_update: LoyaltyProgramUpdate, db: Session = Depends(get_db) |
|
): |
|
db_tier = ( |
|
db.query(LoyaltyProgramModel).filter(LoyaltyProgramModel.id == tier_id).first() |
|
) |
|
if not db_tier: |
|
raise HTTPException(status_code=404, detail="Loyalty tier not found") |
|
|
|
|
|
if ( |
|
tier_update.visit_count is not None |
|
and tier_update.visit_count != db_tier.visit_count |
|
): |
|
existing_tier = ( |
|
db.query(LoyaltyProgramModel) |
|
.filter( |
|
LoyaltyProgramModel.visit_count == tier_update.visit_count, |
|
LoyaltyProgramModel.id != tier_id, |
|
) |
|
.first() |
|
) |
|
if existing_tier: |
|
raise HTTPException( |
|
status_code=400, |
|
detail=f"Loyalty tier with visit count {tier_update.visit_count} already exists", |
|
) |
|
db_tier.visit_count = tier_update.visit_count |
|
|
|
|
|
if tier_update.discount_percentage is not None: |
|
db_tier.discount_percentage = tier_update.discount_percentage |
|
if tier_update.is_active is not None: |
|
db_tier.is_active = tier_update.is_active |
|
|
|
db_tier.updated_at = datetime.now(timezone.utc) |
|
db.commit() |
|
db.refresh(db_tier) |
|
return db_tier |
|
|
|
|
|
|
|
@router.delete("/{tier_id}") |
|
def delete_loyalty_tier(tier_id: int, db: Session = Depends(get_db)): |
|
db_tier = ( |
|
db.query(LoyaltyProgramModel).filter(LoyaltyProgramModel.id == tier_id).first() |
|
) |
|
if not db_tier: |
|
raise HTTPException(status_code=404, detail="Loyalty tier not found") |
|
|
|
db.delete(db_tier) |
|
db.commit() |
|
return {"message": "Loyalty tier deleted successfully"} |
|
|
|
|
|
|
|
@router.get("/discount/{visit_count}") |
|
def get_discount_for_visit_count(visit_count: int, db: Session = Depends(get_db)): |
|
|
|
applicable_tier = ( |
|
db.query(LoyaltyProgramModel) |
|
.filter( |
|
LoyaltyProgramModel.visit_count == visit_count, |
|
LoyaltyProgramModel.is_active == True, |
|
) |
|
.first() |
|
) |
|
|
|
if not applicable_tier: |
|
return {"discount_percentage": 0, "message": "No applicable loyalty discount"} |
|
|
|
return { |
|
"discount_percentage": applicable_tier.discount_percentage, |
|
"tier_id": applicable_tier.id, |
|
"visit_count": applicable_tier.visit_count, |
|
"message": f"Loyalty discount of {applicable_tier.discount_percentage}% applied for {visit_count} visits", |
|
} |
|
|