OnlyBiggg commited on
Commit
69e4506
·
1 Parent(s): 5dcf888
app/dialogflow/api/v1/dialogflow.py CHANGED
@@ -266,6 +266,119 @@ async def price(request: Request):
266
  except:
267
  return DialogFlowResponseAPI(text=["Hệ thống xảy ra lỗi. Quý khách vui lòng thử lại sau hoặc liên hệ Trung tâm tổng đài 1900 6067 để được hỗ trợ."])
268
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
 
270
  @router.post('/trip/route/list')
271
  async def booking_trip(request: Request) -> Response:
@@ -365,30 +478,29 @@ async def booking_trip(request: Request) -> Response:
365
  }
366
  )
367
 
368
- @router.post('/trip/route/check-route-select')
369
  async def is_valid_select_trip(request: Request) -> Response:
370
  body = await request.json()
371
  raw_input = body.get("text", "")
372
  session_info = body.get("sessionInfo", {})
373
  parameters = session_info.get("parameters")
374
- routes_name = parameters.get("routes_name")
 
 
 
 
 
375
  if raw_input:
376
  raw_input = raw_input.strip()
377
- if raw_input in routes_name:
378
- trip_list: List[Dict[str, any]] = parameters.get("trip_list")
379
- for trip in trip_list:
380
- if trip["route_name"] == raw_input:
381
- route_id = int(trip["route_id"])
382
- kind = trip["kind"]
383
- way_id = trip["way_id"]
384
  break
385
 
386
  parameters = {
387
  "is_valid_trip": True,
388
- "route_name": raw_input,
389
- "kind": kind,
390
- "route_id": route_id,
391
- "way_id": way_id,
392
  }
393
  else:
394
  parameters = {
@@ -620,13 +732,13 @@ async def seats_trip(request: Request) -> Response:
620
  parameters = session_info.get("parameters")
621
 
622
  trip = parameters.get("trip", None)
623
- route_id: int = parameters.get("route_id", None)
624
- route_id = int(route_id) if route_id else None
625
- departure_date: str = parameters.get("departure_date", None)
626
- departure_time: str = parameters.get("departure_time", None)
627
- kind: str = parameters.get("kind", None)
 
628
 
629
- trip_id = int(trip["id"]) if trip else None
630
  seats = await dialog_service.seats_trip(route_id, trip_id, departure_date, departure_time, kind)
631
  seats_empty = [ seat for seat in seats if seat["bookStatus"] == 0 ]
632
  seats_empty.sort(key=lambda x: x["chair"])
@@ -657,15 +769,19 @@ async def is_valid_select_seat(request: Request) -> Response:
657
  session_info = body.get("sessionInfo", {})
658
  parameters = session_info.get("parameters")
659
 
660
- trip = parameters.get("trip", None)
661
- route_id: int = parameters.get("route_id", None)
662
- route_id = int(route_id) if route_id else None
663
- departure_date: str = parameters.get("departure_date", None)
664
- departure_time: str = parameters.get("departure_time", None)
665
- kind: str = parameters.get("kind", None)
666
- seat: str = parameters.get("seat", None)
667
-
668
- trip_id = int(trip["id"]) if trip else None
 
 
 
 
669
 
670
  is_valid = await dialog_service.is_valid_select_seat(seat, route_id, trip_id, departure_date, departure_time, kind)
671
  if is_valid:
@@ -679,7 +795,7 @@ async def is_valid_select_seat(request: Request) -> Response:
679
  "is_valid_seat": False,
680
  "seat": None
681
  }
682
- text = [f"Ghế **{seat}** đã được đặt. Quý khách vui lòng chọn ghế khác"]
683
  return DialogFlowResponseAPI(text=text, parameters=parameters)
684
 
685
  except Exception as e:
@@ -690,11 +806,13 @@ async def pickup(request: Request) -> Response:
690
  body = await request.json()
691
  session_info = body.get("sessionInfo", {})
692
  parameters = session_info.get("parameters")
