You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
724 lines
22 KiB
724 lines
22 KiB
import 'dart:async'; |
|
|
|
import 'package:flutter/material.dart'; |
|
import 'package:flutter_easyloading/flutter_easyloading.dart'; |
|
import 'package:siopas/migrations/databasehelper.dart'; |
|
import 'package:siopas/models/transfer_peti_model.dart'; |
|
import 'package:provider/provider.dart'; |
|
import 'package:shared_preferences/shared_preferences.dart'; |
|
import '../../models/asset_status_model.dart'; |
|
import '../../models/condition_peti_model.dart'; |
|
import '../../models/customer_model.dart'; |
|
import '../../models/m_asset_status_model.dart'; |
|
import '../../models/type_peti_model.dart'; |
|
import '../../models/user_model.dart'; |
|
import '../../models/warehouse_mode.dart'; |
|
import '../../providers/auth_provider.dart'; |
|
import 'package:intl/intl.dart'; |
|
import 'package:intl/date_symbol_data_local.dart'; |
|
|
|
import '../../services/controllerApi.dart'; |
|
import '../../services/syncronizeAPI.dart'; |
|
import '../../theme.dart'; |
|
import '../peminjaman_barang/conn/syncronize.dart'; |
|
import '../peminjaman_barang/controller/peminjaman_controller.dart'; |
|
import '../pengembalian_barang/conn/syncronize.dart'; |
|
import '../transfer_peti/conn/syncronize.dart'; |
|
import 'conn_home_page.dart/syncronize.dart'; |
|
import 'controller/home_controller.dart'; |
|
|
|
class HomePage extends StatefulWidget { |
|
@override |
|
State<HomePage> createState() => _HomePageState(); |
|
} |
|
|
|
class _HomePageState extends State<HomePage> { |
|
String? token; |
|
bool loading = true; |
|
|
|
// Reinit atau Upload Only |
|
WarehouseModel? warehouseSqfliteApi; |
|
List<TypePetiModel>? typePetiSqfliteApi; |
|
List<CustomerModel>? customerSqfliteApi; |
|
PetiAssetModel? petiSqfliteApi; |
|
|
|
List<PetiAssetModel>? _valpeti; // Change this line |
|
List<WarehouseModel>? _valwarehouse; |
|
|
|
// Datatable |
|
int _currentPage = 1; |
|
int _pageSize = 10; |
|
List<AssetStatusModel>? _data; |
|
List<PetiAssetModel>? _petiData; |
|
List<TypePetiModel>? _tipePetiData; |
|
List<CustomerModel>? _customerData; |
|
List<WarehouseModel>? _warehouseData; |
|
Timer? _timer; |
|
|
|
bool _isLoading = true; |
|
|
|
@override |
|
void initState() { |
|
super.initState(); |
|
_getUserToken(); |
|
|
|
// Menerapkan Future untuk menangani tugas asinkronus |
|
Future.wait([ |
|
warehouseListAPI(), |
|
typePetiListAPI(), |
|
customerListAPI(), |
|
petiListAPI(), |
|
datatablesAssetStatusList(), |
|
datatablesPetiList(), |
|
datatablesTipePetiList(), |
|
datatablesCustomerList(), |
|
datatablesWarehouseList(), |
|
]).then((_) { |
|
// Selesaikan loading setelah semua tugas selesai |
|
setState(() { |
|
_isLoading = false; |
|
}); |
|
}); |
|
|
|
// Inisialisasi _data di sini jika diperlukan |
|
_data = <AssetStatusModel>[]; |
|
} |
|
|
|
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<dynamic>) |
|
.map((item) => WarehouseModel.fromJson(item)) |
|
.toList(); |
|
loading = false; |
|
}); |
|
}); |
|
} |
|
} |
|
|
|
Future typePetiListAPI() async { |
|
if (mounted) { |
|
await ControllerApi().fetchTipePetiDataAPI().then((value) { |
|
setState(() { |
|
typePetiSqfliteApi = (value as List<dynamic>) |
|
.map((item) => TypePetiModel.fromJson(item)) |
|
.toList(); |
|
loading = false; |
|
}); |
|
}); |
|
} |
|
} |
|
|
|
Future customerListAPI() async { |
|
if (mounted) { |
|
await ControllerApi().fetchCustomerDataAPI().then((value) { |
|
setState(() { |
|
customerSqfliteApi = (value as List<dynamic>) |
|
.map((item) => CustomerModel.fromJson(item)) |
|
.toList(); |
|
loading = false; |
|
}); |
|
}); |
|
} |
|
} |
|
|
|
Future petiListAPI() async { |
|
if (mounted) { |
|
await ControllerApi().fetchPetiDataAPI().then((value) { |
|
setState(() { |
|
_valpeti = (value as List<dynamic>) |
|
.map((item) => PetiAssetModel.fromJson(item)) |
|
.toList(); |
|
loading = false; |
|
}); |
|
}); |
|
} |
|
} |
|
|
|
Future<void> reinitWarehouseApi() async { |
|
EasyLoading.show(status: 'Mengambil data Warehouse...'); |
|
List<WarehouseModel> warehouseApiData = |
|
await SyncronizationDataAPI().fetchWarehouseFromApi(); |
|
await ControllerApi() |
|
.deleteAllWarehouseDataAPI(); // Clear existing data in SQLite |
|
await ControllerApi() |
|
.addAllWarehouseDataAPI(warehouseApiData); // Add new data to SQLite |
|
EasyLoading.dismiss(); |
|
} |
|
|
|
Future<void> reinitPetiApi() async { |
|
EasyLoading.show(status: 'Mengambil data Peti...'); |
|
List<PetiAssetModel> 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<void> reinitCustomerApi() async { |
|
EasyLoading.show(status: 'Mengambil data Customer...'); |
|
List<CustomerModel> customerApiData = |
|
await SyncronizationDataAPI().fetchCustomerFromApi(); |
|
await ControllerApi() |
|
.deleteAllCustomerDataAPI(); // Clear existing data in SQLite |
|
await ControllerApi() |
|
.addAllCustomerDataAPI(customerApiData); // Add new data to SQLite |
|
EasyLoading.dismiss(); |
|
} |
|
|
|
Future<void> reinitConditionPetiApi() async { |
|
EasyLoading.show(status: 'Mengambil data Condition Peti...'); |
|
List<ConditionPetiModel> conditionPetiApiData = |
|
await SyncronizationDataAPI().fetchKondisiPetiFromApi(); |
|
await ControllerApi() |
|
.deleteAllKondisiPetiDataAPI(); // Clear existing data in SQLite |
|
await ControllerApi().addAllKondisiPetiDataAPI( |
|
conditionPetiApiData); // Add new data to SQLite |
|
EasyLoading.dismiss(); |
|
} |
|
|
|
Future<void> fetchDataFromApiAndSync() async { |
|
EasyLoading.show(status: 'Mengambil data dari Server...'); |
|
try { |
|
// await syncToGlobal(); |
|
await syncToGlobal('Peminjaman'); |
|
await syncToGlobal('Pengembalian'); |
|
await syncToGlobal('Transfer'); |
|
|
|
// await reinitAssetStatusApi(); |
|
await reinitWarehouseApi(); |
|
await reinitPetiApi(); |
|
await reinitCustomerApi(); |
|
// await reinitTypePetiApi(); |
|
await reinitConditionPetiApi(); |
|
|
|
await datatablesAssetStatusList(); |
|
EasyLoading.showSuccess('Data berhasil diperbarui'); |
|
} catch (e) { |
|
EasyLoading.showError('Gagal memperbarui data: $e'); |
|
} finally { |
|
EasyLoading.dismiss(); |
|
} |
|
} |
|
|
|
Future syncToGlobal(String type) async { |
|
try { |
|
EasyLoading.show( |
|
status: 'Jangan tutup aplikasi. Kami sedang menyinkronkan...'); |
|
await Future.delayed(Duration(seconds: 3)); |
|
|
|
// Tambahkan penanganan pengunggahan |
|
bool uploadSuccess = false; // Berikan nilai awal false |
|
|
|
if (type == 'Peminjaman') { |
|
List<AssetStatusModel> peminjamanList = |
|
await SyncronizationGlobalData().fetchAllPeminjamanInfo(); |
|
uploadSuccess = await SyncronizationPeminjamanData() |
|
.saveToPeminjamanWith(peminjamanList); |
|
|
|
// Jika pengunggahan berhasil, hapus data lokal Peminjaman |
|
if (uploadSuccess) { |
|
await SyncronizationGlobalData().deleteAllPeminjamanData(); |
|
} |
|
} else if (type == 'Pengembalian') { |
|
List<AssetStatusModel> pengembalianList = |
|
await SyncronizationGlobalData().fetchAllPengembalianInfo(); |
|
uploadSuccess = await SyncronizationPengembalianData() |
|
.savePengembalianToServerWith(pengembalianList); |
|
|
|
// Jika pengunggahan berhasil, hapus data lokal Pengembalian |
|
if (uploadSuccess) { |
|
await SyncronizationGlobalData().deleteAllPengembalianData(); |
|
} |
|
} else if (type == 'Transfer') { |
|
List<TransferPetiModel> transferPetiList = |
|
await SyncronizationGlobalData().fetchAllTransferInfo(); |
|
uploadSuccess = await SyncronizationTransferPetiData() |
|
.saveTransferPetiServerWith(transferPetiList); |
|
|
|
// Jika pengunggahan berhasil, hapus data lokal Pengembalian |
|
if (uploadSuccess) { |
|
await SyncronizationGlobalData().deleteAllTransferData(); |
|
} |
|
} |
|
|
|
// Setelah selesai, tampilkan pesan sukses atau gagal |
|
if (uploadSuccess) { |
|
EasyLoading.showSuccess('Berhasil disinkronkan dengan Server'); |
|
} else { |
|
EasyLoading.showError('Gagal disinkronkan dengan Server'); |
|
} |
|
} catch (error) { |
|
// Handle error jika terjadi |
|
EasyLoading.showError('Terjadi kesalahan: $error'); |
|
} |
|
} |
|
|
|
Future<void> isInteret() async { |
|
await SyncronizationGlobalData.isInternet().then((connection) { |
|
if (connection) { |
|
print("Internet connection available"); |
|
} else { |
|
ScaffoldMessenger.of(context) |
|
.showSnackBar(SnackBar(content: Text("No Internet"))); |
|
} |
|
}); |
|
} |
|
|
|
// Datatables ------------------------------------------------------------------------ |
|
Future datatablesAssetStatusList() async { |
|
await Controller().fetchAssetStatusLocalController().then((value) { |
|
setState(() { |
|
_data = (value as List<dynamic>) |
|
.map((e) => AssetStatusModel.fromJson(e)) |
|
.toList(); |
|
loading = false; |
|
}); |
|
}); |
|
} |
|
|
|
Future datatablesPetiList() async { |
|
await Controller().fetchPetiData().then((value) { |
|
setState(() { |
|
_petiData = (value as List<dynamic>) |
|
.map((e) => PetiAssetModel.fromJson(e)) |
|
.toList(); |
|
loading = false; |
|
}); |
|
}); |
|
} |
|
|
|
Future datatablesTipePetiList() async { |
|
await Controller().fetchTipePetiData().then((value) { |
|
setState(() { |
|
_tipePetiData = (value as List<dynamic>) |
|
.map((e) => TypePetiModel.fromJson(e)) |
|
.toList(); |
|
loading = false; |
|
}); |
|
}); |
|
} |
|
|
|
Future datatablesCustomerList() async { |
|
await Controller().fetchCustomerData().then((value) { |
|
setState(() { |
|
_customerData = (value as List<dynamic>) |
|
.map((e) => CustomerModel.fromJson(e)) |
|
.toList(); |
|
loading = false; |
|
}); |
|
}); |
|
} |
|
|
|
Future datatablesWarehouseList() async { |
|
await Controller().fetchWarehouseData().then((value) { |
|
setState(() { |
|
_warehouseData = (value as List<dynamic>) |
|
.map((e) => WarehouseModel.fromJson(e)) |
|
.toList(); |
|
loading = false; |
|
}); |
|
}); |
|
} |
|
|
|
@override |
|
void dispose() { |
|
// Memastikan untuk membatalkan timer saat widget di-dispose |
|
super.dispose(); |
|
} |
|
|
|
@override |
|
Widget build(BuildContext context) { |
|
AuthProvider authProvider = Provider.of<AuthProvider>(context); |
|
UserModel user = authProvider.user; |
|
// String? token = authProvider.token; |
|
|
|
Widget cardMenuPeminjaman() { |
|
return Container( |
|
margin: EdgeInsets.all(10), |
|
child: Card( |
|
shape: RoundedRectangleBorder( |
|
borderRadius: BorderRadius.circular(15.0), |
|
), |
|
elevation: 5, |
|
child: InkWell( |
|
onTap: () { |
|
// Aksi ketika card diklik |
|
Navigator.pushNamed(context, '/peminjaman-barang'); |
|
}, |
|
child: Container( |
|
padding: EdgeInsets.all(16.0), |
|
child: Column( |
|
mainAxisAlignment: MainAxisAlignment.center, |
|
children: [ |
|
Icon( |
|
Icons.vertical_align_top, |
|
size: 50, |
|
color: Colors.greenAccent[700], |
|
), |
|
SizedBox(height: 10), |
|
Text( |
|
'Peminjaman', |
|
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), |
|
), |
|
], |
|
), |
|
), |
|
), |
|
), |
|
); |
|
} |
|
|
|
Widget cardMenuPengembalian() { |
|
return Container( |
|
margin: EdgeInsets.all(10), |
|
child: Card( |
|
shape: RoundedRectangleBorder( |
|
borderRadius: BorderRadius.circular(15.0), |
|
), |
|
elevation: 5, |
|
child: InkWell( |
|
onTap: () { |
|
// Aksi ketika card diklik |
|
Navigator.pushNamed(context, '/pengembalian-barang'); |
|
}, |
|
child: Container( |
|
padding: EdgeInsets.all(16.0), |
|
child: Column( |
|
mainAxisAlignment: MainAxisAlignment.center, |
|
children: [ |
|
Icon( |
|
Icons.vertical_align_bottom, |
|
size: 50, |
|
color: Colors.blueAccent[700], |
|
), |
|
SizedBox(height: 10), |
|
Text( |
|
'Pengembalian', |
|
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), |
|
), |
|
], |
|
), |
|
), |
|
), |
|
), |
|
); |
|
} |
|
|
|
Widget cardTotal(String title, int total, IconData icon) { |
|
return Expanded( |
|
child: Card( |
|
margin: EdgeInsets.all(5), |
|
child: Container( |
|
padding: EdgeInsets.all(5), |
|
child: Column( |
|
mainAxisAlignment: MainAxisAlignment.center, |
|
children: <Widget>[ |
|
Icon( |
|
icon, |
|
size: 20, |
|
color: Colors.blue[700], |
|
), |
|
SizedBox(height: 2), |
|
Text( |
|
title, |
|
style: TextStyle( |
|
fontSize: 8, |
|
fontWeight: FontWeight.bold, |
|
), |
|
textAlign: TextAlign.center, |
|
), |
|
SizedBox(height: 2), |
|
Text( |
|
total.toString(), |
|
style: TextStyle( |
|
fontSize: 14, |
|
fontWeight: FontWeight.bold, |
|
color: Colors.blue[700], |
|
), |
|
), |
|
], |
|
), |
|
), |
|
), |
|
); |
|
} |
|
|
|
Widget cardMenuTransfer() { |
|
return Container( |
|
margin: EdgeInsets.all(10), |
|
child: Card( |
|
shape: RoundedRectangleBorder( |
|
borderRadius: BorderRadius.circular(15.0), |
|
), |
|
elevation: 5, |
|
child: InkWell( |
|
onTap: () { |
|
// Aksi ketika card diklik |
|
Navigator.pushNamed(context, '/transfer-peti'); |
|
}, |
|
child: Container( |
|
padding: EdgeInsets.all(16.0), |
|
child: Column( |
|
mainAxisAlignment: MainAxisAlignment.center, |
|
children: [ |
|
Icon( |
|
Icons.input_outlined, |
|
size: 50, |
|
color: Colors.yellow[700], |
|
), |
|
SizedBox(height: 10), |
|
Text( |
|
'Transfer Peti', |
|
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), |
|
), |
|
], |
|
), |
|
), |
|
), |
|
), |
|
); |
|
} |
|
|
|
Widget _buildCountTile(IconData icon, int count, Color color, String text) { |
|
return Column( |
|
children: [ |
|
CircleAvatar( |
|
backgroundColor: color, |
|
radius: 12, |
|
child: Icon(icon, size: 12, color: Colors.white), |
|
), |
|
SizedBox(height: 4), |
|
Text( |
|
text, |
|
style: TextStyle( |
|
fontSize: 12, |
|
fontWeight: FontWeight.bold, |
|
), |
|
), |
|
Text( |
|
'$count', |
|
style: TextStyle(fontSize: 12), |
|
), |
|
], |
|
); |
|
} |
|
|
|
Future<void> showSyncDialog(BuildContext context) async { |
|
// Create an instance of ControllerHome |
|
ControllerHome controllerHome = ControllerHome(); |
|
|
|
// Fetch counts from the ControllerHome |
|
int peminjamanCount = await controllerHome.getPeminjamanCount(); |
|
int pengembalianCount = await controllerHome.getPengembalianCount(); |
|
int transferCount = await controllerHome.getTransferCount(); |
|
|
|
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 Global", |
|
style: TextStyle( |
|
color: Colors.white, |
|
fontWeight: FontWeight.bold, |
|
fontSize: 20.0, |
|
), |
|
), |
|
), |
|
IconButton( |
|
icon: Icon( |
|
Icons.close, |
|
color: Colors.white, |
|
), |
|
onPressed: () { |
|
Navigator.pop(context); // Close dialog |
|
}, |
|
), |
|
], |
|
), |
|
), |
|
|
|
Divider( |
|
height: 1, |
|
thickness: 1, |
|
color: Colors.black, // Black divider |
|
), |
|
// Display counts for each table |
|
SizedBox(height: 10), |
|
Row( |
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly, |
|
children: [ |
|
_buildCountTile(Icons.vertical_align_top, peminjamanCount, |
|
Colors.green[700]!, 'Peminjaman'), |
|
_buildCountTile(Icons.vertical_align_bottom, |
|
pengembalianCount, Colors.blue[700]!, 'Pengembalian'), |
|
_buildCountTile(Icons.input_outlined, transferCount, |
|
Colors.yellow[700]!, 'Transfer'), |
|
], |
|
), |
|
SizedBox(height: 10), |
|
// 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 |
|
// syncToGlobal('Peminjaman'); |
|
// syncToGlobal('Pengembalian'); |
|
// syncToGlobal('Transfer'); |
|
// }, |
|
// child: Text( |
|
// "Upload Only", |
|
// style: TextStyle( |
|
// color: Colors.black, |
|
// fontSize: 16.0, |
|
// fontFamily: 'Poppins', |
|
// ), |
|
// ), |
|
// ), |
|
// ), |
|
], |
|
), |
|
); |
|
}, |
|
); |
|
} |
|
|
|
return Scaffold( |
|
backgroundColor: Colors.grey[200], |
|
appBar: AppBar( |
|
elevation: 0, |
|
automaticallyImplyLeading: false, |
|
backgroundColor: Colors.indigo[700], |
|
actions: [ |
|
IconButton( |
|
icon: Icon( |
|
Icons.cloud_sync, |
|
size: 30, |
|
), |
|
onPressed: () async { |
|
if (await SyncronizationGlobalData.isInternet()) { |
|
// Display custom dialog when the IconButton is pressed |
|
showSyncDialog(context); |
|
} else { |
|
ScaffoldMessenger.of(context).showSnackBar( |
|
SnackBar(content: Text("No internet connection")), |
|
); |
|
} |
|
}, |
|
), |
|
], |
|
title: Row( |
|
children: [ |
|
SizedBox(width: 10), |
|
Expanded( |
|
child: Center( |
|
child: Column( |
|
children: [ |
|
Text( |
|
'SIOPAS-ISTW', |
|
textAlign: TextAlign.center, |
|
), |
|
Text( |
|
'${user.fullname}', |
|
style: TextStyle( |
|
fontSize: 10, |
|
), |
|
), |
|
], |
|
), |
|
), |
|
), |
|
], |
|
), |
|
), |
|
body: ListView( |
|
children: [ |
|
GridView.count( |
|
crossAxisCount: 2, |
|
shrinkWrap: true, |
|
physics: NeverScrollableScrollPhysics(), |
|
children: [ |
|
cardMenuPeminjaman(), |
|
cardMenuPengembalian(), |
|
cardMenuTransfer(), |
|
], |
|
), |
|
], |
|
), |
|
); |
|
} |
|
}
|
|
|