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.
786 lines
24 KiB
786 lines
24 KiB
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: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/peminjaman_barang/conn/syncronize.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:siopas/providers/asset_status_provider.dart'; |
|
import 'package:collection/collection.dart'; |
|
|
|
import '../../models/condition_peti_model.dart'; |
|
import 'show.dart'; |
|
|
|
class AssetStatusPage extends StatefulWidget { |
|
const AssetStatusPage({super.key}); |
|
|
|
@override |
|
State<AssetStatusPage> createState() => AssetStatusPageState(); |
|
} |
|
|
|
class AssetStatusPageState extends State<AssetStatusPage> { |
|
String? token; |
|
bool loading = true; |
|
|
|
// Reinit atau Upload Only |
|
WarehouseModel? warehouseSqfliteApi; |
|
List<TypePetiModel>? typePetiSqfliteApi; |
|
List<CustomerModel>? customerSqfliteApi; |
|
PetiAssetModel? petiSqfliteApi; |
|
DisposalPetiModel? disposalSqfliteApi; |
|
|
|
List<PetiAssetModel>? _valpeti; // Change this line |
|
List<WarehouseModel>? _valwarehouse; |
|
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; |
|
|
|
bool _isLoading = false; |
|
Timer? _timer; |
|
|
|
@override |
|
void initState() { |
|
super.initState(); |
|
_getUserToken(); |
|
|
|
warehouseListAPI(); |
|
typePetiListAPI(); |
|
customerListAPI(); |
|
petiListAPI(); |
|
// disposalListAPI(); |
|
|
|
// Tampil data Datatables |
|
datatablesAssetStatusList(); |
|
datatablesPetiList(); |
|
datatablesTipePetiList(); |
|
datatablesCustomerList(); |
|
datatablesWarehouseList(); |
|
_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<void> reinitAssetStatusApi() async { |
|
EasyLoading.show(status: 'Mengambil data Asset Status...'); |
|
List<AssetStatusModel> assetStatusApiData = |
|
await SyncronizationDataAPI().fetchAssetStatusFromApi(); |
|
await ControllerApi() |
|
.deleteAllAssetStatusDataAPI(); // Clear existing data in SQLite |
|
await ControllerApi() |
|
.addAllAssetStatusDataAPI(assetStatusApiData); // Add new data to SQLite |
|
EasyLoading.dismiss(); |
|
} |
|
|
|
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 |
|
await ControllerApi() |
|
.addAllPetiDataAPI(petiApiData); // Add new data to SQLite |
|
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> reinitTypePetiApi() async { |
|
EasyLoading.show(status: 'Mengambil data Type Peti...'); |
|
List<TypePetiModel> typePetiApiData = |
|
await SyncronizationDataAPI().fetchTipePetiFromApi(); |
|
await ControllerApi() |
|
.deleteAllTipePetiDataAPI(); // Clear existing data in SQLite |
|
await ControllerApi() |
|
.addAllTipePetiDataAPI(typePetiApiData); // 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...'); |
|
await Future.delayed(Duration(seconds: 3)); |
|
|
|
try { |
|
await syncToMysql(); |
|
|
|
// await reinitAssetStatusApi(); |
|
await reinitWarehouseApi(); |
|
await reinitPetiApi(); |
|
await reinitCustomerApi(); |
|
// await reinitTypePetiApi(); |
|
await reinitConditionPetiApi(); |
|
// await reinitDisposalApi(); |
|
|
|
await datatablesAssetStatusList(); |
|
EasyLoading.showSuccess('Data berhasil diperbarui'); |
|
} catch (e) { |
|
EasyLoading.showError('Gagal memperbarui data: $e'); |
|
} finally { |
|
EasyLoading.dismiss(); |
|
} |
|
} |
|
|
|
Future syncToMysql() async { |
|
await SyncronizationPeminjamanData() |
|
.fetchAllInfo() |
|
.then((peminjamanList) async { |
|
EasyLoading.show( |
|
status: 'Jangan tutup aplikasi. Kami sedang menyinkronkan...'); |
|
await Future.delayed(Duration(seconds: 3)); |
|
|
|
// Tambahkan penanganan pengunggahan |
|
bool uploadSuccess = await SyncronizationPeminjamanData() |
|
.saveToPeminjamanWith(peminjamanList); |
|
|
|
// Jika pengunggahan berhasil, hapus data lokal |
|
if (uploadSuccess) { |
|
await SyncronizationPeminjamanData().deleteAllAssetStatusData(); |
|
// Setelah selesai, tampilkan pesan sukses |
|
EasyLoading.showSuccess('Berhasil disinkronkan dengan Server'); |
|
await datatablesAssetStatusList(); |
|
} 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 SyncronizationPeminjamanData.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; |
|
}); |
|
}); |
|
} |
|
|
|
void _loadMoreData() { |
|
if (mounted && !_isLoading) { |
|
setState(() { |
|
_currentPage++; |
|
}); |
|
datatablesAssetStatusList(); |
|
} |
|
} |
|
|
|
@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 Peminjaman", |
|
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 Peminjaman Barang', |
|
style: TextStyle( |
|
fontSize: 16, |
|
)), |
|
actions: [ |
|
IconButton( |
|
icon: Icon(Icons.backup), |
|
onPressed: () async { |
|
if (await SyncronizationPeminjamanData.isInternet()) { |
|
// Display custom dialog when the IconButton is pressed |
|
showSyncDialog(context); |
|
} else { |
|
ScaffoldMessenger.of(context).showSnackBar( |
|
SnackBar(content: Text("No internet connection")), |
|
); |
|
} |
|
}, |
|
), |
|
], |
|
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: 'Peminjaman Hari ini'), |
|
], |
|
), |
|
), |
|
body: _isLoading |
|
? const Center(child: CircularProgressIndicator()) |
|
: 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) { |
|
setState(() { |
|
_pageSize = value!; |
|
}); |
|
}, |
|
columns: [ |
|
DataColumn(label: Text('No')), |
|
DataColumn(label: Text('')), |
|
DataColumn(label: Text('Kode Peti')), |
|
DataColumn(label: Text('Nama Customer')), |
|
DataColumn(label: Text('Tgl Peminjaman')), |
|
DataColumn(label: Text('Est Peminjaman')), |
|
DataColumn(label: Text('PJ Peminjaman')), |
|
DataColumn(label: Text('Asal Gudang')), |
|
DataColumn(label: Text('Tujuan Gudang')), |
|
], |
|
source: _DataSourceLokal( |
|
data: _data!, |
|
context: context, |
|
petiData: _petiData != null ? _petiData : [], |
|
tipePetiData: |
|
_tipePetiData != null ? _tipePetiData : [], |
|
customerData: |
|
_customerData != null ? _customerData : [], |
|
warehouseData: |
|
_warehouseData != null ? _warehouseData : [], |
|
), |
|
), |
|
), |
|
], |
|
), |
|
), |
|
], |
|
), |
|
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, '/peminjaman-barang/create'); |
|
}, |
|
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; |
|
final BuildContext context; |
|
|
|
_DataSourceLokal({ |
|
required this.data, |
|
required this.petiData, |
|
required this.tipePetiData, |
|
required this.customerData, |
|
required this.warehouseData, |
|
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 == item.customer_id, |
|
orElse: () => CustomerModel( |
|
id: null, |
|
name: 'null', |
|
code_customer: 'null', |
|
lot_no: 'null', |
|
created_by: 'null', |
|
updated_by: 'null', |
|
), |
|
); |
|
} |
|
|
|
WarehouseModel? warehouseSqfliteApi; |
|
if (item.warehouse_id != null) { |
|
warehouseSqfliteApi = warehouseData?.firstWhere( |
|
(warehouse) => warehouse.id == item.warehouse_id, |
|
orElse: () => WarehouseModel( |
|
id: null, |
|
name: 'null', |
|
created_by: 'null', |
|
updated_by: 'null', |
|
), |
|
); |
|
} |
|
|
|
WarehouseModel? warehouseTujuanSqfliteApi; |
|
warehouseTujuanSqfliteApi = warehouseData?.firstWhereOrNull( |
|
(warehouse) => warehouse.id == item.exit_warehouse, |
|
); |
|
|
|
return DataRow(cells: [ |
|
DataCell( |
|
Text( |
|
(index + 1).toString(), |
|
), |
|
), |
|
DataCell( |
|
GestureDetector( |
|
onTap: () { |
|
if (item.id != null) { |
|
Navigator.push( |
|
context, |
|
MaterialPageRoute( |
|
builder: (context) => DetailPeminjamanBarangPage( |
|
peminjamanId: 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( |
|
customerSqfliteApi != null && customerSqfliteApi.name != null |
|
? customerSqfliteApi!.name.toString() |
|
: '-', |
|
), |
|
), |
|
DataCell( |
|
Text( |
|
item.exit_at != null |
|
? DateFormat('dd-MM-yyyy').format(item.exit_at!) |
|
: '-', |
|
), |
|
), |
|
DataCell( |
|
Text( |
|
item.est_pengembalian != null |
|
? DateFormat('dd-MM-yyyy').format(item.est_pengembalian!) |
|
: '-', |
|
), |
|
), |
|
DataCell( |
|
Text( |
|
item.exit_pic != null ? item.exit_pic.toString() : '-', |
|
), |
|
), |
|
DataCell( |
|
Text( |
|
warehouseSqfliteApi != null && warehouseSqfliteApi.name != null |
|
? warehouseSqfliteApi.name.toString() |
|
: '-', |
|
), |
|
), |
|
DataCell( |
|
Text( |
|
warehouseTujuanSqfliteApi != null && |
|
warehouseTujuanSqfliteApi.name != null |
|
? warehouseTujuanSqfliteApi.name.toString() |
|
: '-', |
|
), |
|
), |
|
]); |
|
} |
|
|
|
@override |
|
bool get isRowCountApproximate => false; |
|
|
|
@override |
|
int get rowCount => data.length; |
|
|
|
@override |
|
int get selectedRowCount => 0; |
|
}
|
|
|