693
- trip: dict[str, any] = parameters.get("trip", None)
694
- route_id: int = trip["route_id"]
695
- route_id = int(route_id) if route_id else None
696
- way_id: int = trip["way_id"]
697
- way_id = int(way_id) if way_id else None
 
 
698
  pickup_list = await dialog_service.pickup_list(route_id, way_id)
699
 
700
  text=["Quý khách vui lòng chọn điểm đón"]
@@ -721,11 +839,13 @@ async def is_valid_select_pickup(request: Request) -> Response:
721
  body = await request.json()
722
  session_info = body.get("sessionInfo", {})
723
  parameters = session_info.get("parameters")
724
- trip = parameters.get("trip", None)
725
- route_id: int = trip["route_id"]
726
- route_id = int(route_id) if route_id else None
727
- way_id: int = trip["way_id"]
728
- way_id = int(way_id) if way_id else None
 
 
729
  raw_input = (body.get("text",""))
730
  pickup = raw_input.strip()
731
 
@@ -750,11 +870,13 @@ async def dropoff(request: Request) -> Response:
750
  body = await request.json()
751
  session_info = body.get("sessionInfo", {})
752
  parameters = session_info.get("parameters")
753
- trip = parameters.get("trip", None)
754
- route_id: int = trip["route_id"]
755
- route_id = int(route_id) if route_id else None
756
- way_id: int = trip["way_id"]
757
- way_id = int(way_id) if way_id else None
 
 
758
  dropoff_list = await dialog_service.dropoff_list(route_id, way_id)
759
 
760
  text=["Quý khách vui lòng chọn điểm trả khách"]
@@ -781,11 +903,13 @@ async def is_valid_select_dropoff(request: Request) -> Response:
781
  body = await request.json()
782
  session_info = body.get("sessionInfo", {})
783
  parameters = session_info.get("parameters")
784
- trip = parameters.get("trip", None)
785
- route_id: int = trip["route_id"]
786
- route_id = int(route_id) if route_id else None
787
- way_id: int = trip["way_id"]
788
- way_id = int(way_id) if way_id else None
 
 
789
  raw_input = (body.get("text",""))
790
  dropoff = raw_input.strip()
791
 
@@ -805,26 +929,33 @@ async def is_valid_select_dropoff(request: Request) -> Response:
805
 
806
  return DialogFlowResponseAPI(text=text, parameters=parameters)
807
 
808
- @router.post('/trip/ticket/info')
809
  async def response_ticket_info(request: Request) -> Response:
810
  body = await request.json()
811
  session_info = body.get("sessionInfo", {})
812
  parameters = session_info.get("parameters")
813
 
814
- user_name = parameters.get("user_name", None)
815
- phone_number = parameters.get("phone_number", None)
816
- email = parameters.get("email", None)
817
- seat = parameters.get("seat", None)
818
- pickup = parameters.get("pick_up", None)
819
- dropoff = parameters.get("drop_off", None)
 
 
 
 
 
820
 
821
- trip = parameters.get("trip", None)
822
 
823
  route_name = trip["route"]["name"]
 
824
  time = trip["raw_departure_time"]
 
825
  date = trip["raw_departure_date"]
826
- price = trip["price"]
827
- price = int(price) if price else None
828
 
