Feat: fix bug in features history transaction porter
This commit is contained in:
parent
56b629b1d7
commit
6bf43369c4
|
@ -638,7 +638,7 @@
|
||||||
"languageVersion": "3.4"
|
"languageVersion": "3.4"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"generated": "2025-04-30T16:03:15.794012Z",
|
"generated": "2025-05-05T05:14:47.271498Z",
|
||||||
"generator": "pub",
|
"generator": "pub",
|
||||||
"generatorVersion": "3.5.0",
|
"generatorVersion": "3.5.0",
|
||||||
"flutterRoot": "file:///D:/Flutter/flutter_sdk/flutter_3.24.0",
|
"flutterRoot": "file:///D:/Flutter/flutter_sdk/flutter_3.24.0",
|
||||||
|
|
|
@ -670,7 +670,7 @@ class TransactionPorterRepositoryImpl implements TransactionPorterRepository {
|
||||||
'isAvailable': false,
|
'isAvailable': false,
|
||||||
'idTransaction': transactionId,
|
'idTransaction': transactionId,
|
||||||
'idUser': txData['idPassenger'] ?? '',
|
'idUser': txData['idPassenger'] ?? '',
|
||||||
'lastAssigned': now,
|
'onlineAt': now,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 6. Update transaksi utama dengan format ReassignmentInfo
|
// 6. Update transaksi utama dengan format ReassignmentInfo
|
||||||
|
|
|
@ -5,7 +5,6 @@ import 'package:e_porter/_core/service/preferences_service.dart';
|
||||||
import 'package:e_porter/_core/utils/snackbar/snackbar_helper.dart';
|
import 'package:e_porter/_core/utils/snackbar/snackbar_helper.dart';
|
||||||
import 'package:e_porter/domain/models/porter_queue_model.dart';
|
import 'package:e_porter/domain/models/porter_queue_model.dart';
|
||||||
import 'package:e_porter/presentation/screens/boarding_pass/provider/porter_service_provider.dart';
|
import 'package:e_porter/presentation/screens/boarding_pass/provider/porter_service_provider.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import '../../domain/models/transaction_porter_model.dart';
|
import '../../domain/models/transaction_porter_model.dart';
|
||||||
import '../../domain/usecases/transaction_porter_usecase.dart';
|
import '../../domain/usecases/transaction_porter_usecase.dart';
|
||||||
|
@ -30,8 +29,6 @@ class TransactionPorterController extends GetxController {
|
||||||
final RxBool isRejecting = false.obs;
|
final RxBool isRejecting = false.obs;
|
||||||
final RxBool needsRefresh = false.obs;
|
final RxBool needsRefresh = false.obs;
|
||||||
|
|
||||||
final TextEditingController rejectionReasonController = TextEditingController();
|
|
||||||
|
|
||||||
StreamSubscription<List<PorterTransactionModel>>? _subscription;
|
StreamSubscription<List<PorterTransactionModel>>? _subscription;
|
||||||
StreamSubscription<PorterQueueModel?>? _porterSubscription;
|
StreamSubscription<PorterQueueModel?>? _porterSubscription;
|
||||||
StreamSubscription<List<PorterTransactionModel>>? _rejectedSubscription;
|
StreamSubscription<List<PorterTransactionModel>>? _rejectedSubscription;
|
||||||
|
@ -524,18 +521,15 @@ class TransactionPorterController extends GetxController {
|
||||||
|
|
||||||
void showRejectDialog() {
|
void showRejectDialog() {
|
||||||
rejectionReason.value = '';
|
rejectionReason.value = '';
|
||||||
rejectionReasonController.clear();
|
|
||||||
isRejectionDialogVisible.value = true;
|
isRejectionDialogVisible.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hideRejectDialog() {
|
void hideRejectDialog() {
|
||||||
isRejectionDialogVisible.value = false;
|
isRejectionDialogVisible.value = false;
|
||||||
rejectionReasonController.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onClose() {
|
void onClose() {
|
||||||
rejectionReasonController.dispose();
|
|
||||||
_porterSubscription?.cancel();
|
_porterSubscription?.cancel();
|
||||||
_subscription?.cancel();
|
_subscription?.cancel();
|
||||||
_rejectedSubscription?.cancel();
|
_rejectedSubscription?.cancel();
|
||||||
|
@ -545,51 +539,4 @@ class TransactionPorterController extends GetxController {
|
||||||
_transactionWatchers.clear();
|
_transactionWatchers.clear();
|
||||||
super.onClose();
|
super.onClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void showRejectionDialog(String transactionId, BuildContext context) {
|
|
||||||
showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
return AlertDialog(
|
|
||||||
title: const Text('Tolak Permintaan Porter'),
|
|
||||||
content: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
const Text('Masukkan alasan penolakan:'),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
TextField(
|
|
||||||
controller: rejectionReasonController,
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
hintText: 'Contoh: Sedang melayani penumpang lain',
|
|
||||||
border: OutlineInputBorder(),
|
|
||||||
),
|
|
||||||
maxLines: 3,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
rejectionReasonController.clear();
|
|
||||||
},
|
|
||||||
child: const Text('Batal'),
|
|
||||||
),
|
|
||||||
TextButton(
|
|
||||||
onPressed: () {
|
|
||||||
final reason = rejectionReasonController.text.trim();
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
rejectTransaction(
|
|
||||||
transactionId: transactionId,
|
|
||||||
reason: reason,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: const Text('Tolak'),
|
|
||||||
style: TextButton.styleFrom(foregroundColor: Colors.red),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,13 @@ import 'package:e_porter/_core/component/button/button_fill.dart';
|
||||||
import 'package:e_porter/_core/component/card/custome_shadow_cotainner.dart';
|
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/colors.dart';
|
||||||
import 'package:e_porter/_core/constants/typography.dart';
|
import 'package:e_porter/_core/constants/typography.dart';
|
||||||
|
import 'package:e_porter/_core/utils/snackbar/snackbar_helper.dart';
|
||||||
import 'package:e_porter/domain/models/transaction_model.dart';
|
import 'package:e_porter/domain/models/transaction_model.dart';
|
||||||
import 'package:e_porter/domain/models/transaction_porter_model.dart';
|
import 'package:e_porter/domain/models/transaction_porter_model.dart';
|
||||||
import 'package:e_porter/presentation/controllers/history_controller.dart';
|
import 'package:e_porter/presentation/controllers/history_controller.dart';
|
||||||
|
import 'package:e_porter/presentation/controllers/navigation_controller.dart';
|
||||||
import 'package:e_porter/presentation/controllers/transaction_porter_controller.dart';
|
import 'package:e_porter/presentation/controllers/transaction_porter_controller.dart';
|
||||||
|
import 'package:e_porter/presentation/screens/navigation/main_navigation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
@ -27,6 +30,7 @@ class DetailHistoryPorterScreen extends StatefulWidget {
|
||||||
class _DetailHistoryPorterScreenState extends State<DetailHistoryPorterScreen> {
|
class _DetailHistoryPorterScreenState extends State<DetailHistoryPorterScreen> {
|
||||||
final TransactionPorterController _porterController = Get.find<TransactionPorterController>();
|
final TransactionPorterController _porterController = Get.find<TransactionPorterController>();
|
||||||
final HistoryController _historyController = Get.find<HistoryController>();
|
final HistoryController _historyController = Get.find<HistoryController>();
|
||||||
|
final _reasonController = TextEditingController();
|
||||||
|
|
||||||
PorterTransactionModel? porterTransaction;
|
PorterTransactionModel? porterTransaction;
|
||||||
|
|
||||||
|
@ -42,12 +46,16 @@ class _DetailHistoryPorterScreenState extends State<DetailHistoryPorterScreen> {
|
||||||
final args = Get.arguments as Map<String, dynamic>;
|
final args = Get.arguments as Map<String, dynamic>;
|
||||||
porterTransactionId = args['transactionPorterId'];
|
porterTransactionId = args['transactionPorterId'];
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||||
_fetchTransactioPorterById();
|
await _fetchTransactioPorterById();
|
||||||
_fetchTransactionData();
|
await _fetchTransactionData();
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
log('[Detail History Porter] ID Transaction Porter : $porterTransactionId');
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_reasonController.dispose();
|
||||||
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _fetchTransactioPorterById() async {
|
Future<void> _fetchTransactioPorterById() async {
|
||||||
|
@ -91,10 +99,7 @@ class _DetailHistoryPorterScreenState extends State<DetailHistoryPorterScreen> {
|
||||||
if (porterTransaction.ticketId.isNotEmpty && porterTransaction.transactionId.isNotEmpty) {
|
if (porterTransaction.ticketId.isNotEmpty && porterTransaction.transactionId.isNotEmpty) {
|
||||||
await _historyController.getTransactionFromFirestore(
|
await _historyController.getTransactionFromFirestore(
|
||||||
porterTransaction.ticketId, porterTransaction.transactionId);
|
porterTransaction.ticketId, porterTransaction.transactionId);
|
||||||
|
|
||||||
log('[Detail History Porter] Berhasil mengambil ticket transaction');
|
|
||||||
} else {
|
} else {
|
||||||
log('[Detail History Porter] ticketId atau transactionId kosong');
|
|
||||||
_historyController.selectedTransaction.value = null;
|
_historyController.selectedTransaction.value = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,6 +110,50 @@ class _DetailHistoryPorterScreenState extends State<DetailHistoryPorterScreen> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _showRejectionDialog() {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (_) => AlertDialog(
|
||||||
|
title: Text('Tolak Permintaan Porter'),
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text('Masukkan alasan penolakan:'),
|
||||||
|
SizedBox(height: 10),
|
||||||
|
TextField(
|
||||||
|
controller: _reasonController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: 'Sedang melayani penumpang lain',
|
||||||
|
border: OutlineInputBorder(),
|
||||||
|
),
|
||||||
|
maxLines: 3,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
_reasonController.clear();
|
||||||
|
},
|
||||||
|
child: Text('Batal'),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
final reason = _reasonController.text.trim();
|
||||||
|
Navigator.pop(context);
|
||||||
|
_porterController.rejectTransaction(
|
||||||
|
transactionId: porterTransactionId,
|
||||||
|
reason: reason,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Text('Tolak', style: TextStyle(color: Colors.red)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
@ -167,7 +216,31 @@ class _DetailHistoryPorterScreenState extends State<DetailHistoryPorterScreen> {
|
||||||
textColor: Colors.white,
|
textColor: Colors.white,
|
||||||
backgroundColor: PrimaryColors.primary700,
|
backgroundColor: PrimaryColors.primary700,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
_porterController.forceReassignTransaction(porterTransactionId);
|
Get.dialog(
|
||||||
|
const Center(child: CircularProgressIndicator()),
|
||||||
|
barrierDismissible: false,
|
||||||
|
);
|
||||||
|
|
||||||
|
Get.delete<NavigationController>();
|
||||||
|
Get.put(NavigationController());
|
||||||
|
Get.offAll(
|
||||||
|
() => MainNavigation(initialTabIndex: 1),
|
||||||
|
arguments: 'porter',
|
||||||
|
);
|
||||||
|
|
||||||
|
_porterController.forceReassignTransaction(porterTransactionId).then((_) {
|
||||||
|
if (Get.isDialogOpen ?? false) Get.back();
|
||||||
|
SnackbarHelper.showSuccess(
|
||||||
|
'Berhasil',
|
||||||
|
'Transaksi berhasil dialihkan ke porter lain',
|
||||||
|
);
|
||||||
|
}).catchError((e) {
|
||||||
|
if (Get.isDialogOpen ?? false) Get.back();
|
||||||
|
SnackbarHelper.showError(
|
||||||
|
'Gagal',
|
||||||
|
'Transaksi gagal dialihkan: $e',
|
||||||
|
);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -184,7 +257,7 @@ class _DetailHistoryPorterScreenState extends State<DetailHistoryPorterScreen> {
|
||||||
textColor: Colors.white,
|
textColor: Colors.white,
|
||||||
backgroundColor: RedColors.red500,
|
backgroundColor: RedColors.red500,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
_porterController.showRejectionDialog(porterTransactionId, context);
|
_showRejectionDialog();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -175,7 +175,11 @@ class AppRoutes {
|
||||||
GetPage(
|
GetPage(
|
||||||
name: Routes.DETAILHISTORYPORTER,
|
name: Routes.DETAILHISTORYPORTER,
|
||||||
page: () => DetailHistoryPorterScreen(),
|
page: () => DetailHistoryPorterScreen(),
|
||||||
binding: TransactionPorterBinding()
|
bindings: [
|
||||||
|
TransactionPorterBinding(),
|
||||||
|
TransactionBinding(),
|
||||||
|
HistoryBinding(),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
GetPage(
|
GetPage(
|
||||||
name: Routes.ADDPASSENGER,
|
name: Routes.ADDPASSENGER,
|
||||||
|
|
Loading…
Reference in New Issue