Browse Source

perbaikan sistem peminjaman, scan qr code, dropdown peti, list peti, pembuatan create finish, pembaharuan tampilan peminjaman, search peminjaman, total peminjaman, perubahan tampilan dashboard home

master
unknown 9 months ago
parent
commit
daa21c4f8b
  1. BIN
      assets/item/empty.png
  2. 1
      lib/main.dart
  3. 5
      lib/migrations/databasehelper.dart
  4. 12
      lib/models/asset_status_model.dart
  5. 7
      lib/models/m_asset_status_model.dart
  6. 8
      lib/pages/home/conn_home_page.dart/syncronize.dart
  7. 484
      lib/pages/home/home_page.dart
  8. 8
      lib/pages/home/main_page.dart
  9. 8
      lib/pages/home/setting_page.dart
  10. 6
      lib/pages/peminjaman_barang/conn/syncronize.dart
  11. 4
      lib/pages/peminjaman_barang/controller/peminjaman_controller.dart
  12. 873
      lib/pages/peminjaman_barang/create-finish.dart
  13. 1813
      lib/pages/peminjaman_barang/create.dart
  14. 1175
      lib/pages/peminjaman_barang/peminjaman_stock_page.dart
  15. 260
      lib/pages/peminjaman_barang/show.dart
  16. 227
      lib/pages/pengembalian_barang/edit.dart
  17. 130
      lib/pages/pengembalian_barang/index.dart
  18. 22
      lib/pages/pengembalian_barang/show.dart
  19. 9
      lib/pages/sign_in_page.dart
  20. 6
      lib/pages/transfer_peti/index.dart
  21. 13
      lib/widget/component_query.dart
  22. 299
      lib/widget/loading_shimmer_show.dart
  23. 8
      pubspec.lock
  24. 2
      pubspec.yaml

BIN
assets/item/empty.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

1
lib/main.dart

@ -1,6 +1,7 @@
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:siopas/migrations/databasehelper.dart'; import 'package:siopas/migrations/databasehelper.dart';
import 'package:siopas/pages/peminjaman_barang/create-finish.dart';
import 'package:siopas/pages/transfer_peti/edit.dart'; import 'package:siopas/pages/transfer_peti/edit.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';

5
lib/migrations/databasehelper.dart