829
  text = [
830
  f" \
 
266
  except:
267
  return DialogFlowResponseAPI(text=["Hệ thống xảy ra lỗi. Quý khách vui lòng thử lại sau hoặc liên hệ Trung tâm tổng đài 1900 6067 để được hỗ trợ."])
268
 
269
+ @router.post('/trip/list')
270
+ async def get_trip_list(request: Request) -> Response:
271
+ body = await request.json()
272
+ session_info = body.get("sessionInfo", {})
273
+ parameters = session_info.get("parameters")
274
+
275
+ raw_departure_city, raw_destination_city, raw_ticket_number, raw_date, _ = dialog_service.get_param_from_dialogflow(body)
276
+
277
+ origin_office = parameters.get("origin_office")
278
+ dest_office = parameters.get("dest_office")
279
+ time = parameters.get("time-select")
280
+
281
+ time = extra_time_dialogflow(time)
282
+
283
+ if isinstance(time, list):
284
+ parameters = {
285
+ "is_time_ambiguous": True
286
+ }
287
+ return DialogFlowResponseAPI(parameters=parameters)
288
+
289
+ from_time, to_time = dialog_service.process_dates_to_timestamp(raw_date)
290
+
291
+ ticket_count = int(raw_ticket_number) if raw_ticket_number else 1
292
+
293
+ origin_code, origin_id, origin_ids, dest_code, dest_id, dest_ids = None, None, None, None, None, None
294
+ if origin_office:
295
+ origin_id, origin_code = await dialog_service.find_id_and_code_provine_by_name_office(origin_office)
296
+ origin_ids = await dialog_service.find_id_office_by_name_office(origin_office)
297
+ elif raw_departure_city:
298
+ origin_id, origin_code = get_origin_id_and_code(raw_departure_city)
299
+ if dest_office:
300
+ dest_id, dest_code = await dialog_service.find_id_and_code_provine_by_name_office(dest_office)
301
+ dest_ids = await dialog_service.find_id_office_by_name_office(dest_office)
302
+ elif raw_destination_city:
303
+ dest_id, dest_code = get_origin_id_and_code(raw_destination_city)
304
+ route_ids = await dialog_service.search_all_route_ids(origin_code=origin_code, from_id=origin_id, orign_ids=origin_ids, dest_code=dest_code, to_id=dest_id, dest_ids=dest_ids)
305
+
306
+
307
+
308
+ try:
309
+ data = await dialog_service.search_trip(from_time, to_time, route_ids, ticket_count)
310
+ if len(data) > 0:
311
+ trip_by_time_office = dialog_service.get_trip_by_time_and_office_id(data, time, origin_id, dest_id)
312
+
313
+ # Nếu có chuyến xe theo thời gian và văn phòng chỉ định
314
+ if trip_by_time_office:
315
+ parameters = {
316
+ "is_valid_trip": True,
317
+ }
318
+ return DialogFlowResponseAPI(parameters=parameters)
319
+
320
+ # Danh sách chuyến xe khớp với văn phòng đón hoặc văn phòng trả
321
+ data_by_office = dialog_service.get_all_trip_by_office(data, origin_id, dest_id)
322
+ # Tìm 4 chuyến xe gần thời gian chỉ định nhất
323
+ trip_surrounding_time = dialog_service.get_4_surrounding_trip(data_by_office, time, origin_id, dest_id)
324
+
325
+ trips = []
326
+ trip_dialogflow = []
327
+
328
+ for trip in trip_surrounding_time:
329
+ if ticket_count <= trip["empty_seat_quantity"]:
330
+ trip_dialogflow.append({"trip_id": trip["id"], "route":f"{trip["raw_departure_time"]} | {trip['route']['origin_hub_name']} => {trip['route']['dest_hub_name']}"})
331
+ text = ["Quý khách vui lòng lựa chọn chuyến xe\n" + "\n".join(f"{i+1}. {trip["route"]}" for i, trip in enumerate(trip_dialogflow))]
332
+ payload={
333
+ "richContent": [
334
+ [
335
+ {
336
+ "type": "chips",
337
+ "options": [
338
+ {"text": trip["route"]} for trip in (trip_dialogflow)
339
+ ]
340
+ }
341
+ ]
342
+ ]
343
+ }
344
+ parameters = {
345
+ "trip_select": trip_dialogflow,
346
+ "trips": trips,
347
+ }
348
+ return DialogFlowResponseAPI(text=text, payload=payload,parameters=parameters)
349
+
350
+ text = [f"Hệ thống không tìm thấy tuyến xe **{raw_departure_city}** - **{raw_destination_city}**.\n Quý khách vui lòng thử lại với lộ trình khác hoặc liên hệ Trung tâm tổng đài 1900 6067 để được hỗ trợ."]
351
+ payload={
352
+ "richContent": [
353
+ [
354
+ {
355
+ "type": "chips",
356
+ "options": [
357
+ {"text": "Xem tuyến xe khác"},
358
+ {"text": "Không, cảm ơn"}
359
+ ]
360
+ }
361
+ ]
362
+ ]
363
+ }
364
+
365
+ return DialogFlowResponseAPI(text=text, payload=payload)
366
+ except Exception as e:
367
+ print(e)
368
+ return JSONResponse(
369
+ {
370
+ "fulfillment_response": {
371
+ "messages": [
372
+ {
373
+ "text": {
374
+ "text": ["Hệ thống xảy ra lỗi. Quý khách vui lòng thử lại sau hoặc liên hệ Trung tâm tổng đài 1900 6067 để được hỗ trợ."]
375
+ }
376
+ }
377
+ ]
378
+ },
379
+ }
380
+ )
381
+
382
 
383
  @router.post('/trip/route/list')
384
  async def booking_trip(request: Request) -> Response:
 
478
  }
