import 'dart:async'; import 'dart:convert'; import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:data_table_2/data_table_2.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:loading_animation_widget/loading_animation_widget.dart'; import 'package:siopas/models/condition_peti_model.dart'; import 'package:siopas/models/customer_model.dart'; import 'package:siopas/models/disposal_model.dart'; import 'package:siopas/models/m_asset_status_model.dart'; import 'package:siopas/models/type_peti_model.dart'; import 'package:siopas/models/warehouse_mode.dart'; import 'package:siopas/pages/pengembalian_barang/conn/syncronize.dart'; import 'package:siopas/pages/pengembalian_barang/controller/pengembalian_controller.dart'; import 'package:siopas/pages/pengembalian_barang/show.dart'; import 'package:siopas/services/syncronizeAPI.dart'; import 'package:siopas/services/controllerApi.dart'; import 'package:siopas/pages/peminjaman_barang/controller/peminjaman_controller.dart'; import 'package:intl/intl.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:siopas/models/asset_status_model.dart'; import 'package:collection/collection.dart'; import '../peminjaman_barang/show.dart'; // import 'show.dart'; class PengembalianBarangPage extends StatefulWidget { const PengembalianBarangPage({super.key}); @override State createState() => PengembalianBarangPageState(); } class PengembalianBarangPageState extends State { String? token; bool loading = true; // Reinit atau Upload Only WarehouseModel? warehouseSqfliteApi; List? typePetiSqfliteApi; List? customerSqfliteApi; PetiAssetModel? petiSqfliteApi; ConditionPetiModel? conditionPetiSqfliteApi; DisposalPetiModel? disposalSqfliteApi; List? _valpeti; // Change this line List? _valwarehouse; List? _valconditionPeti; List? _valdisposal; // Datatable int _currentPage = 1; int _pageSize = 10; List? _data; List? _petiData; List? _tipePetiData; List? _customerData; List? _warehouseData; List? _conditionData; Timer? _timer; bool _isLoading = false; @override void initState() { super.initState(); _getUserToken(); // Set _isLoading ke true sebelum memulai tugas if (mounted) { setState(() { _isLoading = true; }); } Future.wait([ warehouseListAPI(), conditionPetiListAPI(), typePetiListAPI(), customerListAPI(), petiListAPI(), // disposalListAPI(), datatablesPengembalianList(), datatablesPetiList(), datatablesTipePetiList(), datatablesCustomerList(), datatablesWarehouseList(), datatablesConditionList(), ]).then((_) { // Set _isLoading ke false setelah semua tugas selesai if (mounted) { setState(() { _isLoading = false; }); } }); // Inisialisasi _data di sini jika diperlukan _data = []; } void _getUserToken() async { SharedPreferences prefs = await SharedPreferences.getInstance(); if (mounted) { setState(() { token = prefs.getString('token'); }); } } // Reinit atau Upload Only ------------------------------------------------------------------------ Future warehouseListAPI() async { if (mounted) { await ControllerApi().fetchWarehouseDataAPI().then((value) { setState(() { _valwarehouse = (value as List) .map((item) => WarehouseModel.fromJson(item)) .toList(); loading = false; }); }); } } // Future disposalListAPI() async { // if (mounted) { // await ControllerApi().fetchDisposalDataAPI().then((value) { // setState(() { // _valdisposal = (value as List) // .map((item) => DisposalPetiModel.fromJson(item)) // .toList(); // loading = false; // }); // }); // } // } Future typePetiListAPI() async { if (mounted) { await ControllerApi().fetchTipePetiDataAPI().then((value) { setState(() { typePetiSqfliteApi = (value as List) .map((item) => TypePetiModel.fromJson(item)) .toList(); loading = false; }); }); } } Future customerListAPI() async { if (mounted) { await ControllerApi().fetchCustomerDataAPI().then((value) { setState(() { customerSqfliteApi = (value as List) .map((item) => CustomerModel.fromJson(item)) .toList(); loading = false; }); }); } } Future petiListAPI() async { if (mounted) { await ControllerApi().fetchPetiDataAPI().then((value) { setState(() { _valpeti = (value as List) .map((item) => PetiAssetModel.fromJson(item)) .toList(); loading = false; }); }); } } Future conditionPetiListAPI() async { if (mounted) { await ControllerApi().fetchKondisiPetiDataAPI().then((value) { setState(() { _valconditionPeti = (value as List) .map((item) => ConditionPetiModel.fromJson(item)) .toList(); loading = false; }); }); } } // Future reinitAssetStatusApi() async { // List assetStatusApiData = // await SyncronizationDataAPI().fetchAssetStatusFromApi(); // await ControllerApi() // .deleteAllAssetStatusDataAPI(); // Clear existing data in SQLite // await ControllerApi() // .addAllAssetStatusDataAPI(assetStatusApiData); // Add new data to SQLite // } Future reinitWarehouseApi() async { EasyLoading.show(status: 'Mengambil data Warehouse...'); List warehouseApiData = await SyncronizationDataAPI().fetchWarehouseFromApi(); await ControllerApi() .deleteAllWarehouseDataAPI(); // Clear existing data in SQLite await ControllerApi() .addAllWarehouseDataAPI(warehouseApiData); // Add new data to SQLite EasyLoading.dismiss(); } Future reinitPetiApi() async { EasyLoading.show(status: 'Mengambil data Peti...'); List petiApiData = await SyncronizationDataAPI().fetchPetiFromApi(); await ControllerApi() .deleteAllPetiDataAPI(); // Clear existing data in SQLite // Menentukan ukuran chunk, misalnya 100 int chunkSize = 100; // Memasukkan data ke SQLite dengan menggunakan chunk await ControllerApi().addAllPetiDataAPI(petiApiData, chunkSize); EasyLoading.dismiss(); } Future reinitCustomerApi() async { EasyLoading.show(status: 'Mengambil data Customer...'); List customerApiData = await SyncronizationDataAPI().fetchCustomerFromApi(); await ControllerApi() .deleteAllCustomerDataAPI(); // Clear existing data in SQLite await ControllerApi() .addAllCustomerDataAPI(customerApiData); // Add new data to SQLite EasyLoading.dismiss(); } Future reinitConditionPetiApi() async { EasyLoading.show(status: 'Mengambil data Condition Peti...'); List conditionPetiApiData = await SyncronizationDataAPI().fetchKondisiPetiFromApi(); await ControllerApi() .deleteAllKondisiPetiDataAPI(); // Clear existing data in SQLite await ControllerApi().addAllKondisiPetiDataAPI( conditionPetiApiData); // Add new data to SQLite EasyLoading.dismiss(); } // Future reinitDisposalApi() async { // List disposalApiData = // await SyncronizationDataAPI().fetchDisposalFromApi(); // await ControllerApi() // .deleteAllDisposalDataAPI(); // Clear existing data in SQLite // await ControllerApi() // .addAllDisposalDataAPI(disposalApiData); // Add new data to SQLite // } Future fetchDataFromApiAndSync() async { EasyLoading.show(status: 'Mengambil data dari Server...'); try { await syncToMysql(); // await reinitAssetStatusApi(); await reinitWarehouseApi(); await reinitPetiApi(); await reinitCustomerApi(); // await reinitTypePetiApi(); await reinitConditionPetiApi(); // await reinitDisposalApi(); await datatablesPengembalianList(); EasyLoading.showSuccess('Data berhasil diperbarui'); } catch (e) { EasyLoading.showError('Gagal memperbarui data: $e'); } finally { EasyLoading.dismiss(); } } Future syncToMysql() async { await SyncronizationPengembalianData() .fetchAllInfo() .then((assetList) async { EasyLoading.show( status: 'Jangan tutup aplikasi. Kami sedang menyinkronkan...'); await Future.delayed(Duration(seconds: 3)); // Tambahkan penanganan pengunggahan bool uploadSuccess = await SyncronizationPengembalianData() .savePengembalianToServerWith(assetList); // Jika pengunggahan berhasil, hapus data lokal if (uploadSuccess) { await SyncronizationPengembalianData().deleteAllAssetStatusData(); // Setelah selesai, tampilkan pesan sukses await datatablesPengembalianList(); EasyLoading.showSuccess('Berhasil disinkronkan dengan Server'); } else { // Tampilkan pesan gagal jika pengunggahan tidak berhasil EasyLoading.showError('Gagal disinkronkan dengan Server'); } }); } // Future syncToMysql() async { // await SyncronizationData().fetchAllInfo().then((assetList) async { // EasyLoading.show(status: 'Don\'t close app. We are syncing...'); // await SyncronizationData().saveToMysqlWith(assetList); // await SyncronizationData().deleteAllAssetStatusData(); // // EasyLoading.showSuccess('Successfully saved to MySQL'); // }); // } Future isInteret() async { await SyncronizationPengembalianData.isInternet().then((connection) { if (connection) { print("Internet connection available"); } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("Tidak ada koneksi internet"))); } }); } // Datatables ------------------------------------------------------------------------ Future datatablesPengembalianList() async { if (mounted) { await ControllerPengembalian() .fetchPengembalianLocalController() .then((value) { setState(() { _data = (value as List) .map((e) => AssetStatusModel.fromJson(e)) .toList(); loading = false; }); }); } } Future datatablesPetiList() async { if (mounted) { await ControllerPengembalian().fetchPetiData().then((value) { setState(() { _petiData = (value as List) .map((e) => PetiAssetModel.fromJson(e)) .toList(); loading = false; }); }); } } Future datatablesTipePetiList() async { if (mounted) { await ControllerPengembalian().fetchTipePetiData().then((value) { setState(() { _tipePetiData = (value as List) .map((e) => TypePetiModel.fromJson(e)) .toList(); loading = false; }); }); } } Future datatablesCustomerList() async { if (mounted) { await ControllerPengembalian().fetchCustomerData().then((value) { setState(() { _customerData = (value as List) .map((e) => CustomerModel.fromJson(e)) .toList(); loading = false; }); }); } } Future datatablesWarehouseList() async { if (mounted) { await ControllerPengembalian().fetchWarehouseData().then((value) { setState(() { _warehouseData = (value as List) .map((e) => WarehouseModel.fromJson(e)) .toList(); loading = false; }); }); } } Future datatablesConditionList() async { if (mounted) { await ControllerPengembalian().fetchConditionData().then((value) { setState(() { _conditionData = (value as List) .map((e) => ConditionPetiModel.fromJson(e)) .toList(); loading = false; }); }); } } void _loadMoreData() { if (mounted && !_isLoading) { setState(() { _currentPage++; }); datatablesPengembalianList(); } } @override Widget build(BuildContext context) { // Add this function outside the build method void showSyncDialog(BuildContext context) { showDialog( context: context, builder: (BuildContext context) { return Dialog( // Dialog shape and style shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), backgroundColor: Colors.grey[100], elevation: 0, // Dialog content child: Column( mainAxisSize: MainAxisSize.min, children: [ // Dialog title with close button Container( width: double.infinity, color: Colors.indigo[700], // Indigo background child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Padding( padding: const EdgeInsets.all(16.0), child: Text( "Sync Server Pengembalian", style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 16.0, ), ), ), IconButton( icon: Icon( Icons.close, color: Colors.white, ), onPressed: () { Navigator.pop(context); // Close dialog }, ), ], ), ), // Divider Divider( height: 1, thickness: 1, color: Colors.black, // Black divider ), // Re-init Button Container( width: double.infinity, child: TextButton( onPressed: () { Navigator.pop(context); // Close dialog fetchDataFromApiAndSync(); }, child: Text( "Upload + Download", style: TextStyle( color: Colors.black, fontSize: 16.0, fontFamily: 'Poppins', ), ), ), ), // Divider // Divider( // height: 1, // thickness: 1, // color: Colors.black, // Black divider // ), // Upload Only Button // Container( // width: double.infinity, // child: TextButton( // onPressed: () { // Navigator.pop(context); // Close dialog // syncToMysql(); // }, // child: Text( // "Upload Only", // style: TextStyle( // color: Colors.black, // fontSize: 16.0, // fontFamily: 'Poppins', // ), // ), // ), // ), ], ), ); }, ); } return DefaultTabController( length: 1, child: Scaffold( appBar: AppBar( backgroundColor: Colors.indigo[700], elevation: 0, title: Text('Data Pengembalian Peti', style: TextStyle( fontSize: 16, )), actions: [ IconButton( icon: Icon(Icons.backup), onPressed: () async { if (await SyncronizationPengembalianData.isInternet()) { // Display custom dialog when the IconButton is pressed showSyncDialog(context); } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("Tidak ada koneksi internet")), ); } }, ), ], leading: IconButton( icon: Icon(Icons.arrow_back, color: Colors.white), onPressed: () { Navigator.pushNamed(context, '/home'); }, ), bottom: TabBar( indicator: BoxDecoration(color: Color.fromARGB(255, 50, 39, 122)), tabs: [ Tab(text: 'Pengembalian Peti Hari ini'), ], ), ), body: _isLoading ? Center( child: LoadingAnimationWidget.staggeredDotsWave( color: Colors.indigo, size: 40, ), ) : TabBarView( children: [ SingleChildScrollView( child: Column( children: [ SizedBox( width: double.infinity, child: PaginatedDataTable( // header: Text('Searching'), // Removed const rowsPerPage: _pageSize, availableRowsPerPage: [10, 25, 50], // Removed const onRowsPerPageChanged: (value) { if (mounted) { setState(() { _pageSize = value!; }); } }, columns: [ DataColumn(label: Text('No')), DataColumn(label: Text('')), DataColumn(label: Text('Kode Peti')), DataColumn(label: Text('Tgl Pengembalian')), DataColumn(label: Text('PJ Pengembalian')), DataColumn(label: Text('Tujuan WH Pengembalian')), DataColumn(label: Text('Kondisi Peti')), ], source: _DataSourceLokal( data: _data!, context: context, petiData: _petiData != null ? _petiData : [], tipePetiData: _tipePetiData != null ? _tipePetiData : [], customerData: _customerData != null ? _customerData : [], warehouseData: _warehouseData != null ? _warehouseData : [], conditionData: _conditionData != null ? _conditionData : [], ), ), ), ], ), ), ], ), bottomNavigationBar: BottomAppBar( color: Color.fromARGB(255, 5, 28, 158), // Warna latar belakang child: Container( height: 65.0, child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ InkWell( customBorder: CircleBorder(), onTap: () { // Aksi ketika ikon diklik Navigator.pushNamed(context, '/pengembalian-barang/edit'); }, child: Container( width: 45, height: 45, decoration: BoxDecoration( shape: BoxShape.circle, color: Colors.greenAccent[700], ), child: Icon( Icons.add, size: 30, color: Colors.white, ), ), ), ], ), ), ), ), ); } } class _DataSourceLokal extends DataTableSource { final List data; List? petiData; List? tipePetiData; List? customerData; List? warehouseData; List? conditionData; final BuildContext context; _DataSourceLokal({ required this.data, required this.petiData, required this.tipePetiData, required this.customerData, required this.warehouseData, required this.conditionData, required this.context, }); @override DataRow? getRow(int index) { if (index >= data.length) { return null; } data.sort((a, b) { if (a.created_at == null && b.created_at == null) { return 0; // Both dates are null, consider them equal } else if (a.created_at == null) { return 1; // Null is considered greater than non-null } else if (b.created_at == null) { return -1; // Non-null is considered smaller than null } else { return b.created_at!.compareTo(a.created_at!); // Compare non-null dates } }); final item = data[index]; // Menemukan data peti yang sesuai dengan asset PetiAssetModel? petiSqfliteApi; if (item.peti_id != null) { petiSqfliteApi = petiData!.firstWhere( (peti) => peti.id == item.peti_id, orElse: () => PetiAssetModel( id: null, tipe_peti_id: null, warna: 'null', packing_no: null, customer_id: null, warehouse_id: null, kondisipeti_id: null, jumlah: null, date_pembuatan: DateTime.now(), created_by: 'null', updated_by: 'null', fix_lot: '', ), ); } TypePetiModel? tipePetiSqfliteApi; if (petiSqfliteApi != null && petiSqfliteApi.tipe_peti_id != null) { tipePetiSqfliteApi = tipePetiData?.firstWhere( (tipePeti) => tipePeti.id == petiSqfliteApi?.tipe_peti_id, orElse: () => TypePetiModel( id: null, type: 'null', size_peti: 'null', description: 'null', created_by: 'null', updated_by: 'null', ), ); } CustomerModel? customerSqfliteApi; if (petiSqfliteApi != null && petiSqfliteApi.customer_id != null) { customerSqfliteApi = customerData?.firstWhere( (customer) => customer.id == petiSqfliteApi?.customer_id, orElse: () => CustomerModel( id: null, name: 'null', code_customer: 'null', lot_no: 'null', created_by: 'null', updated_by: 'null', ), ); } ConditionPetiModel? conditionSqfliteApi; if (item.kondisi_peti_id != null) { conditionSqfliteApi = conditionData?.firstWhere( (warehouse) => warehouse.id == item.kondisi_peti_id, orElse: () => ConditionPetiModel( id: null, nama_kondisi: 'null', created_by: 'null', updated_by: 'null', ), ); } WarehouseModel? warehouseSqfliteApi; if (item.enter_warehouse != null) { warehouseSqfliteApi = warehouseData?.firstWhere( (warehouse) => warehouse.id == item.enter_warehouse, orElse: () => WarehouseModel( id: null, name: 'null', created_by: 'null', updated_by: 'null', ), ); } return DataRow(cells: [ DataCell( Text( (index + 1).toString(), ), ), DataCell( GestureDetector( onTap: () { if (item.id != null) { Navigator.push( context, MaterialPageRoute( builder: (context) => DetailPengembalianBarangPage( pengembalianId: item.id.toString(), ), ), ); // print('asset id: ${item.id}'); } }, child: Icon(Icons.article, size: 40, color: Colors.indigo[700]), // Ganti ikon sesuai kebutuhan ), ), DataCell( Text( petiSqfliteApi != null && petiSqfliteApi.fix_lot != null ? petiSqfliteApi!.fix_lot.toString() : '-', ), ), DataCell( Text( item.enter_at != null ? DateFormat('dd-MM-yyyy').format(item.enter_at!) : '-', ), ), DataCell( Text( item.enter_pic.toString() != 'null' ? item.enter_pic.toString() : '-', ), ), DataCell( Text( (item.enter_warehouse != null && item.enter_warehouse != 'null') ? warehouseSqfliteApi != null && warehouseSqfliteApi.id == item.enter_warehouse ? warehouseSqfliteApi.name.toString() : '-' : '-', ), ), DataCell( Text( conditionSqfliteApi != null && conditionSqfliteApi.nama_kondisi != null ? conditionSqfliteApi!.nama_kondisi.toString() : '-', ), ), ]); } @override bool get isRowCountApproximate => false; @override int get rowCount => data.length; @override int get selectedRowCount => 0; }