|
|
|
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<PengembalianBarangPage> createState() => PengembalianBarangPageState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class PengembalianBarangPageState extends State<PengembalianBarangPage> {
|
|
|
|
String? token;
|
|
|
|
bool loading = true;
|
|
|
|
|
|
|
|
// Reinit atau Upload Only
|
|
|
|
WarehouseModel? warehouseSqfliteApi;
|
|
|
|
List<TypePetiModel>? typePetiSqfliteApi;
|
|
|
|
List<CustomerModel>? customerSqfliteApi;
|
|
|
|
PetiAssetModel? petiSqfliteApi;
|
|
|
|
ConditionPetiModel? conditionPetiSqfliteApi;
|
|
|
|
DisposalPetiModel? disposalSqfliteApi;
|
|
|
|
|
|
|
|
List<PetiAssetModel>? _valpeti; // Change this line
|
|
|
|
List<WarehouseModel>? _valwarehouse;
|
|
|
|
List<ConditionPetiModel>? _valconditionPeti;
|
|
|
|
List<DisposalPetiModel>? _valdisposal;
|
|
|
|
|
|
|
|
// Datatable
|
|
|
|
int _currentPage = 1;
|
|
|
|
int _pageSize = 10;
|
|
|
|
List<AssetStatusModel>? _data;
|
|
|
|
List<PetiAssetModel>? _petiData;
|
|
|
|
List<TypePetiModel>? _tipePetiData;
|
|
|
|
List<CustomerModel>? _customerData;
|
|
|
|
List<WarehouseModel>? _warehouseData;
|
|
|
|
List<ConditionPetiModel>? _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 = <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 disposalListAPI() async {
|
|
|
|
// if (mounted) {
|
|
|
|
// await ControllerApi().fetchDisposalDataAPI().then((value) {
|
|
|
|
// setState(() {
|
|
|
|
// _valdisposal = (value as List<dynamic>)
|
|
|
|
// .map((item) => DisposalPetiModel.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 conditionPetiListAPI() async {
|
|
|
|
if (mounted) {
|
|
|
|
await ControllerApi().fetchKondisiPetiDataAPI().then((value) {
|
|
|
|
setState(() {
|
|
|
|
_valconditionPeti = (value as List<dynamic>)
|
|
|
|
.map((item) => ConditionPetiModel.fromJson(item))
|
|
|
|
.toList();
|
|
|
|
loading = false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Future<void> reinitAssetStatusApi() async {
|
|
|
|
// List<AssetStatusModel> assetStatusApiData =
|
|
|
|
// await SyncronizationDataAPI().fetchAssetStatusFromApi();
|
|
|
|
// await ControllerApi()
|
|
|
|
// .deleteAllAssetStatusDataAPI(); // Clear existing data in SQLite
|
|
|
|
// await ControllerApi()
|
|
|
|
// .addAllAssetStatusDataAPI(assetStatusApiData); // Add new data to SQLite
|
|
|
|
// }
|
|
|
|
|
|
|
|
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> reinitDisposalApi() async {
|
|
|
|
// List<DisposalPetiModel> disposalApiData =
|
|
|
|
// await SyncronizationDataAPI().fetchDisposalFromApi();
|
|
|
|
// await ControllerApi()
|
|
|
|
// .deleteAllDisposalDataAPI(); // Clear existing data in SQLite
|
|
|
|
// await ControllerApi()
|
|
|
|
// .addAllDisposalDataAPI(disposalApiData); // Add new data to SQLite
|
|
|
|
// }
|
|
|
|
|
|
|
|
Future<void> 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<void> 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<dynamic>)
|
|
|
|
.map((e) => AssetStatusModel.fromJson(e))
|
|
|
|
.toList();
|
|
|
|
loading = false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future datatablesPetiList() async {
|
|
|
|
if (mounted) {
|
|
|
|
await ControllerPengembalian().fetchPetiData().then((value) {
|
|
|
|
setState(() {
|
|
|
|
_petiData = (value as List<dynamic>)
|
|
|
|
.map((e) => PetiAssetModel.fromJson(e))
|
|
|
|
.toList();
|
|
|
|
loading = false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future datatablesTipePetiList() async {
|
|
|
|
if (mounted) {
|
|
|
|
await ControllerPengembalian().fetchTipePetiData().then((value) {
|
|
|
|
setState(() {
|
|
|
|
_tipePetiData = (value as List<dynamic>)
|
|
|
|
.map((e) => TypePetiModel.fromJson(e))
|
|
|
|
.toList();
|
|
|
|
loading = false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future datatablesCustomerList() async {
|
|
|
|
if (mounted) {
|
|
|
|
await ControllerPengembalian().fetchCustomerData().then((value) {
|
|
|
|
setState(() {
|
|
|
|
_customerData = (value as List<dynamic>)
|
|
|
|
.map((e) => CustomerModel.fromJson(e))
|
|
|
|
.toList();
|
|
|
|
loading = false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future datatablesWarehouseList() async {
|
|
|
|
if (mounted) {
|
|
|
|
await ControllerPengembalian().fetchWarehouseData().then((value) {
|
|
|
|
setState(() {
|
|
|
|
_warehouseData = (value as List<dynamic>)
|
|
|
|
.map((e) => WarehouseModel.fromJson(e))
|
|
|
|
.toList();
|
|
|
|
loading = false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future datatablesConditionList() async {
|
|
|
|
if (mounted) {
|
|
|
|
await ControllerPengembalian().fetchConditionData().then((value) {
|
|
|
|
setState(() {
|
|
|
|
_conditionData = (value as List<dynamic>)
|
|
|
|
.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: <Widget>[
|
|
|
|
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<AssetStatusModel> data;
|
|
|
|
List<PetiAssetModel>? petiData;
|
|
|
|
List<TypePetiModel>? tipePetiData;
|
|
|
|
List<CustomerModel>? customerData;
|
|
|
|
List<WarehouseModel>? warehouseData;
|
|
|
|
List<ConditionPetiModel>? 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;
|
|
|
|
}
|