Siopas Inventory PETI for ISTW Mobile
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.

802 lines
25 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/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;
bool _isLoading = false;
Timer? _timer;
@override
void initState() {
super.initState();
_getUserToken();
warehouseListAPI();
conditionPetiListAPI();
typePetiListAPI();
customerListAPI();
petiListAPI();
// disposalListAPI();
// Tampil data Datatables
datatablesPengembalianList();
datatablesPetiList();
datatablesTipePetiList();
datatablesCustomerList();
datatablesWarehouseList();
datatablesConditionList();
_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
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> 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("No Internet")));
}
});
}
// Datatables ------------------------------------------------------------------------
Future datatablesPengembalianList() async {
await ControllerPengembalian()
.fetchPengembalianLocalController()
.then((value) {
setState(() {
_data = (value as List<dynamic>)
.map((e) => AssetStatusModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesPetiList() async {
await ControllerPengembalian().fetchPetiData().then((value) {
setState(() {
_petiData = (value as List<dynamic>)
.map((e) => PetiAssetModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesTipePetiList() async {
await ControllerPengembalian().fetchTipePetiData().then((value) {
setState(() {
_tipePetiData = (value as List<dynamic>)
.map((e) => TypePetiModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesCustomerList() async {
await ControllerPengembalian().fetchCustomerData().then((value) {
setState(() {
_customerData = (value as List<dynamic>)
.map((e) => CustomerModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesWarehouseList() async {
await ControllerPengembalian().fetchWarehouseData().then((value) {
setState(() {
_warehouseData = (value as List<dynamic>)
.map((e) => WarehouseModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesConditionList() async {
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 Barang',
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("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: 'Pengembalian Peti 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('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;
}