479
  )
480
 
481
+ @router.post('/trip/check-trip')
482
  async def is_valid_select_trip(request: Request) -> Response:
483
  body = await request.json()
484
  raw_input = body.get("text", "")
485
  session_info = body.get("sessionInfo", {})
486
  parameters = session_info.get("parameters")
487
+ trip_select: list[dict[str, any]] = parameters.get("trip_select")
488
+ trips: list[dict[str, any]] = parameters.get("trip")
489
+
490
+ if trip_select is None and trips is None:
491
+ return DialogFlowResponseAPI()
492
+
493
  if raw_input:
494
  raw_input = raw_input.strip()
495
+ if raw_input in trip_select:
496
+ for item in trips:
497
+ if item["route"] == raw_input:
498
+ trip = item
 
 
 
499
  break
500
 
501
  parameters = {
502
  "is_valid_trip": True,
503
+ "trip": trip
 
 
 
504
  }
505
  else:
506
  parameters = {
 
732
  parameters = session_info.get("parameters")
733
 
734
  trip = parameters.get("trip", None)
735
+ route_id = int(trip.get("route_id")) if trip.get("route_id") else None
736
+ trip_id = int(trip.get("id")) if trip.get("id") else None
737
+
738
+ departure_date: str = trip.get("raw_departure_time")
739
+ departure_time: str = trip.get("raw_departure_date")
740
+ kind: str = trip.get("seat_type_name")
741
 
 
742
  seats = await dialog_service.seats_trip(route_id, trip_id, departure_date, departure_time, kind)
743
  seats_empty = [ seat for seat in seats if seat["bookStatus"] == 0 ]
744
  seats_empty.sort(key=lambda x: x["chair"])
 
769
  session_info = body.get("sessionInfo", {})
770
  parameters = session_info.get("parameters")
771
 
772
+ trip: list[dict[str, any]] = parameters.get("trip", None)
773
+
774
+ route_id = int(trip.get("route_id")) if trip.get("route_id") else None
775
+
776
+ trip_id = int(trip.get("id")) if trip.get("id") else None
777
+
778
+ departure_date: str = trip.get("raw_departure_time")
779
+
780
+ departure_time: str = trip.get("raw_departure_date")
781
+
782
+ kind: str = trip.get("seat_type_name")
783
+
784
+ seat: str = parameters.get("seat")
785
 
786
  is_valid = await dialog_service.is_valid_select_seat(seat, route_id, trip_id, departure_date, departure_time, kind)
787
  if is_valid:
 
795
  "is_valid_seat": False,
796
  "seat": None
797
  }
798
+ text = [f"Ghế **{seat}** không hợp lệ. Quý khách vui lòng chọn ghế khác"]
799
  return DialogFlowResponseAPI(text=text, parameters=parameters)
800
 
801
  except Exception as e:
 
806
  body = await request.json()
807
  session_info = body.get("sessionInfo", {})
808
  parameters = session_info.get("parameters")
809
+
810
+ trip: list[dict[str, any]] = parameters.get("trip", {})
811
+
812
+ route_id = int(trip.get("route_id")) if trip.get("route_id") else None
813
+
814
+ way_id = int(trip.get("way_id")) if trip.get("way_id") else None
815
+
816
  pickup_list = await dialog_service.pickup_list(route_id, way_id)
817
 
818
  text=["Quý khách vui lòng chọn điểm đón"]
 
839
  body = await request.json()
840
  session_info = body.get("sessionInfo", {})