@ -24,6 +24,8 @@ class SqfliteDatabaseHelper {
// static final assetLocalTable = 'asset_statuses_local'; // static final assetLocalTable = 'asset_statuses_local';
static final peminjamanTable = 'peminjamans'; static final peminjamanTable = 'peminjamans';
static final temporaryPeminjamanTable = 'temporary_peminjamans';
static final pengembalianTable = 'pengembalians'; static final pengembalianTable = 'pengembalians';
static final _version = 1; // Versi database ditingkatkan static final _version = 1; // Versi database ditingkatkan
@ -73,7 +75,6 @@ class SqfliteDatabaseHelper {
exit_at DATETIME NULL, exit_at DATETIME NULL,
est_pengembalian DATETIME NULL, est_pengembalian DATETIME NULL,
exit_pic TEXT NULL, exit_pic TEXT NULL,
exit_warehouse INTEGER NULL,
enter_at DATETIME NULL, enter_at DATETIME NULL,
enter_pic TEXT NULL, enter_pic TEXT NULL,
enter_warehouse INTEGER NULL, enter_warehouse INTEGER NULL,
@ -97,7 +98,6 @@ class SqfliteDatabaseHelper {
exit_at DATETIME NULL, exit_at DATETIME NULL,
est_pengembalian DATETIME NULL, est_pengembalian DATETIME NULL,
exit_pic TEXT NULL, exit_pic TEXT NULL,
exit_warehouse INTEGER NULL,
enter_at DATETIME NULL, enter_at DATETIME NULL,
enter_pic TEXT NULL, enter_pic TEXT NULL,
enter_warehouse INTEGER NULL, enter_warehouse INTEGER NULL,
@ -121,7 +121,6 @@ class SqfliteDatabaseHelper {
exit_at DATETIME NULL, exit_at DATETIME NULL,
est_pengembalian DATETIME NULL, est_pengembalian DATETIME NULL,
exit_pic TEXT NULL, exit_pic TEXT NULL,
exit_warehouse INTEGER NULL,
enter_at DATETIME NULL, enter_at DATETIME NULL,
enter_pic TEXT NULL, enter_pic TEXT NULL,
enter_warehouse INTEGER NULL, enter_warehouse INTEGER NULL,

12
lib/models/asset_status_model.dart

@ -9,7 +9,7 @@ class AssetStatusModel {
int? warehouse_id; int? warehouse_id;
DateTime? exit_at; DateTime? exit_at;
String? exit_pic; String? exit_pic;
int? exit_warehouse; // int? exit_warehouse;
DateTime? enter_at; DateTime? enter_at;
String? enter_pic; String? enter_pic;
int? enter_warehouse; int? enter_warehouse;
@ -33,7 +33,7 @@ class AssetStatusModel {
this.warehouse_id, this.warehouse_id,
this.exit_at, this.exit_at,
this.exit_pic, this.exit_pic,
this.exit_warehouse, // this.exit_warehouse,
this.enter_at, this.enter_at,
this.enter_pic, this.enter_pic,
this.enter_warehouse, this.enter_warehouse,
@ -64,9 +64,9 @@ class AssetStatusModel {
: 0, : 0,
exit_at: parseDateTime(json['exit_at']), exit_at: parseDateTime(json['exit_at']),
exit_pic: json['exit_pic'], exit_pic: json['exit_pic'],
exit_warehouse: json['exit_warehouse'] != null // exit_warehouse: json['exit_warehouse'] != null
? int.parse(json['exit_warehouse'].toString()) // ? int.parse(json['exit_warehouse'].toString())
: 0, // : 0,
enter_at: parseDateTime(json['enter_at']), enter_at: parseDateTime(json['enter_at']),
enter_pic: json['enter_pic'], enter_pic: json['enter_pic'],
enter_warehouse: json['enter_warehouse'] != null enter_warehouse: json['enter_warehouse'] != null
@ -92,7 +92,7 @@ class AssetStatusModel {
'warehouse_id': warehouse_id, 'warehouse_id': warehouse_id,
'exit_at': exit_at?.toIso8601String(), 'exit_at': exit_at?.toIso8601String(),
'exit_pic': exit_pic.toString(), 'exit_pic': exit_pic.toString(),
'exit_warehouse': exit_warehouse, // 'exit_warehouse': exit_warehouse,
'enter_at': enter_at?.toIso8601String(), 'enter_at': enter_at?.toIso8601String(),
'enter_pic': enter_pic, 'enter_pic': enter_pic,
'enter_warehouse': enter_warehouse?.toString(), 'enter_warehouse': enter_warehouse?.toString(),

7
lib/models/m_asset_status_model.dart

@ -6,7 +6,7 @@ class PetiAssetModel {
int? id; int? id;
int? tipe_peti_id; int? tipe_peti_id;
String? warna; String? warna;
final String fix_lot; String? fix_lot;
int? packing_no; int? packing_no;
int? customer_id; int? customer_id;
int? jumlah; int? jumlah;
@ -47,7 +47,7 @@ class PetiAssetModel {
? int.parse(json['tipe_peti_id'].toString()) ? int.parse(json['tipe_peti_id'].toString())
: null, : null,
warna: json['warna'] != null ? json['warna'].toString() : null, warna: json['warna'] != null ? json['warna'].toString() : null,
fix_lot: json['fix_lot'], fix_lot: json['fix_lot'] != null ? json['fix_lot'].toString() : null,
packing_no: json['packing_no'] != null packing_no: json['packing_no'] != null
? int.parse(json['packing_no'].toString()) ? int.parse(json['packing_no'].toString())
: null, : null,
@ -95,7 +95,8 @@ class PetiAssetModel {
'kondisipeti_id': kondisipeti_id, 'kondisipeti_id': kondisipeti_id,
'status': status, 'status': status,
'jumlah': jumlah, 'jumlah': jumlah,
'date_pembuatan': date_pembuatan!.toIso8601String(), 'date_pembuatan':
date_pembuatan != null ? date_pembuatan.toString() : null,
'created_by': created_by, 'created_by': created_by,
'updated_by': updated_by, 'updated_by': updated_by,
'created_at': created_at!.toIso8601String(), 'created_at': created_at!.toIso8601String(),

8
lib/pages/home/conn_home_page.dart/syncronize.dart

@ -148,11 +148,12 @@ class SyncronizationGlobalData {
Map<String, dynamic> data = { Map<String, dynamic> data = {
"mobile_id": assetStatusesLocalList[i].mobile_id.toString(), "mobile_id": assetStatusesLocalList[i].mobile_id.toString(),
"peti_id": assetStatusesLocalList[i].peti_id.toString(), "peti_id": assetStatusesLocalList[i].peti_id.toString(),
"warehouse_id": assetStatusesLocalList[i].warehouse_id.toString(),
"exit_at": assetStatusesLocalList[i].exit_at.toString(), "exit_at": assetStatusesLocalList[i].exit_at.toString(),
"est_pengembalian": "est_pengembalian":
assetStatusesLocalList[i].est_pengembalian.toString(), assetStatusesLocalList[i].est_pengembalian.toString(),
"exit_pic": assetStatusesLocalList[i].exit_pic.toString(), "exit_pic": assetStatusesLocalList[i].exit_pic.toString(),
"exit_warehouse": assetStatusesLocalList[i].exit_warehouse.toString(), // "exit_warehouse": assetStatusesLocalList[i].exit_warehouse.toString(),
// "status": assetStatusesLocalList[i].status.toString(), // "status": assetStatusesLocalList[i].status.toString(),
"created_by": assetStatusesLocalList[i].created_by.toString(), "created_by": assetStatusesLocalList[i].created_by.toString(),
"created_at": formattedCreatedAt, "created_at": formattedCreatedAt,
@ -216,12 +217,13 @@ class SyncronizationGlobalData {
Map<String, dynamic> data = { Map<String, dynamic> data = {
"mobile_id": assetStatusesLocalList[i]['mobile_id'].toString(), "mobile_id": assetStatusesLocalList[i]['mobile_id'].toString(),
"peti_id": assetStatusesLocalList[i]['peti_id'].toString(), "peti_id": assetStatusesLocalList[i]['peti_id'].toString(),
"warehouse_id": assetStatusesLocalList[i]['warehouse_id'].toString(),
"exit_at": assetStatusesLocalList[i]['exit_at'].toString(), "exit_at": assetStatusesLocalList[i]['exit_at'].toString(),
"est_pengembalian": "est_pengembalian":
assetStatusesLocalList[i]['est_pengembalian'].toString(), assetStatusesLocalList[i]['est_pengembalian'].toString(),
"exit_pic": assetStatusesLocalList[i]['exit_pic'].toString(), "exit_pic": assetStatusesLocalList[i]['exit_pic'].toString(),
"exit_warehouse": // "exit_warehouse":
assetStatusesLocalList[i]['exit_warehouse'].toString(), // assetStatusesLocalList[i]['exit_warehouse'].toString(),
"status": assetStatusesLocalList[i]['status'].toString(), "status": assetStatusesLocalList[i]['status'].toString(),
"created_by": assetStatusesLocalList[i]['created_by'].toString(), "created_by": assetStatusesLocalList[i]['created_by'].toString(),
"created_at": formattedCreatedAt, "created_at": formattedCreatedAt,

484
lib/pages/home/home_page.dart

@ -28,6 +28,8 @@ import 'conn_home_page.dart/syncronize.dart';
import 'controller/home_controller.dart'; import 'controller/home_controller.dart';
class HomePage extends StatefulWidget { class HomePage extends StatefulWidget {
final ControllerHome controllerHome = ControllerHome(); // Declare here
@override @override
State<HomePage> createState() => _HomePageState(); State<HomePage> createState() => _HomePageState();
} }
@ -55,13 +57,17 @@ class _HomePageState extends State<HomePage> {
List<WarehouseModel>? _warehouseData; List<WarehouseModel>? _warehouseData;
Timer? _timer; Timer? _timer;
int _peminjamanCount = 0;
int _pengembalianCount = 0;
int _transferCount = 0;
bool _isLoading = true; bool _isLoading = true;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_getUserToken(); _getUserToken();
_initData();
// Menerapkan Future untuk menangani tugas asinkronus // Menerapkan Future untuk menangani tugas asinkronus
Future.wait([ Future.wait([
warehouseListAPI(), warehouseListAPI(),
@ -75,15 +81,35 @@ class _HomePageState extends State<HomePage> {
datatablesWarehouseList(), datatablesWarehouseList(),
]).then((_) { ]).then((_) {
// Selesaikan loading setelah semua tugas selesai // Selesaikan loading setelah semua tugas selesai
setState(() { if (mounted) {
_isLoading = false; setState(() {
}); _isLoading = false;
});
}
}); });
// Inisialisasi _data di sini jika diperlukan // Inisialisasi _data di sini jika diperlukan
_data = <AssetStatusModel>[]; _data = <AssetStatusModel>[];
} }
@override
void setState(fn) {
if (mounted) {
super.setState(fn);
}
}
Future<void> _initData() async {
try {
_peminjamanCount = await widget.controllerHome.getPeminjamanCount();
_pengembalianCount = await widget.controllerHome.getPengembalianCount();
_transferCount = await widget.controllerHome.getTransferCount();
} catch (error) {
print(error);
}
// ... tambahkan inisialisasi lainnya
}
void _getUserToken() async { void _getUserToken() async {
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
if (mounted) { if (mounted) {
@ -286,63 +312,73 @@ class _HomePageState extends State<HomePage> {
// Datatables ------------------------------------------------------------------------ // Datatables ------------------------------------------------------------------------
Future datatablesAssetStatusList() async { Future datatablesAssetStatusList() async {
await Controller().fetchAssetStatusLocalController().then((value) { if (mounted) {
setState(() { await Controller().fetchAssetStatusLocalController().then((value) {
_data = (value as List<dynamic>) setState(() {
.map((e) => AssetStatusModel.fromJson(e)) _data = (value as List<dynamic>)
.toList(); .map((e) => AssetStatusModel.fromJson(e))
loading = false; .toList();
loading = false;
});
}); });
}); }
} }
Future datatablesPetiList() async { Future datatablesPetiList() async {
await Controller().fetchPetiData().then((value) { if (mounted) {
setState(() { await Controller().fetchPetiData().then((value) {
_petiData = (value as List<dynamic>) setState(() {
.map((e) => PetiAssetModel.fromJson(e)) _petiData = (value as List<dynamic>)
.toList(); .map((e) => PetiAssetModel.fromJson(e))
loading = false; .toList();
loading = false;
});
}); });
}); }
} }
Future datatablesTipePetiList() async { Future datatablesTipePetiList() async {
await Controller().fetchTipePetiData().then((value) { if (mounted) {
setState(() { await Controller().fetchTipePetiData().then((value) {
_tipePetiData = (value as List<dynamic>) setState(() {
.map((e) => TypePetiModel.fromJson(e)) _tipePetiData = (value as List<dynamic>)
.toList(); .map((e) => TypePetiModel.fromJson(e))
loading = false; .toList();
loading = false;
});
}); });
}); }
} }
Future datatablesCustomerList() async { Future datatablesCustomerList() async {
await Controller().fetchCustomerData().then((value) { if (mounted) {
setState(() { await Controller().fetchCustomerData().then((value) {
_customerData = (value as List<dynamic>) setState(() {
.map((e) => CustomerModel.fromJson(e)) _customerData = (value as List<dynamic>)
.toList(); .map((e) => CustomerModel.fromJson(e))
loading = false; .toList();
loading = false;
});
}); });
}); }
} }
Future datatablesWarehouseList() async { Future datatablesWarehouseList() async {
await Controller().fetchWarehouseData().then((value) { if (mounted) {
setState(() { await Controller().fetchWarehouseData().then((value) {
_warehouseData = (value as List<dynamic>) setState(() {
.map((e) => WarehouseModel.fromJson(e)) _warehouseData = (value as List<dynamic>)
.toList(); .map((e) => WarehouseModel.fromJson(e))
loading = false; .toList();
loading = false;
});
}); });
}); }
} }
@override @override
void dispose() { void dispose() {
// Memastikan untuk membatalkan timer saat widget di-dispose _timer?.cancel();
super.dispose(); super.dispose();
} }
@ -354,31 +390,31 @@ class _HomePageState extends State<HomePage> {
Widget cardMenuPeminjaman() { Widget cardMenuPeminjaman() {
return Container( return Container(
margin: EdgeInsets.all(10), height: 125,
child: Card( child: Card(
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0), borderRadius: BorderRadius.circular(10.0),
), ),
elevation: 5, elevation: 3,
child: InkWell( child: InkWell(
onTap: () { onTap: () {
// Aksi ketika card diklik // Aksi ketika card diklik
Navigator.pushNamed(context, '/peminjaman-barang'); Navigator.pushNamed(context, '/peminjaman-barang');
}, },
child: Container( child: Container(
padding: EdgeInsets.all(16.0), // padding: EdgeInsets.only(top: 8.0, bottom: 8.0),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Icon( Icon(
Icons.vertical_align_top, Icons.vertical_align_top,
size: 50, size: 30,
color: Colors.greenAccent[700], color: Colors.greenAccent[700],
), ),
SizedBox(height: 10), SizedBox(height: 5),
Text( Text(
'Peminjaman', 'Peminjaman',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
), ),
], ],
), ),
@ -390,31 +426,66 @@ class _HomePageState extends State<HomePage> {
Widget cardMenuPengembalian() { Widget cardMenuPengembalian() {
return Container( return Container(
margin: EdgeInsets.all(10), height: 125,
child: Card( child: Card(
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0), borderRadius: BorderRadius.circular(10.0),
), ),
elevation: 5, elevation: 3,
child: InkWell( child: InkWell(
onTap: () { onTap: () {
// Aksi ketika card diklik // Aksi ketika card diklik
Navigator.pushNamed(context, '/pengembalian-barang'); Navigator.pushNamed(context, '/pengembalian-barang');
}, },
child: Container( child: Container(
padding: EdgeInsets.all(16.0), // padding: EdgeInsets.all(8.0),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Icon( Icon(
Icons.vertical_align_bottom, Icons.vertical_align_bottom,
size: 50, size: 30,
color: Colors.blueAccent[700], color: Colors.blueAccent[700],
), ),
SizedBox(height: 10), SizedBox(height: 5),
Text( Text(
'Pengembalian', 'Pengembalian',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
),
],
),
),
),
),
);
}
Widget cardMenuTransfer() {
return Container(
height: 125,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
elevation: 3,
child: InkWell(
onTap: () {
// Aksi ketika card diklik
Navigator.pushNamed(context, '/transfer-peti');
},
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.input_outlined,
size: 30,
color: Colors.yellow[700],
),
SizedBox(height: 5),
Text(
'Transfer Peti',
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
), ),
], ],
), ),
@ -463,42 +534,6 @@ class _HomePageState extends State<HomePage> {
); );
} }
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) { Widget _buildCountTile(IconData icon, int count, Color color, String text) {
return Column( return Column(
children: [ children: [
@ -622,34 +657,6 @@ class _HomePageState extends State<HomePage> {
), ),
), ),
), ),
// 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',
// ),
// ),
// ),
// ),
], ],
), ),
); );
@ -657,30 +664,196 @@ class _HomePageState extends State<HomePage> {
); );
} }
Widget cardMenuSync() {
return Card(
elevation: 3,
margin: EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
color: Color.fromARGB(255, 50, 39, 122),
padding: EdgeInsets.all(16.0),
child: Text(
"Sync Data Global",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 20.0,
),
),
),
SizedBox(height: 10),
// Display counts for each table
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),
// Re-init Button
ElevatedButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
backgroundColor:
Colors.grey[100], // Set the background color
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
elevation: 0,
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(
"Konfirmasi Sync",
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
),
// Description text
Container(
padding: EdgeInsets.all(16.0),
child: Text(
"Apakah Anda yakin ingin mengunggah dan mengunduh data?",
style: TextStyle(
fontSize: 16.0,
),
),
),
// Re-init Button with blue background
ElevatedButton(
onPressed: () {
Navigator.pop(context); // Close dialog
fetchDataFromApiAndSync();
},
style: TextButton.styleFrom(
backgroundColor: Colors.blue[700],
),
child: Text(
"Upload + Download",
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
fontFamily: 'Poppins',
),
),
),
],
),
);
},
);
},
style: ElevatedButton.styleFrom(
primary: Colors.blue[700],
),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Upload + Download",
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
fontFamily: 'Poppins',
),
),
Icon(
Icons.cloud_upload,
color: Colors.white,
),
],
),
),
)
],
),
);
}
return Scaffold( return Scaffold(
backgroundColor: Colors.grey[200], backgroundColor: Colors.grey[200],
appBar: AppBar( appBar: AppBar(
elevation: 0, elevation: 0,
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
backgroundColor: Colors.indigo[700], backgroundColor: Colors.indigo[700],
actions: [ // actions: [
IconButton( // IconButton(
icon: Icon( // icon: Icon(
Icons.cloud_sync, // Icons.cloud_sync,
size: 30, // size: 30,
), // ),
onPressed: () async { // onPressed: () async {
if (await SyncronizationGlobalData.isInternet()) { // if (await SyncronizationGlobalData.isInternet()) {
// Display custom dialog when the IconButton is pressed // // Display custom dialog when the IconButton is pressed
showSyncDialog(context); // showSyncDialog(context);
} else { // } else {
ScaffoldMessenger.of(context).showSnackBar( // ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("No internet connection")), // SnackBar(content: Text("No internet connection")),
); // );
} // }
}, // },
), // ),
], // ],
centerTitle: true,
title: Row( title: Row(
children: [ children: [
SizedBox(width: 10), SizedBox(width: 10),
@ -707,14 +880,39 @@ class _HomePageState extends State<HomePage> {
), ),
body: ListView( body: ListView(
children: [ children: [
GridView.count( cardMenuSync(),
crossAxisCount: 2, SizedBox(height: 10),
shrinkWrap: true, Container(
physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.all(10),
child: Text(
'Menu Aplikasi',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
cardMenuPeminjaman(), Expanded(
cardMenuPengembalian(), child: cardMenuPeminjaman(),
cardMenuTransfer(), ),
Expanded(
child: cardMenuPengembalian(),
),
],
),
SizedBox(height: 10), // Add some space between rows
Row(
children: [
Expanded(
child: cardMenuTransfer(),
),
Expanded(
child: Container(),
// child: cardMenuPengembalian(),
),
], ],
), ),
], ],

8
lib/pages/home/main_page.dart

@ -28,9 +28,11 @@ class _MainPageState extends State<MainPage> {
currentIndex: currentIndex, currentIndex: currentIndex,
selectedItemColor: Colors.indigoAccent, // Warna saat dipilih selectedItemColor: Colors.indigoAccent, // Warna saat dipilih
onTap: (index) { onTap: (index) {
setState(() { if (mounted) {
currentIndex = index; setState(() {
}); currentIndex = index;
});
}
}, },
items: [ items: [
BottomNavigationBarItem( BottomNavigationBarItem(

8
lib/pages/home/setting_page.dart

@ -27,9 +27,11 @@ class SettingPageState extends State<SettingPage> {
void _getUserToken() async { void _getUserToken() async {
try { try {
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() { if (mounted) {
token = prefs.getString('token'); setState(() {
}); token = prefs.getString('token');
});
}
} catch (e) { } catch (e) {
print("Error: $e"); print("Error: $e");
} }

6
lib/pages/peminjaman_barang/conn/syncronize.dart

@ -173,7 +173,7 @@ class SyncronizationPeminjamanData {
"exit_at": assetStatus.exit_at.toString(), "exit_at": assetStatus.exit_at.toString(),
"est_pengembalian": assetStatus.est_pengembalian.toString(), "est_pengembalian": assetStatus.est_pengembalian.toString(),
"exit_pic": assetStatus.exit_pic.toString(), "exit_pic": assetStatus.exit_pic.toString(),
"exit_warehouse": assetStatus.exit_warehouse.toString(), // "exit_warehouse": assetStatus.exit_warehouse.toString(),
"created_by": assetStatus.created_by.toString(), "created_by": assetStatus.created_by.toString(),
"created_at": formattedCreatedAt, "created_at": formattedCreatedAt,
}; };
@ -248,8 +248,8 @@ class SyncronizationPeminjamanData {
"est_pengembalian": "est_pengembalian":
assetStatusesLocalList[i]['est_pengembalian'].toString(), assetStatusesLocalList[i]['est_pengembalian'].toString(),
"exit_pic": assetStatusesLocalList[i]['exit_pic'].toString(), "exit_pic": assetStatusesLocalList[i]['exit_pic'].toString(),
"exit_warehouse": // "exit_warehouse":
assetStatusesLocalList[i]['exit_warehouse'].toString(), // assetStatusesLocalList[i]['exit_warehouse'].toString(),
"status": assetStatusesLocalList[i]['status'].toString(), "status": assetStatusesLocalList[i]['status'].toString(),
"created_by": assetStatusesLocalList[i]['created_by'].toString(), "created_by": assetStatusesLocalList[i]['created_by'].toString(),
"created_at": formattedCreatedAt, "created_at": formattedCreatedAt,

4
lib/pages/peminjaman_barang/controller/peminjaman_controller.dart

@ -127,11 +127,11 @@ class Controller {
await dbClient!.delete(SqfliteDatabaseHelper.peminjamanTable); await dbClient!.delete(SqfliteDatabaseHelper.peminjamanTable);
} }
Future<void> addAllData(List<AssetStatusModel> contactList) async { Future<void> addAllData(List<AssetStatusModel> peminjamanList) async {
var dbclient = await conn.db; var dbclient = await conn.db;
Batch batch = dbclient!.batch(); Batch batch = dbclient!.batch();
for (var contact in contactList) { for (var contact in peminjamanList) {
batch.insert( batch.insert(
SqfliteDatabaseHelper.peminjamanTable, SqfliteDatabaseHelper.peminjamanTable,
contact.toJson(), contact.toJson(),

873
lib/pages/peminjaman_barang/create-finish.dart

@ -0,0 +1,873 @@
import 'dart:convert';
import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:intl/intl.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:collection/collection.dart';
import 'package:uuid/uuid.dart';
import '../../models/asset_status_model.dart';
import '../../models/customer_model.dart';
import '../../models/disposal_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 '../../services/controllerApi.dart';
import 'conn/syncronize.dart';
import 'controller/peminjaman_controller.dart';
class InformasiDataEntryPage extends StatefulWidget {
final List<AssetStatusModel> temporaryDataList;
InformasiDataEntryPage({required this.temporaryDataList});
@override
_InformasiDataEntryPageState createState() => _InformasiDataEntryPageState();
}
class _InformasiDataEntryPageState extends State<InformasiDataEntryPage> {
String? token;
// List<CustomerModel>? customerSqfliteApi;
PetiAssetModel? petiSqfliteApi;
WarehouseModel? warehouseSqfliteApi;
WarehouseModel? warehouseTujuanSqfliteApi;
DisposalPetiModel? disposalSqfliteApi;
CustomerModel? customerSqfliteApi;
List<PetiAssetModel>? _valpeti; // Change this line
List<WarehouseModel>? _valwarehouse;
List<WarehouseModel>? _valwarehouseTujuan;
List<CustomerModel>? _valcustomer;
List<DisposalPetiModel>? _valdisposal;
List<PetiAssetModel> _allPetiList = [];
List<PetiAssetModel> _unrestrictedPetiList = [];
List<PetiAssetModel> _filteredPetiList = [];
bool isQRCodeScanned = false;
String searchText = '';
PetiAssetModel? selectedPeti;
TextEditingController searchBoxController = TextEditingController();
TextEditingController _exit_atController = TextEditingController();
TextEditingController _est_pengembalianController = TextEditingController();
TextEditingController _penanggungJawabController = TextEditingController();
TextEditingController _warehouseController = TextEditingController();
List<PetiAssetModel> selectedPetiList = [];
List<AssetStatusModel>? _data;
List<AssetStatusModel> temporaryDataList = [];
final _formKey = GlobalKey<FormState>();
bool loading = true;
late Future<void> _dataFuture;
// bool _isLoading = false;
@override
void initState() {
super.initState();
// Set loading ke true pada awalnya
if (mounted) {
if (mounted) {
setState(() {
loading = false;
});
}
}
_dataFuture = fetchData();
}
Future<void> fetchData() async {
await _getUserToken();
await warehouseListAPI();
await petiListAPI();
await disposalListAPI();
await customerListAPI();
initializeDateFormatting('id_ID', null);
// Tandai bahwa proses loading telah selesai
if (mounted) {
setState(() {
loading = false;
});
}
}
Future<void> _getUserToken() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
if (mounted) {
setState(() {
token = prefs.getString('token');
loading = false;
});
}
}
void addDataToDropdown(PetiAssetModel peti) {
if (mounted) {
setState(() {
selectedPetiList.add(peti);
});
}
}
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 customerListAPI() async {
if (mounted) {
await ControllerApi().fetchCustomerDataAPI().then((value) {
setState(() {
_valcustomer = (value as List<dynamic>)
.map((item) => CustomerModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
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 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> isInteret() async {
await SyncronizationPeminjamanData.isInternet().then((connection) {
if (connection) {
print("Internet connection available");
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("No Internet")));
}
});
}
@override
Widget build(BuildContext context) {
AuthProvider authProvider =
Provider.of<AuthProvider>(context, listen: false);
UserModel user = authProvider.user;
// WarehouseModel? warehouseSqfliteApi = _valwarehouse?.firstWhereOrNull(
// (warehouse) => warehouse.id == _valwarehouse?.first.id,
// );
var uuid = Uuid();
DateTime? parseDateTime(String? dateTimeString) {
if (dateTimeString == null || dateTimeString.isEmpty) {
return null;
}
try {
return DateTime.parse(dateTimeString);
} catch (e) {
print('Error parsing DateTime: $e');
return null;
}
}
Future<void> removePetiFromSharedPreferences(
PetiAssetModel removedPeti) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
// Retrieve existing data from SharedPreferences
List<String>? petiListJson = prefs.getStringList('selectedPetiList');
if (petiListJson != null) {
// Convert JSON strings to PetiAssetModel objects
List<PetiAssetModel> existingPetiList = petiListJson
.map((petiJson) => PetiAssetModel.fromJson(json.decode(petiJson)))
.toList();
// Remove the specified peti from the list
existingPetiList.removeWhere((peti) => peti.id == removedPeti.id);
// Save the updated list back to SharedPreferences
List<String> updatedPetiListJson =
existingPetiList.map((peti) => json.encode(peti.toJson())).toList();
prefs.setStringList('selectedPetiList', updatedPetiListJson);
}
}
void removePeti(int index) async {
PetiAssetModel? selectedPeti =
selectedPetiList != null ? selectedPetiList[index] : null;
print('Before Remove: ${selectedPeti?.fix_lot}');
if (index >= 0 && index < selectedPetiList.length) {
if (mounted) {
PetiAssetModel removedPeti = selectedPetiList[index];
// Remove the data with the specified peti_id from temporaryDataList
temporaryDataList
.removeWhere((data) => data.peti_id == removedPeti.id);
selectedPetiList.removeAt(index);
await removePetiFromSharedPreferences(removedPeti);
print('After Remove: ${selectedPeti?.fix_lot}');
}
} else {
print('Invalid index: $index. No removal performed.');
}
}
List<PetiAssetModel> selectedPetis = widget.temporaryDataList
.map((data) {
PetiAssetModel? peti =
_valpeti?.firstWhereOrNull((peti) => peti.id == data.peti_id);
print("Checking conditions for Peti ID: ${data.peti_id}");
print("Exit_atController: ${_exit_atController.text.isNotEmpty}");
print("petiSqfliteApi: ${peti != null}");
print("warehouseSqfliteApi: ${warehouseSqfliteApi != null}");
if (peti != null) {
return peti;
} else {
print("Peti not found for ID: ${data.peti_id}");
return PetiAssetModel(
id: -1,
fix_lot: '', /* other default values */
);
}
})
.where((peti) => peti != null && peti.id != -1)
.cast<PetiAssetModel>()
.toList();
Future<void> saveAssetData(List<PetiAssetModel> selectedPetis) async {
DateTime now = DateTime.now().toLocal();
String formattedDate = DateFormat('yyyy-MM-dd HH:mm:ss.SSS').format(now);
List<int?> savedPetiIds = [];
for (PetiAssetModel selectedPeti in selectedPetis) {
// print("Checking conditions for Peti ID: ${selectedPeti.id}");
// print("Exit_atController: ${_exit_atController.text.isNotEmpty}");
// print("petiSqfliteApi: ${petiSqfliteApi != null}");
// print("warehouseSqfliteApi: ${warehouseSqfliteApi != null}");
if (selectedPeti == null) {
print("Selected Peti is null");
continue;
}
// Ensure that _valpeti is not null before trying to find the PetiAssetModel
if (_valpeti == null) {
print("_valpeti is null");
continue;
}
petiSqfliteApi =
_valpeti?.firstWhereOrNull((peti) => peti.id == selectedPeti.id);
if (petiSqfliteApi == null) {
print("Peti not found for ID: ${selectedPeti.id}");
continue;
}
if (_exit_atController.text.isNotEmpty &&
petiSqfliteApi != null &&
warehouseSqfliteApi != null) {
print("All conditions met. Saving data...");
AssetStatusModel assetAddModel = AssetStatusModel(
id: null,
peti_id: selectedPeti.id,
customer_id: customerSqfliteApi?.id,
warehouse_id: warehouseSqfliteApi?.id,
exit_at: parseDateTime(_exit_atController.text),
exit_pic: _penanggungJawabController.text,
est_pengembalian: parseDateTime(_est_pengembalianController.text),
created_by: user.fullname,
created_at: parseDateTime(formattedDate),
mobile_id: uuid.v4(),
);
// Call addData function
int result = await Controller().addPeminjamanData(assetAddModel);
if (result > 0) {
savedPetiIds.add(selectedPeti.id!);
if (mounted) {
setState(() {
_exit_atController.text = '';
_penanggungJawabController.text = '';
_est_pengembalianController.text = '';
warehouseSqfliteApi?.id = null;
customerSqfliteApi?.id = null;
});
}
print("Success Tambah data untuk Peti ID: ${selectedPeti.id}");
EasyLoading.showSuccess("Data Berhasil Disimpan");
// Reset controllers and make fields nullable
} else {
print("Failed untuk Peti ID: ${selectedPeti.id}");
}
} else {
print("Conditions not met. Unable to save data.");
if (_exit_atController.text.isEmpty) {
print("Exit_atController is empty");
}
if (petiSqfliteApi == null) {
print("petiSqfliteApi is null");
}
if (warehouseSqfliteApi == null) {
print("warehouseSqfliteApi is null");
}
}
}
// Hapus peti-peti yang baru saja disimpan dari SharedPreferences
for (PetiAssetModel selectedPeti in selectedPetis) {
if (selectedPeti != null) {
await removePetiFromSharedPreferences(selectedPeti);
}
}
// Jika Anda ingin pindah ke halaman setelah menyimpan data untuk semua peti
Navigator.pushNamed(context, '/peminjaman-barang');
}
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: true,
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text('Isikan Data Peminjaman Peti',
style: TextStyle(
fontSize: 16,
)),
),
body: Form(
key: _formKey,
child: FutureBuilder<void>(
future: _dataFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: LoadingAnimationWidget.staggeredDotsWave(
color: Colors.indigo,
size: 40,
),
);
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 8),
Text(
'List Peti:',
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
Container(
height: 250,
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey.withOpacity(0.5),
width: 1,
),
borderRadius: BorderRadius.circular(8),
color: Colors.grey[100],
),
padding: EdgeInsets.all(8),
child: Expanded(
child: ListView.builder(
itemCount: widget.temporaryDataList.length,
itemBuilder: (context, index) {
int? petiId =
widget.temporaryDataList[index].peti_id;
PetiAssetModel? petiSqfliteApi =
_valpeti?.firstWhereOrNull(
(peti) => peti.id == petiId,
);
return ConstrainedBox(
constraints: BoxConstraints(
maxHeight:
100, // Set your desired height here
),
child: Card(
elevation: 1,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(
color: Colors.grey.withOpacity(0.5),
width: 1,
),
),
margin: EdgeInsets.symmetric(vertical: 4),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Row(
children: [
Text(
'${index + 1}.',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
SizedBox(width: 16),
Text(
' ${petiSqfliteApi?.fix_lot ?? ''}',
style: TextStyle(fontSize: 13),
),
// Tambahkan properti lainnya sesuai kebutuhan
],
),
),
),
),
);
},
),
),
),
SizedBox(height: 16),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Pilih Customer:',
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
DropdownSearch<CustomerModel>(
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
hintText: 'Pilih Customer',
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(5.0),
),
),
),
),
popupProps: PopupProps.bottomSheet(
showSearchBox: true,
itemBuilder: (context, CustomerModel? customer,
bool? isSelected) {
if (customer == null) {
return SizedBox.shrink();
}
return Container(
child: Column(
children: [
ListTile(
title: Text(
customer.name.toString(),
style: TextStyle(
fontSize: 16,
fontFamily: 'OpenSansCondensed',
),
),
leading: Icon(
Icons.person_pin,
size: 24,
color: customer.id ==
customerSqfliteApi?.id
? Colors.indigo[700]
: Colors.grey,
),
),
Divider(
height: 1,
color: Colors
.grey, // Warna pembatas (divider)
),
],
),
color: customer.id == customerSqfliteApi?.id
? Colors.grey.withOpacity(0.7)
: Colors.white,
);
},
fit: FlexFit.loose,
title: Padding(
padding: EdgeInsets.all(8.0),
child: Column(
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'Pilih Customer',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold),
),
IconButton(
icon: Icon(
Icons.close,
color: Colors.red,
),
onPressed: () {
Navigator.pop(context);
},
),
],
),
Divider(),
],
),
),
),
items: (_valcustomer ?? [])
.where((customer) =>
customer.deleted_at != true)
.where((customer) => customer.name!
.toLowerCase()
.contains(searchBoxController.text
.toLowerCase()))
.toList() ??
[],
itemAsString: (CustomerModel customer) =>
customer.name ??
"", // Ganti dengan properti yang sesuai
selectedItem: customerSqfliteApi,
onChanged: (CustomerModel? value) {
setState(() {
customerSqfliteApi = value;
});
},
validator: (CustomerModel? value) {
if (value == null) {
return 'Harus diisi';
}
return null;
},
),
],
),
),
SizedBox(height: 16),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Tanggal Peminjaman:',
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
FormBuilderDateTimePicker(
validator: (value) {
if (_exit_atController.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent[700],
content: Row(
children: [
Icon(
Icons.error_outline,
color: Colors.white,
),
SizedBox(width: 5),
Text(
'Tanggal Peminjaman harus diisi'),
],
),
duration: Duration(seconds: 2),
),
);
return null; // Return null jika ada kesalahan
}
return null; // Return null jika tidak ada kesalahan
},
controller: _exit_atController,
name: 'tanggal_peminjaman',
inputType: InputType.date,
format: DateFormat('yyyy-MM-dd', 'id_ID'),
decoration: InputDecoration(
hintText: 'Tanggal Peminjaman',
border: OutlineInputBorder(),
suffixIcon: Icon(Icons.calendar_today),
),
onChanged: (DateTime? selectedDate) {
if (selectedDate != null) {
// Mengisi tanggal estimasi 7 hari ke depan
DateTime estimasiPengembalian =
selectedDate.add(Duration(days: 7));
_est_pengembalianController.text =
DateFormat('yyyy-MM-dd')
.format(estimasiPengembalian);
}
},
),
],
),
),
SizedBox(height: 16),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Estimasi Pengembalian:',
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.bold),
),
SizedBox(height: 4),
Text(
'* Terisi otomatis 7 hari setelah tanggal peminjaman',
style: TextStyle(
fontSize: 12,
color: Colors.red,
fontStyle: FontStyle.italic),
),
SizedBox(height: 8),
FormBuilderDateTimePicker(
validator: (value) {
if (_est_pengembalianController.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent[700],
content: Row(
children: [
Icon(
Icons.error_outline,
color: Colors.white,
),
SizedBox(width: 5),
Text('Tanggal Estimasi Pengembalian'),
],
),
duration: Duration(seconds: 2),
),
);
return null; // Return null jika ada kesalahan
}
return null; // Return null jika tidak ada kesalahan
},
controller: _est_pengembalianController,
name: 'estimasi_pengembalian',
inputType: InputType.date,
format: DateFormat('yyyy-MM-dd', 'id_ID'),
decoration: InputDecoration(
hintText: 'Estimasi Tanggal Pengembalian',
border: OutlineInputBorder(),
suffixIcon: Icon(Icons.calendar_today),
),
),
],
),
),
SizedBox(height: 16),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Penanggung Jawab:',
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
TextFormField(
controller: _penanggungJawabController =
TextEditingController(text: user.fullname),
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'Penanggung Jawab',
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Harus diisi';
}
return null; // Return null jika tidak ada kesalahan
},
),
],
),
),
SizedBox(height: 16),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Gudang:',
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
DropdownButtonFormField<WarehouseModel>(
validator: (value) {
if (value == null) {
return 'Harus diisi';
}
return null;
},
decoration: InputDecoration(
hintText: 'Gudang',
border: OutlineInputBorder(),
),
hint: Text("Gudang"),
value: warehouseSqfliteApi,
items: (_valwarehouse ?? [])
.where((warehouse) =>
warehouse.deleted_at != true)
.map((WarehouseModel warehouse)
// _valwarehouse?.map((WarehouseModel warehouse)
{
return DropdownMenuItem<WarehouseModel>(
child: Row(
children: [
Icon(
Icons.warehouse,
color: warehouseSqfliteApi?.id ==
warehouse.id
? Colors.indigo[700]
: Colors.grey,
),
SizedBox(
width:
8), // Jarak antara ikon dan teks
Text(
'${warehouse.name}',
style: TextStyle(
fontSize: 16,
fontFamily: 'OpenSansCondensed',
fontWeight:
warehouseSqfliteApi?.id ==
warehouse.id
? FontWeight.bold
: FontWeight.normal,
),
),
],
),
value: warehouse,
);
}).toList() ??
[],
onChanged: (value) {
setState(() {
warehouseSqfliteApi = value;
});
},
),
],
),
),
],
),
),
);
}
},
),
),
bottomNavigationBar: BottomAppBar(
height: MediaQuery.of(context).size.height / 10,
color: Color.fromARGB(255, 5, 28, 158), // Warna latar belakang
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: MediaQuery.of(context).size.width / 3,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 50, // Lebar dan tinggi sesuai kebutuhan
width: 50,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.green, // Warna hijau untuk save
),
child: IconButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
try {
if (_exit_atController.text.isNotEmpty &&
warehouseSqfliteApi != null) {
await saveAssetData(selectedPetis);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent[700],
content: Row(
children: [
Icon(
Icons.error_outline,
color: Colors.white,
),
SizedBox(width: 5),
Text('Data belum lengkap'),
],
),
duration: Duration(seconds: 2),
),
);
}
} catch (e) {
print('Error storing data: $e');
}
}
},
icon: Icon(Icons.check, color: Colors.white),
),
),
],
),
),
],
),
),
);
}
}

