File size: 6,836 Bytes
90537f3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
from fastapi import APIRouter, Depends, HTTPException, status, Request
from sqlalchemy.orm import Session
from typing import List
from datetime import datetime, timezone

from ..database import get_db, SelectionOffer as SelectionOfferModel, get_session_db, get_hotel_id_from_request
from ..models.selection_offer import (
    SelectionOffer,
    SelectionOfferCreate,
    SelectionOfferUpdate,
)
from ..middleware import get_session_id

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


# Dependency to get session-aware database
def get_session_database(request: Request):
    session_id = get_session_id(request)
    return next(get_session_db(session_id))


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


# Get active selection offers
@router.get("/active", response_model=List[SelectionOffer])
def get_active_selection_offers(request: Request, db: Session = Depends(get_session_database)):
    hotel_id = get_hotel_id_from_request(request)
    return (
        db.query(SelectionOfferModel)
        .filter(
            SelectionOfferModel.hotel_id == hotel_id,
            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, request: Request, db: Session = Depends(get_session_database)):
    hotel_id = get_hotel_id_from_request(request)
    db_offer = (
        db.query(SelectionOfferModel).filter(
            SelectionOfferModel.hotel_id == hotel_id,
            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, request: Request, db: Session = Depends(get_session_database)):
    hotel_id = get_hotel_id_from_request(request)

    # Check if an offer with this min_amount already exists for this hotel
    existing_offer = (
        db.query(SelectionOfferModel)
        .filter(
            SelectionOfferModel.hotel_id == hotel_id,
            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(
        hotel_id=hotel_id,
        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, request: Request, db: Session = Depends(get_session_database)
):
    hotel_id = get_hotel_id_from_request(request)

    db_offer = (
        db.query(SelectionOfferModel).filter(
            SelectionOfferModel.hotel_id == hotel_id,
            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 for this hotel
    if (
        offer_update.min_amount is not None
        and offer_update.min_amount != db_offer.min_amount
    ):
        existing_offer = (
            db.query(SelectionOfferModel)
            .filter(
                SelectionOfferModel.hotel_id == hotel_id,
                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, request: Request, db: Session = Depends(get_session_database)):
    hotel_id = get_hotel_id_from_request(request)

    db_offer = (
        db.query(SelectionOfferModel).filter(
            SelectionOfferModel.hotel_id == hotel_id,
            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, request: Request, db: Session = Depends(get_session_database)):
    hotel_id = get_hotel_id_from_request(request)

    # Find the highest tier that the order amount qualifies for this hotel
    applicable_offer = (
        db.query(SelectionOfferModel)
        .filter(
            SelectionOfferModel.hotel_id == hotel_id,
            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",
    }