From 3c635dd9513597b8739407cf47be6e2d9231785a Mon Sep 17 00:00:00 2001 From: orangdeso Date: Tue, 15 Apr 2025 15:28:54 +0700 Subject: [PATCH] Feat: Addition of more complete airport attributes in transactions --- lib/data/repositories/airport_repository.dart | 18 ++++++++- .../repositories/airport_repository.dart | 1 + lib/domain/usecases/get_airport.dart | 4 ++ .../controllers/search_flight_controller.dart | 13 ++++++- .../screens/home/pages/payment_screen.dart | 2 +- .../home/pages/search_tickets_screen.dart | 12 +++++- .../pages/ticket_booking_step1_screen.dart | 15 +++++++- .../pages/ticket_booking_step2_screen.dart | 15 ++++++-- .../pages/ticket_booking_step3_screen.dart | 32 +++++++--------- .../pages/ticket_booking_step4_screen.dart | 37 +++++++++++++++++-- .../screens/routes/app_rountes.dart | 12 +++++- 11 files changed, 128 insertions(+), 33 deletions(-) diff --git a/lib/data/repositories/airport_repository.dart b/lib/data/repositories/airport_repository.dart index 34064ab..6173059 100644 --- a/lib/data/repositories/airport_repository.dart +++ b/lib/data/repositories/airport_repository.dart @@ -1,5 +1,6 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; +import 'dart:developer'; +import 'package:cloud_firestore/cloud_firestore.dart'; import '../../domain/models/airport.dart'; import '../../domain/repositories/airport_repository.dart'; @@ -15,4 +16,19 @@ class AirportRepositoryImpl implements AirportRepository { .map((doc) => Airport.fromMap(doc.data(), doc.id)) .toList(); } + + @override + Future getAirportsById(String id) async { + try { + final doc = await firestore.collection('bandara').doc(id).get(); + + if (doc.exists) { + return Airport.fromMap(doc.data()!, doc.id); + } + return null; + } catch (e) { + log('Error fetching airport by ID: $e'); + return null; + } + } } \ No newline at end of file diff --git a/lib/domain/repositories/airport_repository.dart b/lib/domain/repositories/airport_repository.dart index 88ca72b..94bb149 100644 --- a/lib/domain/repositories/airport_repository.dart +++ b/lib/domain/repositories/airport_repository.dart @@ -2,4 +2,5 @@ import '../models/airport.dart'; abstract class AirportRepository { Future> getAirports(); + Future getAirportsById(String id); } \ No newline at end of file diff --git a/lib/domain/usecases/get_airport.dart b/lib/domain/usecases/get_airport.dart index e340575..2eb0dbf 100644 --- a/lib/domain/usecases/get_airport.dart +++ b/lib/domain/usecases/get_airport.dart @@ -9,4 +9,8 @@ class GetAirports { Future> call() async { return await repository.getAirports(); } + + Future get(String id) async { + return await repository.getAirportsById(id); + } } \ No newline at end of file diff --git a/lib/presentation/controllers/search_flight_controller.dart b/lib/presentation/controllers/search_flight_controller.dart index d4c95c5..700f18d 100644 --- a/lib/presentation/controllers/search_flight_controller.dart +++ b/lib/presentation/controllers/search_flight_controller.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:get/get.dart'; import '../../domain/models/airport.dart'; @@ -6,7 +8,7 @@ import '../../domain/usecases/get_airport.dart'; class SearchFlightController extends GetxController { final GetAirports getAirports; - var airports = [].obs; // Gunakan Rx agar bisa reaktif + var airports = [].obs; var filteredAirports = [].obs; var searchText = ''.obs; @@ -39,4 +41,13 @@ class SearchFlightController extends GetxController { .toList()); } } + + Future getAirportById(String id) async { + try { + return await getAirports.get(id); + } catch (e) { + log('Error fetching airport by ID: $e'); + return null; + } + } } diff --git a/lib/presentation/screens/home/pages/payment_screen.dart b/lib/presentation/screens/home/pages/payment_screen.dart index 4d02aaf..871fabf 100644 --- a/lib/presentation/screens/home/pages/payment_screen.dart +++ b/lib/presentation/screens/home/pages/payment_screen.dart @@ -129,7 +129,7 @@ class _PaymentScreenState extends State { onTap: () { final argument = { 'ticketId': ticketId, - 'transactionId': Get.arguments['transactionId'], // Ambil dari argumen yang diteruskan + 'transactionId': Get.arguments['transactionId'], 'flightData': flightData, 'totalAll': totalAll, }; diff --git a/lib/presentation/screens/home/pages/search_tickets_screen.dart b/lib/presentation/screens/home/pages/search_tickets_screen.dart index 81c8d94..c0175bb 100644 --- a/lib/presentation/screens/home/pages/search_tickets_screen.dart +++ b/lib/presentation/screens/home/pages/search_tickets_screen.dart @@ -1,4 +1,6 @@ // ignore_for_file: unnecessary_null_comparison +import 'dart:developer'; + import 'package:e_porter/_core/component/appbar/appbar_component.dart'; import 'package:e_porter/_core/constants/colors.dart'; import 'package:e_porter/_core/constants/typography.dart'; @@ -19,6 +21,8 @@ class SearchTicketsScreen extends StatefulWidget { class _SearchTicketsScreenState extends State { late final TicketController ticketController; + late final String fromId; + late final String toId; late final String from; late final String to; late final DateTime leavingDate; @@ -28,9 +32,9 @@ class _SearchTicketsScreenState extends State { @override void initState() { super.initState(); - - // Ambil parameter yang dikirim dari BookingTickets final args = Get.arguments as Map; + fromId = args['fromId']; + toId = args['toId']; from = args['from']; to = args['to']; leavingDate = args['leavingDate']; @@ -134,11 +138,15 @@ class _SearchTicketsScreenState extends State { airlineLogo: flight.airlineLogo, onTap: () { final argument = { + "fromId": fromId, + "toId": toId, "ticketId": ticketId, "flightId": flightId, "ticketDate": ticketDate, "passenger": passengerCount, }; + log('[Search Ticket] ID from : $fromId'); + log('[Search Ticket] ID to : $toId'); Get.toNamed(Routes.TICKETBOOKINGSTEP1, arguments: argument); }, ), diff --git a/lib/presentation/screens/home/pages/ticket_booking_step1_screen.dart b/lib/presentation/screens/home/pages/ticket_booking_step1_screen.dart index ea5395b..18be077 100644 --- a/lib/presentation/screens/home/pages/ticket_booking_step1_screen.dart +++ b/lib/presentation/screens/home/pages/ticket_booking_step1_screen.dart @@ -1,5 +1,7 @@ // ignore_for_file: deprecated_member_use +import 'dart:developer'; + import 'package:e_porter/_core/component/appbar/appbar_component.dart'; import 'package:e_porter/_core/component/button/button_fill.dart'; import 'package:e_porter/_core/component/button/switch_button.dart'; @@ -33,14 +35,20 @@ class TicketBookingStep1Screen extends StatefulWidget { class _TicketBookingStep1ScreenState extends State { bool isToggled = false; + + late final String fromId; + late final String toId; late final String ticketId; late final String flightId; late final String ticketDate; late final int passenger; + late Future _flightFuture; late final TicketController ticketController; + final ProfilController profilController = Get.find(); final currencyFormatter = NumberFormat.decimalPattern('id_ID'); + dynamic _loggedUser; List selectedPassengers = []; @@ -61,7 +69,10 @@ class _TicketBookingStep1ScreenState extends State { void initState() { super.initState(); _loadPassengers(); + final args = Get.arguments as Map; + fromId = args['fromId']; + toId = args['toId']; ticketId = args['ticketId']; flightId = args['flightId']; ticketDate = args['ticketDate']; @@ -90,7 +101,6 @@ class _TicketBookingStep1ScreenState extends State { } final userId = userData.uid; await profilController.fetchPassangerById(userId); - // logger.d('User ID: $userId'); } bool isAllPassengersFilled() { @@ -183,6 +193,8 @@ class _TicketBookingStep1ScreenState extends State { SnackbarHelper.showError('Error', 'Harap lengkapi slot penumpang'); } else { final argument = { + "fromId": fromId, + "toId": toId, 'ticketId': ticketId, 'flightId': flightId, 'date': ticketDate, @@ -201,6 +213,7 @@ class _TicketBookingStep1ScreenState extends State { 'passenger': passenger, 'selectedPassenger': selectedPassengers, }; + log('[Ticket Booking Step1] From ID: $fromId'); Get.toNamed(Routes.TICKETBOOKINGSTEP2, arguments: argument); } diff --git a/lib/presentation/screens/home/pages/ticket_booking_step2_screen.dart b/lib/presentation/screens/home/pages/ticket_booking_step2_screen.dart index cf3a263..e3fc013 100644 --- a/lib/presentation/screens/home/pages/ticket_booking_step2_screen.dart +++ b/lib/presentation/screens/home/pages/ticket_booking_step2_screen.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:e_porter/_core/component/appbar/appbar_component.dart'; import 'package:e_porter/_core/component/card/custome_shadow_cotainner.dart'; import 'package:e_porter/_core/constants/colors.dart'; @@ -22,6 +24,8 @@ class TicketBookingStep2Screen extends StatefulWidget { class _TicketBookingStep2ScreenState extends State { late final TicketController ticketController; + late final String fromId; + late final String toId; late final String ticketId; late final String flightId; String? ticketDate; @@ -45,6 +49,8 @@ class _TicketBookingStep2ScreenState extends State { void initState() { super.initState(); final args = Get.arguments as Map; + fromId = args['fromId']; + toId = args['toId']; ticketId = args['ticketId']; flightId = args['flightId']; ticketDate = args['date']; @@ -63,8 +69,6 @@ class _TicketBookingStep2ScreenState extends State { passenger = args['passenger']; selectedPassengers = args['selectedPassenger'] ?? []; selectedSeatNumbers = args['selectedSeatNumbers'] ?? List.filled(passenger, ''); - - // logger.d('Ticket ID: $ticketId \nFlight ID: $flightId'); } @override @@ -114,11 +118,14 @@ class _TicketBookingStep2ScreenState extends State { numberSeat: '${selectedSeatNumbers[index].isEmpty ? '-' : selectedSeatNumbers[index]}', onTap: () async { final argument = { + // "fromId": fromId, + // "toId": toId, 'ticketId': ticketId, 'flightId': flightId, 'passenger': passenger, 'selectedPassenger': selectedPassengers, }; + // log('[Ticket Booking Step2 in Passing Choose Seat] From ID: $fromId'); final result = await Get.toNamed(Routes.CHOOSECHAIR, arguments: argument); if (result != null && result is List) { setState(() { @@ -147,6 +154,8 @@ class _TicketBookingStep2ScreenState extends State { ? null : () { final argument = { + "fromId": fromId, + "toId": toId, 'ticketId': ticketId, 'flightId': flightId, 'date': ticketDate, @@ -154,7 +163,7 @@ class _TicketBookingStep2ScreenState extends State { 'selectedPassenger': selectedPassengers, 'numberSeat': selectedSeatNumbers }; - // logger.d('Number Seat: $selectedSeatNumbers \n Passenger: $selectedPassengers'); + log('[Ticket Booking Step2] From ID: $fromId'); Get.toNamed(Routes.TICKETBOOKINGSTEP3, arguments: argument); }, ), diff --git a/lib/presentation/screens/home/pages/ticket_booking_step3_screen.dart b/lib/presentation/screens/home/pages/ticket_booking_step3_screen.dart index 2c352e8..98478a1 100644 --- a/lib/presentation/screens/home/pages/ticket_booking_step3_screen.dart +++ b/lib/presentation/screens/home/pages/ticket_booking_step3_screen.dart @@ -40,6 +40,9 @@ class _TicketBookingStep3ScreenState extends State { late final PorterServiceController _porterController; final TicketController ticketController = Get.find(); + + late final String fromId; + late final String toId; late final String ticketId; late final String flightId; late String? ticketDate; @@ -61,6 +64,8 @@ class _TicketBookingStep3ScreenState extends State { void initState() { super.initState(); final args = Get.arguments as Map; + fromId = args['fromId']; + toId = args['toId']; ticketId = args['ticketId']; flightId = args['flightId']; ticketDate = args['date']; @@ -291,6 +296,8 @@ class _TicketBookingStep3ScreenState extends State { selectedPorterServices['transit'] = selectedTransitService; } final argument = { + "fromId": fromId, + "toId": toId, 'ticketId': ticketId, 'flightId': flightId, 'date': ticketDate, @@ -302,25 +309,12 @@ class _TicketBookingStep3ScreenState extends State { 'selectedServiceLabels': selectedServiceLabels, 'selectedPorterServices': selectedPorterServices, }; - log('Ticket ID: $ticketId'); - log('Flight ID: $flightId'); - log('Ticket Date: $ticketDate'); - log('Opsi Penerbangan: $selectedServiceLabels'); - log('Layanan Porter: $selectedPorterServices'); - - // final Map debugPorterServices = {}; - // selectedPorterServices.forEach((key, value) { - // if (value != null) { - // debugPorterServices[key] = { - // 'id': value.id, - // 'name': value.name, - // 'price': value.price, - // }; - // } else { - // debugPorterServices[key] = null; - // } - // }); - // log('Layanan Porter: $debugPorterServices'); + log('[Ticket Booking Step3] From ID: $fromId'); + log('[Ticket Booking Step3] Ticket ID: $ticketId'); + log('[Ticket Booking Step3] Flight ID: $flightId'); + log('[Ticket Booking Step3] Ticket Date: $ticketDate'); + log('[Ticket Booking Step3] Opsi Penerbangan: $selectedServiceLabels'); + log('[Ticket Booking Step3] Layanan Porter: $selectedPorterServices'); Get.toNamed(Routes.TICKETBOOKINGSTEP4, arguments: argument); }, diff --git a/lib/presentation/screens/home/pages/ticket_booking_step4_screen.dart b/lib/presentation/screens/home/pages/ticket_booking_step4_screen.dart index e77c772..e63be3d 100644 --- a/lib/presentation/screens/home/pages/ticket_booking_step4_screen.dart +++ b/lib/presentation/screens/home/pages/ticket_booking_step4_screen.dart @@ -3,6 +3,8 @@ import 'dart:developer'; import 'package:e_porter/_core/component/card/custome_shadow_cotainner.dart'; import 'package:e_porter/_core/constants/colors.dart'; import 'package:e_porter/_core/constants/typography.dart'; +import 'package:e_porter/domain/models/airport.dart'; +import 'package:e_porter/presentation/controllers/search_flight_controller.dart'; import 'package:e_porter/presentation/screens/home/component/footer_price.dart'; import 'package:e_porter/presentation/screens/routes/app_rountes.dart'; import 'package:flutter/material.dart'; @@ -12,7 +14,6 @@ import 'package:get/get.dart'; import 'package:intl/intl.dart'; import '../../../../_core/component/appbar/appbar_component.dart'; import '../../../../_core/component/icons/icons_library.dart'; -import '../../../../_core/service/logger_service.dart'; import '../../../../_core/service/preferences_service.dart'; import '../../../../_core/utils/snackbar/snackbar_helper.dart'; import '../../../../domain/models/porter_service_model.dart'; @@ -30,6 +31,8 @@ class TicketBookingStep4Screen extends StatefulWidget { } class _TicketBookingStep4ScreenState extends State { + late final String fromId; + late final String toId; late final String ticketId; late final String flightId; late String? ticketDate; @@ -45,14 +48,23 @@ class _TicketBookingStep4ScreenState extends State { final TicketController ticketController = Get.find(); final TransactionController transactionController = Get.find(); + late final SearchFlightController searchFlightController; + FlightModel? flightData; String? departureTime; String? arrivalTime; + Airport? departureAirport; + Airport? arrivalAirport; + @override void initState() { super.initState(); + searchFlightController = Get.find(); + final args = Get.arguments as Map; + fromId = args['fromId'] ?? ''; + toId = args['toId'] ?? ''; ticketId = args['ticketId'] ?? ''; flightId = args['flightId'] ?? ''; ticketDate = args['date']; @@ -65,6 +77,7 @@ class _TicketBookingStep4ScreenState extends State { selectedPorterServices = args['selectedPorterServices'] ?? {}; fetchDataFlight(); + fetchAirportData(); transactionController.checkExpiredTransactions(); } @@ -77,7 +90,21 @@ class _TicketBookingStep4ScreenState extends State { arrivalTime = DateFormat.jm().format(flightData!.arrivalTime); }); } catch (e) { - logger.e('Terjadi kesalahan: $e'); + log('Terjadi kesalahan: $e'); + } + } + + Future fetchAirportData() async { + try { + if (fromId.isNotEmpty) { + departureAirport = await searchFlightController.getAirportById(fromId); + } + if (toId.isNotEmpty) { + arrivalAirport = await searchFlightController.getAirportById(toId); + } + setState(() {}); + } catch (e) { + log('Error fetching airport data: $e'); } } @@ -95,7 +122,7 @@ class _TicketBookingStep4ScreenState extends State { try { return NumberFormat.decimalPattern('id_ID').format(porter.price); } catch (e) { - print("Error formatting porter price: $e"); + log("Error formatting porter price: $e"); return '0'; } } @@ -244,12 +271,16 @@ class _TicketBookingStep4ScreenState extends State { // Persiapkan data bandara final bandaraData = { 'departure': { + 'id': fromId, 'code': flightData?.codeDeparture, 'city': flightData?.cityDeparture, + 'name': departureAirport?.name ?? '', }, 'arrival': { + 'id': toId, 'code': flightData?.codeArrival, 'city': flightData?.cityArrival, + 'name': arrivalAirport?.name ?? '' }, }; diff --git a/lib/presentation/screens/routes/app_rountes.dart b/lib/presentation/screens/routes/app_rountes.dart index 8ec29a3..3303554 100644 --- a/lib/presentation/screens/routes/app_rountes.dart +++ b/lib/presentation/screens/routes/app_rountes.dart @@ -1,4 +1,5 @@ import 'package:e_porter/domain/bindings/auth_binding.dart'; +import 'package:e_porter/domain/bindings/history_binding.dart'; import 'package:e_porter/domain/bindings/navigation_binding.dart'; import 'package:e_porter/domain/bindings/porter_service_binding.dart'; import 'package:e_porter/domain/bindings/profil_binding.dart'; @@ -38,7 +39,10 @@ class AppRoutes { GetPage( name: Routes.NAVBAR, page: () => MainNavigation(), - binding: MainNavigationBinding(), + bindings: [ + MainNavigationBinding(), + HistoryBinding(), + ], ), GetPage( name: Routes.SPLASH, @@ -61,6 +65,7 @@ class AppRoutes { GetPage( name: Routes.BOARDINGPASS, page: () => BoardingPassScreen(), + binding: HistoryBinding(), ), GetPage( name: Routes.PROFILE, @@ -113,7 +118,10 @@ class AppRoutes { GetPage( name: Routes.TICKETBOOKINGSTEP4, page: () => TicketBookingStep4Screen(), - binding: TransactionBinding(), + bindings: [ + TransactionBinding(), + SearchFlightBinding(), + ], ), GetPage( name: Routes.CHOOSECHAIR,