841
  parameters = session_info.get("parameters")
842
+
843
+ trip: list[dict[str, any]] = parameters.get("trip", {})
844
+
845
+ route_id = int(trip.get("route_id")) if trip.get("route_id") else None
846
+
847
+ way_id = int(trip.get("way_id")) if trip.get("way_id") else None
848
+
849
  raw_input = (body.get("text",""))
850
  pickup = raw_input.strip()
851
 
 
870
  body = await request.json()
871
  session_info = body.get("sessionInfo", {})
872
  parameters = session_info.get("parameters")
873
+
874
+ trip: list[dict[str, any]] = parameters.get("trip", {})
875
+
876
+ route_id = int(trip.get("route_id")) if trip.get("route_id") else None
877
+
878
+ way_id = int(trip.get("way_id")) if trip.get("way_id") else None
879
+
880
  dropoff_list = await dialog_service.dropoff_list(route_id, way_id)
881
 
882
  text=["Quý khách vui lòng chọn điểm trả khách"]
 
903
  body = await request.json()
904
  session_info = body.get("sessionInfo", {})
905
  parameters = session_info.get("parameters")
906
+
907
+ trip: list[dict[str, any]] = parameters.get("trip", {})
908
+
909
+ route_id = int(trip.get("route_id")) if trip.get("route_id") else None
910
+
911
+ way_id = int(trip.get("way_id")) if trip.get("way_id") else None
912
+
913
  raw_input = (body.get("text",""))
914
  dropoff = raw_input.strip()
915
 
 
929
 
930
  return DialogFlowResponseAPI(text=text, parameters=parameters)
931
 
932
+ @router.post('/ticket/info')
933
  async def response_ticket_info(request: Request) -> Response:
934
  body = await request.json()
935
  session_info = body.get("sessionInfo", {})
936
  parameters = session_info.get("parameters")
937
 
938
+ user_name = parameters.get("user_name")
939
+
940
+ phone_number = parameters.get("phone_number")
941
+
942
+ email = parameters.get("email")
943
+
944
+ seat = parameters.get("seat")
945
+
946
+ pickup = parameters.get("pick_up")
947
+
948
+ dropoff = parameters.get("drop_off")
949
 
950
+ trip = parameters.get("trip", {})
951
 
952
  route_name = trip["route"]["name"]
953
+
954
  time = trip["raw_departure_time"]
955
+
956
  date = trip["raw_departure_date"]
957
+
958
+ price = int(trip.get("price")) if trip.get("price") else None
959
 