1813
lib/pages/peminjaman_barang/create.dart

File diff suppressed because it is too large Load Diff

1175
lib/pages/peminjaman_barang/peminjaman_stock_page.dart

File diff suppressed because it is too large Load Diff

260
lib/pages/peminjaman_barang/show.dart

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:shimmer/shimmer.dart';
import 'package:siopas/models/asset_status_model.dart'; import 'package:siopas/models/asset_status_model.dart';
import 'package:siopas/models/customer_model.dart'; import 'package:siopas/models/customer_model.dart';
import 'package:siopas/models/m_asset_status_model.dart'; import 'package:siopas/models/m_asset_status_model.dart';
@ -10,6 +11,7 @@ import 'package:collection/collection.dart';
import '../../models/warehouse_mode.dart'; import '../../models/warehouse_mode.dart';
import '../../services/controllerApi.dart'; import '../../services/controllerApi.dart';
import '../../widget/loading_shimmer_show.dart';
class DetailPeminjamanBarangPage extends StatefulWidget { class DetailPeminjamanBarangPage extends StatefulWidget {
final String peminjamanId; final String peminjamanId;
@ -31,19 +33,38 @@ class _DetailPeminjamanBarangPageState
List<CustomerModel>? customerData; List<CustomerModel>? customerData;
List<WarehouseModel>? warehouseData; List<WarehouseModel>? warehouseData;
bool loading = true; late Future<void> _dataFuture;
bool loading = true; // Atur loading ke true pada awalnya
@override @override
void initState() { void initState() {
super.initState(); super.initState();
getPeminjamanIdData();
customerListAPI(); // Set loading ke true pada awalnya
petiListAPI(); if (mounted) {
warehouseListAPI(); if (mounted) {
setState(() {
loading = false;
});
}
}
_dataFuture = fetchData();
}
Future<void> fetchData() async {
await getPeminjamanIdData();
await customerListAPI();
await petiListAPI();
await warehouseListAPI();
initializeDateFormatting('id_ID', null); initializeDateFormatting('id_ID', null);
setState(() {
loading = false; // Tandai bahwa proses loading telah selesai
}); if (mounted) {
setState(() {
loading = false;
});
}
} }
Future customerListAPI() async { Future customerListAPI() async {
@ -91,8 +112,9 @@ class _DetailPeminjamanBarangPageState
peminjamanInfo = peminjamans.firstWhereOrNull( peminjamanInfo = peminjamans.firstWhereOrNull(
(peminjaman) => peminjaman.id.toString() == widget.peminjamanId, (peminjaman) => peminjaman.id.toString() == widget.peminjamanId,
); );
if (mounted) {
setState(() {}); setState(() {});
}
} }
String _formatDate(String? date) { String _formatDate(String? date) {
@ -134,10 +156,10 @@ class _DetailPeminjamanBarangPageState
warehouseSqfliteApi = warehouseData?.firstWhereOrNull( warehouseSqfliteApi = warehouseData?.firstWhereOrNull(
(warehouse) => warehouse.id == peminjamanInfo!.warehouse_id, (warehouse) => warehouse.id == peminjamanInfo!.warehouse_id,
); );
WarehouseModel? warehouseTujuanSqfliteApi; // WarehouseModel? warehouseTujuanSqfliteApi;
warehouseTujuanSqfliteApi = warehouseData?.firstWhereOrNull( // warehouseTujuanSqfliteApi = warehouseData?.firstWhereOrNull(
(warehouse) => warehouse.id == peminjamanInfo!.exit_warehouse, // (warehouse) => warehouse.id == peminjamanInfo!.exit_warehouse,
); // );
Future<void> _showDeleteConfirmationDialog() async { Future<void> _showDeleteConfirmationDialog() async {
return showDialog<void>( return showDialog<void>(
@ -224,10 +246,10 @@ class _DetailPeminjamanBarangPageState
), ),
), ),
leading: IconButton( leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () { onPressed: () {
Navigator.pushNamed(context, '/peminjaman-barang'); Navigator.pop(context);
}, },
icon: Icon(Icons.arrow_back),
), ),
actions: [ actions: [
IconButton( IconButton(
@ -238,109 +260,123 @@ class _DetailPeminjamanBarangPageState
), ),
], ],
), ),
body: Padding( body: FutureBuilder<void>(
padding: EdgeInsets.all(16.0), future: _dataFuture,
child: Card( builder: (context, snapshot) {
shape: RoundedRectangleBorder( if (snapshot.connectionState == ConnectionState.waiting) {
borderRadius: BorderRadius.circular(15.0), return ShimmerShow();
), } else if (snapshot.hasError) {
elevation: 5, return Text('Error: ${snapshot.error}');
child: Column( } else {
children: [ return Padding(
Card( padding: EdgeInsets.all(16.0),
child: Card(
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: borderRadius: BorderRadius.circular(15.0),
BorderRadius.vertical(top: Radius.circular(15.0)),
), ),
elevation: 0, elevation: 5,
margin: EdgeInsets.all(0), child: Column(
color: Colors.indigo[700], children: [
child: Padding( Card(
padding: const EdgeInsets.all(16.0), shape: RoundedRectangleBorder(
child: Column( borderRadius:
crossAxisAlignment: CrossAxisAlignment.start, BorderRadius.vertical(top: Radius.circular(15.0)),
children: [ ),
Row( elevation: 0,
children: [ margin: EdgeInsets.all(0),
Icon(Icons.article, size: 30, color: Colors.white), color: Colors.indigo[700],
SizedBox(width: 10), child: Padding(
Column( padding: const EdgeInsets.all(16.0),
crossAxisAlignment: CrossAxisAlignment.start, child: Column(
children: [ crossAxisAlignment: CrossAxisAlignment.start,
Text( children: [
'ID:', Row(
style: TextStyle( children: [
fontSize: 12, Icon(Icons.article,
fontWeight: FontWeight.bold, size: 30, color: Colors.white),
color: Colors.white, SizedBox(width: 10),
), Column(
), crossAxisAlignment: CrossAxisAlignment.start,
SizedBox(height: 5), children: [
Text( Text(
petiSqfliteApi != null && 'ID:',
petiSqfliteApi.fix_lot != null style: TextStyle(
? petiSqfliteApi!.fix_lot.toString() fontSize: 12,
: '-', fontWeight: FontWeight.bold,
style: TextStyle( color: Colors.white,
fontSize: 12, ),
fontWeight: FontWeight.bold, ),
color: Colors.white, SizedBox(height: 5),
Text(
petiSqfliteApi != null &&
petiSqfliteApi.fix_lot != null
? petiSqfliteApi!.fix_lot.toString()
: '-',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
],
), ),
), ],
], ),
), ],
], ),
),
),
SizedBox(height: 10),
if (peminjamanInfo != null) ...[
_buildDetailItem(
'Kode Peti',
petiSqfliteApi != null && petiSqfliteApi.fix_lot != null
? petiSqfliteApi!.fix_lot.toString()
: '-',
), ),
Divider(thickness: 1),
_buildDetailItem(
'Nama Customer',
customerSqfliteApi != null &&
customerSqfliteApi.name != null
? customerSqfliteApi!.name.toString()
: '-',
),
Divider(thickness: 1),
_buildDetailItem('Tgl Peminjaman',
_formatDate(peminjamanInfo!.exit_at.toString())),
Divider(thickness: 1),
_buildDetailItem(
'Est Peminjaman',
_formatDate(
peminjamanInfo!.est_pengembalian.toString())),
Divider(thickness: 1),
_buildDetailItem(
'PJ Peminjaman', peminjamanInfo!.exit_pic.toString()),
Divider(thickness: 1),
_buildDetailItem(
' Gudang',
warehouseSqfliteApi != null &&
warehouseSqfliteApi.name != null
? warehouseSqfliteApi!.name.toString()
: '-'),
Divider(thickness: 1),
_buildDetailItem(
'PIC',
peminjamanInfo!.exit_pic != null
? peminjamanInfo!.exit_pic.toString()
: '-'),
Divider(thickness: 1),
// ... tambahkan data lainnya sesuai kebutuhan
], ],
), ],
), ),
), ),
SizedBox(height: 10), );
if (peminjamanInfo != null) ...[ }
_buildDetailItem( },
'Kode Peti',
petiSqfliteApi != null && petiSqfliteApi.fix_lot != null
? petiSqfliteApi!.fix_lot.toString()
: '-',
),
Divider(thickness: 1),
_buildDetailItem(
'Nama Customer',
customerSqfliteApi != null && customerSqfliteApi.name != null
? customerSqfliteApi!.name.toString()
: '-',
),
Divider(thickness: 1),
_buildDetailItem('Tgl Peminjaman',
_formatDate(peminjamanInfo!.exit_at.toString())),
Divider(thickness: 1),
_buildDetailItem('Est Peminjaman',
_formatDate(peminjamanInfo!.est_pengembalian.toString())),
Divider(thickness: 1),
_buildDetailItem(
'PJ Peminjaman', peminjamanInfo!.exit_pic.toString()),
Divider(thickness: 1),
_buildDetailItem(
'Asal Gudang',
// peminjamanInfo!.exit_warehouse.toString()),
warehouseSqfliteApi != null &&
warehouseSqfliteApi.name != null
? warehouseSqfliteApi!.name.toString()
: '-'),
Divider(thickness: 1),
_buildDetailItem(
'Tujuan Gudang',
// peminjamanInfo!.exit_warehouse.toString()),
warehouseTujuanSqfliteApi != null &&
warehouseTujuanSqfliteApi.name != null
? warehouseTujuanSqfliteApi!.name.toString()
: '-'),
Divider(thickness: 1),
// ... tambahkan data lainnya sesuai kebutuhan
],
],
),
),
), ),
); );
} }

227
lib/pages/pengembalian_barang/edit.dart

@ -90,9 +90,11 @@ class _CreatePengembalianBarangPageState
kondisiPetiListAPI(); kondisiPetiListAPI();
initializeDateFormatting('id_ID', null); initializeDateFormatting('id_ID', null);
setState(() { if (mounted) {
loading = false; // Mengatur loading ke false setelah tugas selesai setState(() {
}); loading = false; // Mengatur loading ke false setelah tugas selesai
});
}
} }
void _getUserToken() async { void _getUserToken() async {
@ -179,67 +181,98 @@ class _CreatePengembalianBarangPageState
(scanData) { (scanData) {
if (!scanned) { if (!scanned) {
try { try {
setState(() { if (mounted) {
result = scanData; setState(() {
List<String> lines = result!.code!.split('\n'); result = scanData;
String idPeti = ''; List<String> lines = result!.code!.split('\n');
String idWarehouse = ''; String idPeti = '';
String idWarehouse = '';
for (String line in lines) {
if (line.contains(';')) { for (String line in lines) {
List<String> values = line.split(';'); if (line.contains(';')) {
if (values.length >= 3) { List<String> values = line.split(';');
idPeti = values[1]; if (values.length >= 3) {
idWarehouse = values[2]; idPeti = values[1];
break; idWarehouse = values[2];
break;
}
} }
} }
}
int? petiId = int.tryParse(idPeti); int? petiId = int.tryParse(idPeti);
int? warehouseId = int.tryParse(idWarehouse); int? warehouseId = int.tryParse(idWarehouse);
// AuthProvider authProvider = Provider.of<AuthProvider>(context, listen: false); // AuthProvider authProvider = Provider.of<AuthProvider>(context, listen: false);
// UserModel user = authProvider.user; // UserModel user = authProvider.user;
// Dalam fungsi yang menangani pemindaian QR code // Dalam fungsi yang menangani pemindaian QR code
// Dalam fungsi yang menangani pemindaian QR code // Dalam fungsi yang menangani pemindaian QR code
if (petiId != null && warehouseId != null) { if (petiId != null && warehouseId != null) {
// Check apakah peti dengan warehouse_id yang sesuai ada dalam daftar yang diizinkan // Check apakah peti dengan warehouse_id yang sesuai ada dalam daftar yang diizinkan
PetiAssetModel? allowedPeti = _valpeti?.firstWhereOrNull( PetiAssetModel? allowedPeti = _valpeti?.firstWhereOrNull(
(peti) => (peti) =>
peti.id == petiId && peti.id == petiId &&
peti.deleted_at != true && peti.deleted_at != true &&
peti.status == 'AKTIF', peti.status == 'AKTIF',
); );
if (allowedPeti != null) {
setState(() {
isQRCodeScanned = true;
// Mengisi _filteredPetiList untuk dropdown hasil QR Code
_filteredPetiList = [
_valpeti!.firstWhere((peti) => peti.id == allowedPeti.id)
];
petiSqfliteApi = allowedPeti; if (allowedPeti != null) {
}); setState(() {
isQRCodeScanned = true;
// Mengisi _filteredPetiList untuk dropdown hasil QR Code
_filteredPetiList = [
_valpeti!
.firstWhere((peti) => peti.id == allowedPeti.id)
];
petiSqfliteApi = allowedPeti;
});
} else {
// Tampilkan pesan error jika data tidak sesuai dengan hak akses
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Data Peti tidak ditemukan atau tidak sesuai dengan hak akses.',
style: TextStyle(
color: Colors.white,
fontSize: 12,
),
),
backgroundColor: Colors.red[700],
action: SnackBarAction(
label: 'Tutup',
onPressed: () {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
},
),
),
);
setState(() {
isQRCodeScanned = false;
petiSqfliteApi = null;
warehouseSqfliteApi = null;
});
}
} else { } else {
// Tampilkan pesan error jika data tidak sesuai dengan hak akses // Tampilkan pesan error jika nilai yang dipindai tidak sesuai
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text( content: Row(
'Data Peti tidak ditemukan atau tidak sesuai dengan hak akses.', children: [
style: TextStyle( Icon(
color: Colors.white, Icons.warning,
fontSize: 12, color: Colors.black,
), ),
), SizedBox(width: 8),
backgroundColor: Colors.red[700], Text(
action: SnackBarAction( 'Nilai QR Code tidak sesuai dengan yang diharapkan.',
label: 'Tutup', style: TextStyle(
onPressed: () { color: Colors.black,
ScaffoldMessenger.of(context).hideCurrentSnackBar(); fontSize: 12,
}, ),
),
],
), ),
backgroundColor: Colors.yellow[700],
), ),
); );
setState(() { setState(() {
@ -248,38 +281,10 @@ class _CreatePengembalianBarangPageState
warehouseSqfliteApi = null; warehouseSqfliteApi = null;
}); });
} }
} else {
// Tampilkan pesan error jika nilai yang dipindai tidak sesuai
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Row(
children: [
Icon(
Icons.warning,
color: Colors.black,
),
SizedBox(width: 8),
Text(
'Nilai QR Code tidak sesuai dengan yang diharapkan.',
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
),
],
),
backgroundColor: Colors.yellow[700],
),
);
setState(() {
isQRCodeScanned = false;
petiSqfliteApi = null;
warehouseSqfliteApi = null;
});
}
scanned = true; scanned = true;
}); });
}
controller.stopCamera(); controller.stopCamera();
@ -292,10 +297,12 @@ class _CreatePengembalianBarangPageState
controller.stopCamera(); controller.stopCamera();
// Reset nilai dropdown Peti dan Warehouse // Reset nilai dropdown Peti dan Warehouse
setState(() { if (mounted) {
petiSqfliteApi = null; setState(() {
warehouseSqfliteApi = null; petiSqfliteApi = null;
}); warehouseSqfliteApi = null;
});
}
print('Error scanning QR Code: $e'); print('Error scanning QR Code: $e');
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
@ -521,16 +528,18 @@ class _CreatePengembalianBarangPageState
selectedItem: petiSqfliteApi, selectedItem: petiSqfliteApi,
onChanged: (PetiAssetModel? value) { onChanged: (PetiAssetModel? value) {
setState(() { if (mounted) {
petiSqfliteApi = value; setState(() {
if (value != null) { petiSqfliteApi = value;
// Perbarui _unrestrictedPetiList sesuai pemilihan manual if (value != null) {
_unrestrictedPetiList = [ // Perbarui _unrestrictedPetiList sesuai pemilihan manual
_valpeti!.firstWhere( _unrestrictedPetiList = [
(peti) => peti.id == value.id) _valpeti!.firstWhere(
]; (peti) => peti.id == value.id)
} ];
}); }
});
}
}, },
validator: (PetiAssetModel? value) { validator: (PetiAssetModel? value) {
if (value == null) { if (value == null) {
@ -711,9 +720,11 @@ class _CreatePengembalianBarangPageState
}).toList() ?? }).toList() ??
[], [],
onChanged: (WarehouseModel? value) { onChanged: (WarehouseModel? value) {
setState(() { if (mounted) {
warehouseSqfliteApi = value; setState(() {
}); warehouseSqfliteApi = value;
});
}
}, },
), ),
), ),
@ -769,9 +780,11 @@ class _CreatePengembalianBarangPageState
}).toList() ?? }).toList() ??
[], [],
onChanged: (ConditionPetiModel? value) { onChanged: (ConditionPetiModel? value) {
setState(() { if (mounted) {
conditionPetiSqfliteApi = value; setState(() {
}); conditionPetiSqfliteApi = value;
});
}
}, },
), ),
), ),

130
lib/pages/pengembalian_barang/index.dart

@ -69,9 +69,11 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
_getUserToken(); _getUserToken();
// Set _isLoading ke true sebelum memulai tugas // Set _isLoading ke true sebelum memulai tugas
setState(() { if (mounted) {
_isLoading = true; setState(() {
}); _isLoading = true;
});
}
Future.wait([ Future.wait([
warehouseListAPI(), warehouseListAPI(),
@ -88,9 +90,11 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
datatablesConditionList(), datatablesConditionList(),
]).then((_) { ]).then((_) {
// Set _isLoading ke false setelah semua tugas selesai // Set _isLoading ke false setelah semua tugas selesai
setState(() { if (mounted) {
_isLoading = false; setState(() {
}); _isLoading = false;
});
}
}); });
// Inisialisasi _data di sini jika diperlukan // Inisialisasi _data di sini jika diperlukan
@ -313,79 +317,91 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
if (connection) { if (connection) {
print("Internet connection available"); print("Internet connection available");
} else { } else {
ScaffoldMessenger.of(context) ScaffoldMessenger.of(context).showSnackBar(
.showSnackBar(SnackBar(content: Text("No Internet"))); SnackBar(content: Text("Tidak ada koneksi internet")));
} }
}); });
} }
// Datatables ------------------------------------------------------------------------ // Datatables ------------------------------------------------------------------------
Future datatablesPengembalianList() async { Future datatablesPengembalianList() async {
await ControllerPengembalian() if (mounted) {
.fetchPengembalianLocalController() await ControllerPengembalian()
.then((value) { .fetchPengembalianLocalController()
setState(() { .then((value) {
_data = (value as List<dynamic>) setState(() {
.map((e) => AssetStatusModel.fromJson(e)) _data = (value as List<dynamic>)
.toList(); .map((e) => AssetStatusModel.fromJson(e))
loading = false; .toList();
loading = false;
});
}); });
}); }
} }
Future datatablesPetiList() async { Future datatablesPetiList() async {
await ControllerPengembalian().fetchPetiData().then((value) { if (mounted) {
setState(() { await ControllerPengembalian().fetchPetiData().then((value) {
_petiData = (value as List<dynamic>) setState(() {
.map((e) => PetiAssetModel.fromJson(e)) _petiData = (value as List<dynamic>)
.toList(); .map((e) => PetiAssetModel.fromJson(e))
loading = false; .toList();
loading = false;
});
}); });
}); }
} }
Future datatablesTipePetiList() async { Future datatablesTipePetiList() async {
await ControllerPengembalian().fetchTipePetiData().then((value) { if (mounted) {
setState(() { await ControllerPengembalian().fetchTipePetiData().then((value) {
_tipePetiData = (value as List<dynamic>) setState(() {
.map((e) => TypePetiModel.fromJson(e)) _tipePetiData = (value as List<dynamic>)
.toList(); .map((e) => TypePetiModel.fromJson(e))
loading = false; .toList();
loading = false;
});
}); });
}); }
} }
Future datatablesCustomerList() async { Future datatablesCustomerList() async {
await ControllerPengembalian().fetchCustomerData().then((value) { if (mounted) {
setState(() { await ControllerPengembalian().fetchCustomerData().then((value) {
_customerData = (value as List<dynamic>) setState(() {
.map((e) => CustomerModel.fromJson(e)) _customerData = (value as List<dynamic>)
.toList(); .map((e) => CustomerModel.fromJson(e))
loading = false; .toList();
loading = false;
});
}); });
}); }
} }
Future datatablesWarehouseList() async { Future datatablesWarehouseList() async {
await ControllerPengembalian().fetchWarehouseData().then((value) { if (mounted) {
setState(() { await ControllerPengembalian().fetchWarehouseData().then((value) {
_warehouseData = (value as List<dynamic>) setState(() {
.map((e) => WarehouseModel.fromJson(e)) _warehouseData = (value as List<dynamic>)
.toList(); .map((e) => WarehouseModel.fromJson(e))
loading = false; .toList();
loading = false;
});
}); });
}); }
} }
Future datatablesConditionList() async { Future datatablesConditionList() async {
await ControllerPengembalian().fetchConditionData().then((value) { if (mounted) {
setState(() { await ControllerPengembalian().fetchConditionData().then((value) {
_conditionData = (value as List<dynamic>) setState(() {
.map((e) => ConditionPetiModel.fromJson(e)) _conditionData = (value as List<dynamic>)
.toList(); .map((e) => ConditionPetiModel.fromJson(e))
loading = false; .toList();
loading = false;
});
}); });
}); }
} }
void _loadMoreData() { void _loadMoreData() {
@ -524,7 +540,7 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
showSyncDialog(context); showSyncDialog(context);
} else { } else {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("No internet connection")), SnackBar(content: Text("Tidak ada koneksi internet")),
); );
} }
}, },
@ -562,9 +578,11 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
rowsPerPage: _pageSize, rowsPerPage: _pageSize,
availableRowsPerPage: [10, 25, 50], // Removed const availableRowsPerPage: [10, 25, 50], // Removed const
onRowsPerPageChanged: (value) { onRowsPerPageChanged: (value) {
setState(() { if (mounted) {
_pageSize = value!; setState(() {
}); _pageSize = value!;
});
}
}, },
columns: [ columns: [
DataColumn(label: Text('No')), DataColumn(label: Text('No')),

22
lib/pages/pengembalian_barang/show.dart

@ -48,12 +48,14 @@ class _DetailPengembalianBarangPageState
initializeDateFormatting('id_ID', null); initializeDateFormatting('id_ID', null);
// Delay sejenak sebelum memanggil EasyLoading.dismiss() // Delay sejenak sebelum memanggil EasyLoading.dismiss()
Future.delayed(Duration(seconds: 1), () { if (mounted) {
setState(() { Future.delayed(Duration(seconds: 1), () {
loading = false; // Mengatur loading ke false setelah tugas selesai setState(() {
loading = false; // Mengatur loading ke false setelah tugas selesai
});
EasyLoading.dismiss();
}); });
EasyLoading.dismiss(); }
});
} }
Future customerListAPI() async { Future customerListAPI() async {
@ -115,7 +117,9 @@ class _DetailPengembalianBarangPageState
(pengembalian) => pengembalian.id.toString() == widget.pengembalianId, (pengembalian) => pengembalian.id.toString() == widget.pengembalianId,
); );
setState(() {}); if (mounted) {
setState(() {});
}
} }
String _formatDate(String? date) { String _formatDate(String? date) {
@ -351,6 +355,12 @@ class _DetailPengembalianBarangPageState
: '-', : '-',
), ),
Divider(thickness: 1), Divider(thickness: 1),
_buildDetailItem(
'PIC',
pengembalianInfo!.enter_pic != null
? pengembalianInfo!.enter_pic.toString()
: '-'),
Divider(thickness: 1),
// ... tambahkan data lainnya sesuai kebutuhan // ... tambahkan data lainnya sesuai kebutuhan
], ],
], ],

9
lib/pages/sign_in_page.dart

@ -172,9 +172,13 @@ class __FormContentState extends State<_FormContent> {
// final String roleId = 'A5C7B207-1A1C-43B8-89BF-222222222222'; // final String roleId = 'A5C7B207-1A1C-43B8-89BF-222222222222';
print('token dapat login: ${user.token}'); print('token dapat login: ${user.token}');
if (user.role_id == 2) { if (user != null && user.role_id == 2) {
print('Berhasil login HALAMAN USER'); print('Berhasil login HALAMAN USER');
Navigator.pushNamed(context, '/home'); if (context != null) {
Navigator.pushReplacementNamed(context, '/home');
} else {
print('Context is null');
}
} else { } else {
print('Tidak ada informasi peran (roles) yang tersedia'); print('Tidak ada informasi peran (roles) yang tersedia');
} }
@ -239,6 +243,7 @@ class __FormContentState extends State<_FormContent> {
prefixIcon: Icon(Icons.email_outlined), prefixIcon: Icon(Icons.email_outlined),
border: OutlineInputBorder(), border: OutlineInputBorder(),
), ),
keyboardType: TextInputType.emailAddress,
), ),
_gap(), _gap(),
TextFormField( TextFormField(

6
lib/pages/transfer_peti/index.dart

@ -299,8 +299,8 @@ class TransferPetiPageState extends State<TransferPetiPage> {
if (connection) { if (connection) {
print("Internet connection available"); print("Internet connection available");
} else { } else {
ScaffoldMessenger.of(context) ScaffoldMessenger.of(context).showSnackBar(
.showSnackBar(SnackBar(content: Text("No Internet"))); SnackBar(content: Text("Tidak ada koneksi internet")));
} }
}); });
} }
@ -500,7 +500,7 @@ class TransferPetiPageState extends State<TransferPetiPage> {
showSyncDialog(context); showSyncDialog(context);
} else { } else {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("No internet connection")), SnackBar(content: Text("Tidak ada koneksi internet")),
); );
} }
}, },

13
lib/widget/component_query.dart

@ -0,0 +1,13 @@
import 'package:intl/intl.dart';
import 'package:flutter/material.dart';
String _formatDate(String? date) {
if (date != null) {
DateTime parsedDate = DateTime.parse(date);
String formattedDate =
DateFormat('EEEE, dd MMMM yyyy', 'id_ID').format(parsedDate);
return formattedDate;
} else {
return '';
}
}

299
lib/widget/loading_shimmer_show.dart

@ -0,0 +1,299 @@
import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
class ShimmerShow extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(16.0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
elevation: 5,
child: Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Column(
children: [
Card(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.vertical(top: Radius.circular(15.0)),
),
elevation: 0,
margin: EdgeInsets.all(0),
color: Colors.grey[300],
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.article, size: 30, color: Colors.white),
SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'ID:',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
SizedBox(height: 5),
Text(
'-',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
],
),
],
),
],
),
),
),
SizedBox(height: 10),
_buildShimmerDetailItem(),
Divider(thickness: 1),
_buildShimmerDetailItem(),
Divider(thickness: 1),
_buildShimmerDetailItem(),
Divider(thickness: 1),
_buildShimmerDetailItem(),
Divider(thickness: 1),
_buildShimmerDetailItem(),
Divider(thickness: 1),
_buildShimmerDetailItem(),
Divider(thickness: 1),
_buildShimmerDetailItem(),
Divider(thickness: 1),
_buildShimmerDetailItem(),
Divider(thickness: 1),
_buildShimmerDetailItem(),
Divider(thickness: 1),
_buildShimmerDetailItem(),
// ... tambahkan shimmer item lainnya sesuai kebutuhan
],
),
),
),
);
}
Widget _buildShimmerDetailItem() {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: 80,
height: 12,
color: Colors.grey[300],
),
Container(
width: 120,
height: 12,
color: Colors.grey[300],
),
],
),
);
}
}
class ShimmerLoadingAssetStatusCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
Card(
elevation: 0.0,
shape: RoundedRectangleBorder(
side: BorderSide(color: Colors.grey, width: 1.0),
// borderRadius: BorderRadius.circular(10),
),
child: Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Padding(
padding: const EdgeInsets.only(
top: 8.0,
bottom: 8.0,
left: 16.0,
right: 16.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildAvatarAndIndex(),
Divider(),
_buildInfoRow('Nama Peminjam:', '', 'PIC:', '', 11.5),
_buildInfoRow('Tanggal Peminjaman:', '',
'Estimasi Pengembalian:', '', 11.5),
_buildInfoRow('Asal Gudang:', '', 'Tujuan Gudang:', '', 11.5),
],
),
),
),
),
],
);
}
Widget _buildAvatarAndIndex() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildAvatar(),
Expanded(
child: Padding(
padding: const EdgeInsets.only(
left: 8.0,
top: 8.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Text(
// '',
// style: TextStyle(
// fontWeight: FontWeight.bold,
// fontSize: 11.5,
// ),
// ),
lineDivider(),
],
),
),
),
],
);
}
Widget lineDivider() {
return Container(
height: 13,
width: double.infinity,
decoration: BoxDecoration(
color: Colors.grey[500],
borderRadius: BorderRadius.vertical(
top: Radius.circular(6), // Adjust top radius as needed
bottom: Radius.circular(6), // Adjust bottom radius as needed
),
),
);
}
Widget _buildAvatar() {
return Container(
child: CircleAvatar(
radius: 11,
backgroundColor: Colors.indigo,
),
);
}
Widget _buildInfoRow(String title1, String content1, String title2,
String content2, double fontSize) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title1,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: fontSize,
),
),
SizedBox(height: 3),
lineDivider(),
// Text(
// content1,
// style: TextStyle(
// fontSize: fontSize - 0.5,
// ),
// ),
],
),
),
SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// lineDivider(),
Text(
title2,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: fontSize,
),
),
SizedBox(height: 3),
lineDivider()
// Text(
// content2,
// style: TextStyle(
// fontSize: fontSize - 0.5,
// ),
// ),
],
),
),
],
);
}
}
Widget shimmerSearch() {
return Container(
margin: EdgeInsets.only(top: 8, bottom: 8),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.grey, width: 1.0),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row(
children: [
Icon(Icons.search),
SizedBox(width: 8),
Expanded(
child: Container(
height: 16, // Match the font size in the original search
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
),
),
],
),
),
),
),
),
);
}

8
pubspec.lock

@ -222,6 +222,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.13.1" version: "0.13.1"
flutter_slidable:
dependency: "direct main"
description:
name: flutter_slidable
sha256: "19ed4813003a6ff4e9c6bcce37e792a2a358919d7603b2b31ff200229191e44c"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
flutter_spinkit: flutter_spinkit:
dependency: transitive dependency: transitive
description: description:

2
pubspec.yaml

@ -55,6 +55,7 @@ dependencies:
dropdown_search: ^5.0.6 dropdown_search: ^5.0.6
shimmer: ^3.0.0 shimmer: ^3.0.0
loading_animation_widget: ^1.2.0+4 loading_animation_widget: ^1.2.0+4
flutter_slidable: ^3.0.1
@ -95,6 +96,7 @@ flutter:
# To add assets to your application, add an assets section, like this: # To add assets to your application, add an assets section, like this:
assets: assets:
- assets/img/ - assets/img/
- assets/item/
# - images/a_dot_ham.jpeg # - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see # An image asset can refer to one or more resolution-specific "variants", see

Loading…
Cancel
Save