File size: 10,820 Bytes
ed3b063
5564ecb
 
c506a3f
5564ecb
 
 
 
 
 
ed3b063
 
5564ecb
 
 
 
 
 
 
 
 
 
ed3b063
5564ecb
 
 
 
 
 
 
 
 
 
 
 
ed3b063
b0f3d0e
1f8c0c2
 
 
 
 
 
 
 
835d9e6
5564ecb
 
835d9e6
1f8c0c2
 
835d9e6
bfc5496
b0f3d0e
 
835d9e6
5564ecb
ed3b063
5564ecb
 
 
 
 
 
 
d34755d
5564ecb
c506a3f
5564ecb
 
 
c506a3f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e86e66c
 
 
 
 
 
74d5e02
e86e66c
 
 
c506a3f
52802de
c506a3f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52802de
c506a3f
 
 
 
 
 
5cc7ddc
c506a3f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52802de
c506a3f
 
 
 
 
 
 
 
 
 
 
 
 
5564ecb
c506a3f
 
 
 
 
 
 
 
6d51aee
9d6412a
0461c2d
84806e0
 
 
 
 
 
 
0461c2d
 
 
9d6412a
0461c2d
9d6412a
0461c2d
835d9e6
 
dee5bff
835d9e6
 
 
 
 
 
 
 
 
 
 
 
 
dee5bff
835d9e6
 
 
 
 
 
 
 
 
 
 
 
 
dee5bff
835d9e6
 
 
 
 
 
 
 
 
 
0461c2d
 
835d9e6
dee5bff
0461c2d
 
 
 
 
 
 
 
 
 
c506a3f
0461c2d
835d9e6
0461c2d
 
 
 
 
 
 
 
 
 
 
c506a3f
5564ecb
 
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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
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_one_way(origin_code: str = None, from_id: int = None, orign_ids: int = None, dest_code: str = None, to_id: str = None, dest_ids: str = None):
        params = {k: v for k, v in {
                    "OriginCode": origin_code,
                    "FromId": from_id,
                    "OriginIds": orign_ids,
                    "DestCode": dest_code,
                    "ToId": to_id,
                    "DestIds": dest_ids
                }.items() if v is not None}
        response = await api.get(f'/metadata/office/routes' , params=params)
        route_ids = []
        if isinstance(response, list):
                route_ids = [route.get("routeId", None) for route in response]
                return route_ids
        return []
    
    async def search_all_route_ids(self, origin_code: str = None, from_id: int = None, orign_ids: int = None, dest_code: str = None, to_id: str = None, dest_ids: str = None):
        route_ids_origin_dest = await self.search_route_ids_one_way(origin_code, from_id, orign_ids, dest_code, to_id, dest_ids)
        route_ids_dest_origin = await self.search_route_ids_one_way(dest_code, to_id, dest_ids, origin_code, from_id, orign_ids)
        route_ids = list(set(route_ids_origin_dest + route_ids_dest_origin))
        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")

    @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 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'] == 0 :
                return True
        return False

    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:
                    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
    @staticmethod
    async def search_pickup_points(origin: str = None, dest: str = None) -> dict:
        session_id = str(int(datetime.now().timestamp()))
        params =    {k: v for k, v in {
                    "origin": origin,
                    "dest": dest,
                    "session_id": session_id,
                    }.items() if v is not None
                }
        
        response = await api.get('search/metadata/pickup-points', params=params)
        if response.get("status") == 200:
            data = response.get("data")
            print(data)
            return data
        return {}
    
    async def find_id_office_by_name_office(self, office_name: str):
        data = await self.search_pickup_points(origin=office_name)
        if data.get("origin"):
            origins = data["origin"]
            for origin in origins:
                if origin.get("group"):
                    groups = origin["group"]
                    for group in groups:
                        if group.get("name"):
                            name = group["name"]
                            if name == office_name:
                                return group["officeId"]
        return None
    
    async def find_id_provine_by_name_office(self, office_name: str):
        data = await self.search_pickup_points(origin=office_name)
        if data.get("origin"):
            origins = data["origin"]
            for origin in origins:
                if origin.get("group"):
                    groups = origin["group"]
                    for group in groups:
                        if group.get("name"):
                            name = group["name"]
                            if name == office_name:
                                return group["provinceId"]
        return None

    async def find_id_and_code_provine_by_name_office(self, office_name: str):
        data = await self.search_pickup_points(origin=office_name)
        if data.get("origin"):
            origins = data["origin"]
            for origin in origins:
                if origin.get("group"):
                    groups = origin["group"]
                    for group in groups:
                        if group.get("name"):
                            name = group["name"]
                            if name == office_name:
                                return group["provinceId"], group["provinceCode"]
        return None
    
    async def get_origin_city_from_office(self, origin_office: str):
        data = await self.search_pickup_points(origin=origin_office)
        if data.get("origin"):
            origins = data["origin"]
            for origin in origins:
                if origin.get("group"):
                    groups = origin["group"]
                    for group in groups:
                        if group.get("name"):
                            name = group["name"]
                            if name == origin_office:
                                return group["provinceName"]
        return None

    async def get_destination_city_from_office(self, dest_office: str):
        data = await self.search_pickup_points(dest=dest_office)
        if data.get("dest"):
            dests = data["dest"]
            for dest in dests:
                if dest.get("group"):
                    groups = dest["group"]
                    for group in groups:
                        if group.get("name"):
                            name = group["name"]
                            if name == dest_office:
                                return group["provinceName"]
        return None

dialog_service: DialogService = DialogService()