960
  text = [
961
  f" \
app/dialogflow/services/dialog_service.py CHANGED
@@ -1,3 +1,4 @@
 
1
  from datetime import datetime, timedelta
2
 
3
  from fastapi import logger
@@ -35,6 +36,7 @@ class DialogService:
35
  raw_time_of_day = parameters.get("time_of_day")
36
  return raw_departure_city, raw_destination_city, raw_ticket_number, raw_date, raw_time_of_day
37
 
 
38
  @staticmethod
39
  async def search_route_ids_one_way_by_metadata(origin_code: str = None, from_id: int = None, orign_ids: int = None, dest_code: str = None, to_id: str = None, dest_ids: str = None):
40
  params = {k: v for k, v in {
@@ -52,6 +54,7 @@ class DialogService:
52
  return route_ids
53
  return []
54
 
 
55
  @staticmethod
56
  async def search_route_ids_one_way_by_origin_dest_code(origin: str, dest: str):
57
  try:
@@ -71,6 +74,7 @@ class DialogService:
71
  if len(route_ids) == 0:
72
  route_ids = await self.search_route_ids_one_way_by_origin_dest_code(origin_code, dest_code)
73
  return route_ids
 
74
  @staticmethod
75
  async def seats_trip(route_id: int, trip_id:int, departure_date: str, departure_time: str, kind: str):
76
  try:
@@ -86,6 +90,7 @@ class DialogService:
86
  print(e)
87
  raise Exception("Error fetching seats data")
88
 
 
89
  @staticmethod
90
  async def search_trip(from_time: int, to_time: int, route_ids: list[int], ticket_count: int = 1):
91
  try:
@@ -112,6 +117,52 @@ class DialogService:
112
  except Exception as e:
113
  print(e)
114
  raise Exception("Error fetching trip data")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
 
116
  async def is_valid_select_seat(self, seat: str,route_id: int, trip_id:int, departure_date: str, departure_time: str, kind: str):
117
  if seat is None:
 
1
+ from bisect import bisect_left
2
  from datetime import datetime, timedelta
3
 
4
  from fastapi import logger
 
36
  raw_time_of_day = parameters.get("time_of_day")
37
  return raw_departure_city, raw_destination_city, raw_ticket_number, raw_date, raw_time_of_day
38
 
39
+ # Danh sách route_id API v1
40
  @staticmethod
41
  async def search_route_ids_one_way_by_metadata(origin_code: str = None, from_id: int = None, orign_ids: int = None, dest_code: str = None, to_id: str = None, dest_ids: str = None):
42
  params = {k: v for k, v in {
 
54
  return route_ids
55
  return []
56
 
57
+ # Danh sách route_id v2 khi API route v1 không có dữ liệu
58
  @staticmethod
59
  async def search_route_ids_one_way_by_origin_dest_code(origin: str, dest: str):
60
  try:
 
74
  if len(route_ids) == 0:
75
  route_ids = await self.search_route_ids_one_way_by_origin_dest_code(origin_code, dest_code)
76
  return route_ids
77
+ # Danh sách ghế
78
  @staticmethod
79
  async def seats_trip(route_id: int, trip_id:int, departure_date: str, departure_time: str, kind: str):
80
  try:
 
90
  print(e)
91
  raise Exception("Error fetching seats data")
92
 
93
+ # Call API để lấy danh sách chuyến đi
94
  @staticmethod
95
  async def search_trip(from_time: int, to_time: int, route_ids: list[int], ticket_count: int = 1):
96
  try:
 
117
  except Exception as e:
118
  print(e)
119
  raise Exception("Error fetching trip data")
120
+
121
+ # Chuyến đi khớp với thời gian và văn phòng đón trả
122
+ @staticmethod
123
+ def get_trip_by_time_and_office_id(trips: list, time: str ,origin_id: int, dest_id: int) -> dict:
124
+ if time is None or origin_id is None or dest_id is None:
125
+ return {}
126
+
127
+ for trip in trips:
128
+ if trip and trip["raw_departure_time"] == time and trip["route"]["origin_hub_office_id"] == origin_id and trip["route"]["dest_hub_office_id"] == dest_id:
129
+ return trip
130
+ return {}
131
+
132
+
133
+ # Danh sách chuyến đi có thể chọn được theo văn phòng
134
+ @staticmethod
135
+ def get_all_trip_by_office(trips, origin_id: int = None, dest_id: int = None) -> list:
136
+ if origin_id is None and dest_id is None:
137
+ return []
138
+
139
+ result = []
140
+ for trip in trips:
141
+ if origin_id and dest_id:
142
+ if trip["route"]["origin_hub_office_id"] == origin_id and trip["route"]["dest_hub_office_id"] == dest_id:
143
+ result.append(trip)
144
+ elif origin_id:
145
+ if trip["route"]["origin_hub_office_id"] == origin_id:
146
+ result.append(trip)
147
+ elif dest_id:
148
+ if trip["route"]["dest_hub_office_id"] == dest_id:
149
+ result.append(trip)
150
+
151
+ return result
152
+ # Danh sách 4 chuyến đi xung quanh thời gian chỉ định
153
+ @staticmethod
154
+ def get_4_surrounding_trip(trips: list, time: str) -> list:
155
+ if time is None:
156
+ return []
157
+
158
+ time_trips = [ trip["raw_departure_time"] for trip in trips]
159
+ index = bisect_left(time_trips, time)
160
+ start = max(0, index - 2)
161
+ end = min(len(time_trips), index + 2)
162
+
163
+ return time_trips[start:end]
164
+
165
+
166
 
167
  async def is_valid_select_seat(self, seat: str,route_id: int, trip_id:int, departure_date: str, departure_time: str, kind: str):
168
  if seat is None: