File size: 5,381 Bytes
80feb1b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
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, SelectionOffer as SelectionOfferModel
from ..models.selection_offer import (
    SelectionOffer,
    SelectionOfferCreate,
    SelectionOfferUpdate,
)

router = APIRouter(
    prefix="/selection-offers",
    tags=["selection-offers"],
    responses={404: {"description": "Not found"}},
)


# Get all selection offers
@router.get("/", response_model=List[SelectionOffer])
def get_all_selection_offers(db: Session = Depends(get_db)):
    return db.query(SelectionOfferModel).order_by(SelectionOfferModel.min_amount).all()


# Get active selection offers
@router.get("/active", response_model=List[SelectionOffer])
def get_active_selection_offers(db: Session = Depends(get_db)):
    return (
        db.query(SelectionOfferModel)
        .filter(SelectionOfferModel.is_active == True)
        .order_by(SelectionOfferModel.min_amount)
        .all()
    )


# Get selection offer by ID
@router.get("/{offer_id}", response_model=SelectionOffer)
def get_selection_offer(offer_id: int, db: Session = Depends(get_db)):
    db_offer = (
        db.query(SelectionOfferModel).filter(SelectionOfferModel.id == offer_id).first()
    )
    if not db_offer:
        raise HTTPException(status_code=404, detail="Selection offer not found")
    return db_offer


# Create new selection offer
@router.post("/", response_model=SelectionOffer)
def create_selection_offer(offer: SelectionOfferCreate, db: Session = Depends(get_db)):
    # Check if an offer with this min_amount already exists
    existing_offer = (
        db.query(SelectionOfferModel)
        .filter(SelectionOfferModel.min_amount == offer.min_amount)
        .first()
    )
    if existing_offer:
        raise HTTPException(
            status_code=400,
            detail=f"Selection offer with minimum amount {offer.min_amount} already exists",
        )

    # Create new offer
    db_offer = SelectionOfferModel(
        min_amount=offer.min_amount,
        discount_amount=offer.discount_amount,
        is_active=offer.is_active,
        description=offer.description,
        created_at=datetime.now(timezone.utc),
        updated_at=datetime.now(timezone.utc),
    )
    db.add(db_offer)
    db.commit()
    db.refresh(db_offer)
    return db_offer


# Update selection offer
@router.put("/{offer_id}", response_model=SelectionOffer)
def update_selection_offer(
    offer_id: int, offer_update: SelectionOfferUpdate, db: Session = Depends(get_db)
):
    db_offer = (
        db.query(SelectionOfferModel).filter(SelectionOfferModel.id == offer_id).first()
    )
    if not db_offer:
        raise HTTPException(status_code=404, detail="Selection offer not found")

    # Check if updating min_amount and if it already exists
    if (
        offer_update.min_amount is not None
        and offer_update.min_amount != db_offer.min_amount
    ):
        existing_offer = (
            db.query(SelectionOfferModel)
            .filter(
                SelectionOfferModel.min_amount == offer_update.min_amount,
                SelectionOfferModel.id != offer_id,
            )
            .first()
        )
        if existing_offer:
            raise HTTPException(
                status_code=400,
                detail=f"Selection offer with minimum amount {offer_update.min_amount} already exists",
            )
        db_offer.min_amount = offer_update.min_amount

    # Update other fields if provided
    if offer_update.discount_amount is not None:
        db_offer.discount_amount = offer_update.discount_amount
    if offer_update.is_active is not None:
        db_offer.is_active = offer_update.is_active
    if offer_update.description is not None:
        db_offer.description = offer_update.description

    db_offer.updated_at = datetime.now(timezone.utc)
    db.commit()
    db.refresh(db_offer)
    return db_offer


# Delete selection offer
@router.delete("/{offer_id}")
def delete_selection_offer(offer_id: int, db: Session = Depends(get_db)):
    db_offer = (
        db.query(SelectionOfferModel).filter(SelectionOfferModel.id == offer_id).first()
    )
    if not db_offer:
        raise HTTPException(status_code=404, detail="Selection offer not found")

    db.delete(db_offer)
    db.commit()
    return {"message": "Selection offer deleted successfully"}


# Get applicable discount for an order amount
@router.get("/discount/{order_amount}")
def get_discount_for_order_amount(order_amount: float, db: Session = Depends(get_db)):
    # Find the highest tier that the order amount qualifies for
    applicable_offer = (
        db.query(SelectionOfferModel)
        .filter(
            SelectionOfferModel.min_amount <= order_amount,
            SelectionOfferModel.is_active == True,
        )
        .order_by(SelectionOfferModel.min_amount.desc())
        .first()
    )

    if not applicable_offer:
        return {
            "discount_amount": 0,
            "message": "No applicable selection offer discount",
        }

    return {
        "discount_amount": applicable_offer.discount_amount,
        "offer_id": applicable_offer.id,
        "min_amount": applicable_offer.min_amount,
        "message": f"Selection offer discount of ${applicable_offer.discount_amount} applied",
    }