from datetime import datetime, timedelta from common.external.external_api import api from core.conf import settings class DialogService: @staticmethod def to_datetime_from_Dialogflow(time: dict): date_time = datetime(int(time["year"]), int(time["month"]), int(time["day"])) return date_time @staticmethod def process_dates_to_timestamp(from_time: datetime = None, to_time: datetime = None): if to_time is None and from_time is not None: to_time = from_time.replace(hour=23, minute=59, second=59) if from_time is None: today = datetime.today().date() from_time = datetime.combine(today, datetime.min.time()) to_time = datetime.combine(today, datetime.max.time()) - timedelta(microseconds=1) return int(from_time.timestamp()) * 1000 , int(to_time.timestamp()) * 1000 def get_param_from_dialogflow(self, body: any): session_info = body.get("sessionInfo", {}) parameters = session_info.get("parameters", {}) if isinstance(session_info.get("parameters"), dict) else {} raw_date = parameters.get("date") if raw_date is not None: raw_date = self.to_datetime_from_Dialogflow(raw_date) raw_departure_city = parameters.get("departure_city") raw_destination_city = parameters.get("destination_city") raw_ticket_number = parameters.get("ticket_number") raw_time_of_day = parameters.get("time_of_day") return raw_departure_city, raw_destination_city, raw_ticket_number, raw_date, raw_time_of_day @staticmethod async def search_route_ids_from_province(departure_code: str, destination_code: str): response = await api.get(f'/metadata/office/routes?DestCode={destination_code}&OriginCode={departure_code}') route_ids = [] if isinstance(response, list): route_ids = [route.get("routeId", -1) for route in response] return route_ids @staticmethod async def seats_trip(route_id: int, trip_id:int, departure_date: str, departure_time: str, kind: str): try: params = { "departureDate": departure_date, "departureTime": departure_time, "kind": kind, } response = await api.get(api_base=settings.API_BASE_URL_VATO, endpoint=f"/seats/{route_id}/{trip_id}" , params=params) seats = response["data"] return seats except Exception as e: print(e) raise Exception("Error fetching seats data") async def is_valid_select_seat(self, seat: str,route_id: int, trip_id:int, departure_date: str, departure_time: str, kind: str): if seat is None: return False seats = await self.seats_trip(route_id, trip_id, departure_date, departure_time, kind) for seat_data in seats: if seat_data['chair'] == seat and seat_data['bookStatus'] == 'available': return True return False @staticmethod async def search_trip(from_time: int, to_time: int, route_ids: list[int], ticket_count: int = 1): try: payload = { "from_time": from_time, "to_time": to_time, "route_ids": route_ids, "ticket_count": ticket_count, "sort_by": ["price", "departure_time"] } response = await api.post("/search/trips", payload=payload) data = response["data"]["items"] return data except Exception as e: print(e) raise Exception("Error fetching trip data") async def search_trip_by_id(self, trip_id: int, from_time: int, to_time: int, route_ids: list[int], ticket_count: int = 1): trip = await self.search_trip(from_time, to_time, route_ids, ticket_count) for item in trip: if trip_id == item["id"]: return item return None @staticmethod async def stops(route_id: int, way_id: int): try: params = { "wayId": way_id, } response = await api.get(api_base=settings.API_BASE_URL_VATO, endpoint=f"/stops/{route_id}", params=params) data = response["data"] return data except Exception as e: print(e) raise Exception("Error fetching stops data") async def pickup_list(self, route_id: int, way_id: int): try: data = await self.stops(route_id, way_id) if not data: return [] pickup_list = [] for pickup in data: if pickup["type"] == 0 or ( pickup["type"] == -1 and pickup["presentBeforeMinutes"] < 0 ): pickup_list.append(pickup) return pickup_list except Exception as e: print(e) raise Exception("Error fetching pickup list data") async def is_valid_pickup(self, pickup: str, route_id: int, way_id: int): if pickup is None: return False pickup_list = await self.pickup_list(route_id, way_id) for pickup_data in pickup_list: if pickup_data['name'] == pickup: return True return False async def dropoff_list(self, route_id: int, way_id: int): try: data = await self.stops(route_id, way_id) if not data: return [] dropoff_list = [] for dropoff in data: if dropoff["type"] == 1 or ( dropoff["type"] == -1 and dropoff["presentBeforeMinutes"] >= 0 ): dropoff_list.append(dropoff) return dropoff_list except Exception as e: print(e) raise Exception("Error fetching dropoff list data") async def is_valid_dropoff(self, dropoff: str, route_id: int, way_id: int): if dropoff is None: return False dropoff_list = await self.dropoff_list(route_id, way_id) for dropoff_data in dropoff_list: if dropoff_data['name'] == dropoff: return True return False dialog_service: DialogService = DialogService()