Browse Source

perbaiki menu pengembalian, transfer peti, login roles, dan reinit

master
unknown 11 months ago
parent
commit
a7b3230f42
  1. 2
      lib/connection/connection.dart
  2. 7
      lib/models/user_model.dart
  3. 21
      lib/models/user_role_model.dart
  4. 435
      lib/pages/home/home_page.dart
  5. 959
      lib/pages/peminjaman_barang/create-finish.dart
  6. 1009
      lib/pages/peminjaman_barang/create.dart
  7. 130
      lib/pages/peminjaman_barang/peminjaman_stock_page.dart
  8. 262
      lib/pages/peminjaman_barang/show.dart
  9. 761
      lib/pages/pengembalian_barang/edit-finish.dart
  10. 1514
      lib/pages/pengembalian_barang/edit.dart
  11. 1077
      lib/pages/pengembalian_barang/index.dart
  12. 266
      lib/pages/pengembalian_barang/show.dart
  13. 29
      lib/pages/sign_in_page.dart
  14. 899
      lib/pages/transfer_peti/edit-finish.dart
  15. 1690
      lib/pages/transfer_peti/edit.dart
  16. 1068
      lib/pages/transfer_peti/index.dart
  17. 262
      lib/pages/transfer_peti/show.dart
  18. 13
      lib/widget/component_query.dart
  19. 36
      lib/widget/loading_shimmer_show.dart

2
lib/connection/connection.dart

@ -6,7 +6,7 @@ Future<String> getBaseUrl() async {
try {
SharedPreferences prefs = await SharedPreferences.getInstance();
String ipAddress =
prefs.getString('ipAddress') ?? '192.168.0.18'; // Default value
prefs.getString('ipAddress') ?? '192.168.1.14'; // Default value
String port = prefs.getString('port') ?? '8000'; // Default value
String baseUrl = 'http://$ipAddress:$port/api/v1';

7
lib/models/user_model.dart

@ -1,5 +1,7 @@
import 'package:flutter/cupertino.dart';
import 'user_role_model.dart';
class UserModel {
String? id;
String? username;
@ -14,6 +16,8 @@ class UserModel {
int? warehouse_id;
String? token;
UserRoleModel? role;
UserModel({
this.id,
this.username,
@ -27,6 +31,7 @@ class UserModel {
this.role_id,
this.warehouse_id,
this.token,
this.role,
});
UserModel.fromJson(Map<String, dynamic> json) {
@ -45,6 +50,7 @@ class UserModel {
? int.parse(json['warehouse_id'].toString())
: null;
token = json['token'].toString();
role = json['role'] != null ? UserRoleModel.fromJson(json['role']) : null;
}
Map<String, dynamic> toJson() {
@ -61,6 +67,7 @@ class UserModel {
'role_id': role_id.toString(),
'warehouse_id': warehouse_id.toString(),
'token': token.toString(),
'role': role!.toJson(),
};
}
}

21
lib/models/user_role_model.dart

@ -0,0 +1,21 @@
class UserRoleModel {
int? id;
String? name;
UserRoleModel({
this.id,
this.name,
});
UserRoleModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'] != null ? json['name'] : null;
}
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
};
}
}

435
lib/pages/home/home_page.dart

@ -20,6 +20,7 @@ import 'package:intl/date_symbol_data_local.dart';
import '../../services/controllerApi.dart';
import '../../services/syncronizeAPI.dart';
import '../../theme.dart';
import '../../widget/loading_shimmer_show.dart';
import '../peminjaman_barang/conn/syncronize.dart';
import '../peminjaman_barang/controller/peminjaman_controller.dart';
import '../pengembalian_barang/conn/syncronize.dart';
@ -46,6 +47,7 @@ class _HomePageState extends State<HomePage> {
List<PetiAssetModel>? _valpeti; // Change this line
List<WarehouseModel>? _valwarehouse;
List<ConditionPetiModel>? _valcondition;
// Datatable
int _currentPage = 1;
@ -61,15 +63,23 @@ class _HomePageState extends State<HomePage> {
int _pengembalianCount = 0;
int _transferCount = 0;
bool _isLoading = true;
bool _isLoading = false;
bool _isFetchingData = false;
@override
void initState() {
super.initState();
_getUserToken();
_initData();
// Menerapkan Future untuk menangani tugas asinkronus
// Mengatur _isLoading ke true sebelum tugas dimulai
if (mounted) {
setState(() {
_isLoading = true;
});
}
Future.wait([
_initData(),
warehouseListAPI(),
typePetiListAPI(),
customerListAPI(),
@ -79,16 +89,15 @@ class _HomePageState extends State<HomePage> {
datatablesTipePetiList(),
datatablesCustomerList(),
datatablesWarehouseList(),
initializeDateFormatting('id_ID', null),
]).then((_) {
// Selesaikan loading setelah semua tugas selesai
// Mengatur _isLoading ke false setelah semua tugas selesai
if (mounted) {
setState(() {
_isLoading = false;
});
}
});
// Inisialisasi _data di sini jika diperlukan
_data = <AssetStatusModel>[];
}
@ -172,6 +181,19 @@ class _HomePageState extends State<HomePage> {
}
}
Future kondisiPetiListAPI() async {
if (mounted) {
await ControllerApi().fetchKondisiPetiDataAPI().then((value) {
setState(() {
_valcondition = (value as List<dynamic>)
.map((item) => ConditionPetiModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
Future<void> reinitWarehouseApi() async {
EasyLoading.show(status: 'Mengambil data Warehouse...');
List<WarehouseModel> warehouseApiData =
@ -223,9 +245,26 @@ class _HomePageState extends State<HomePage> {
}
Future<void> fetchDataFromApiAndSync() async {
if (_isFetchingData) {
// Data is already being fetched, don't start another process
return;
}
// Set _isFetchingData to true to disable the button
setState(() {
_isFetchingData = true;
});
EasyLoading.show(status: 'Mengambil data dari Server...');
try {
// await syncToGlobal();
// Cek koneksi internet
bool hasInternet = await SyncronizationGlobalData.isInternet();
if (!hasInternet) {
EasyLoading.showError('Tidak ada koneksi internet');
return;
}
// Lanjutkan sinkronisasi jika ada koneksi
await syncToGlobal('Peminjaman');
await syncToGlobal('Pengembalian');
await syncToGlobal('Transfer');
@ -238,11 +277,18 @@ class _HomePageState extends State<HomePage> {
await reinitConditionPetiApi();
await datatablesAssetStatusList();
Navigator.pushNamed(context, '/home');
EasyLoading.showSuccess('Data berhasil diperbarui');
} catch (e) {
EasyLoading.showError('Gagal memperbarui data: $e');
} finally {
EasyLoading.dismiss();
// Set _isFetchingData back to false when the process finishes
if (mounted) {
setState(() {
_isFetchingData = false;
});
EasyLoading.dismiss();
}
}
}
@ -413,7 +459,7 @@ class _HomePageState extends State<HomePage> {
),
SizedBox(height: 5),
Text(
'Peminjaman',
'Peminjaman (Peti Out)',
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
),
],
@ -449,7 +495,7 @@ class _HomePageState extends State<HomePage> {
),
SizedBox(height: 5),
Text(
'Pengembalian',
'Pengembalian (Peti In)',
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
),
],
@ -624,9 +670,12 @@ class _HomePageState extends State<HomePage> {
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildCountTile(Icons.vertical_align_top, peminjamanCount,
Colors.green[700]!, 'Peminjaman'),
_buildCountTile(Icons.vertical_align_bottom,
pengembalianCount, Colors.blue[700]!, 'Pengembalian'),
Colors.green[700]!, 'Peminjaman (Peti Out)'),
_buildCountTile(
Icons.vertical_align_bottom,
pengembalianCount,
Colors.blue[700]!,
'Pengembalian (Peti In)'),
_buildCountTile(Icons.input_outlined, transferCount,
Colors.yellow[700]!, 'Transfer'),
],
@ -643,10 +692,11 @@ class _HomePageState extends State<HomePage> {
Container(
width: double.infinity,
child: TextButton(
onPressed: () {
Navigator.pop(context); // Close dialog
fetchDataFromApiAndSync();
},
onPressed: _isFetchingData
? null
: () {
fetchDataFromApiAndSync();
},
child: Text(
"Upload + Download",
style: TextStyle(
@ -688,117 +738,133 @@ class _HomePageState extends State<HomePage> {
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',
),
_isLoading
? ShimmerLoadingReinit()
: _buildCountTile(
Icons.vertical_align_top,
_peminjamanCount,
Colors.green[700]!,
'Peti Out',
),
_isLoading
? ShimmerLoadingReinit()
: _buildCountTile(
Icons.vertical_align_bottom,
_pengembalianCount,
Colors.blue[700]!,
'Peti In',
),
_isLoading
? ShimmerLoadingReinit()
: _buildCountTile(
Icons.input_outlined,
_transferCount,
Colors.yellow[700]!,
'Transfer Peti',
),
],
),
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,
onPressed: () async {
bool hasInternet = await ControllerApi.isInternetApi();
if (hasInternet) {
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,
IconButton(
icon: Icon(
Icons.close,
color: Colors.white,
),
onPressed: () {
Navigator.pop(context); // Close dialog
},
),
onPressed: () {
Navigator.pop(context); // Close dialog
},
),
],
],
),
),
),
// Divider
Divider(
height: 1,
thickness: 1,
color: Colors.black, // Black divider
),
// 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,
// 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',
// Re-init Button with blue background
ElevatedButton(
onPressed: () {
if (hasInternet) {
Navigator.pop(context); // Close dialog
fetchDataFromApiAndSync();
} else {
EasyLoading.showError(
"Tidak ada koneksi internet");
}
},
style: TextButton.styleFrom(
backgroundColor: Colors.blue[700],
),
child: Text(
"Upload + Download",
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
fontFamily: 'Poppins',
),
),
),
),
],
),
);
},
);
],
),
);
},
);
} else {
EasyLoading.showError("Tidak ada koneksi internet");
}
},
style: ElevatedButton.styleFrom(
primary: Colors.blue[700],
@ -829,93 +895,78 @@ class _HomePageState extends State<HomePage> {
);
}
return Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
elevation: 0,
automaticallyImplyLeading: false,
backgroundColor: Colors.indigo[700],
// actions: [
// IconButton(
// icon: Icon(
// Icons.cloud_sync,
// size: 30,
// ),
// onPressed: () async {
// if (await SyncronizationGlobalData.isInternet()) {
// // Display custom dialog when the IconButton is pressed
// showSyncDialog(context);
// } else {
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(content: Text("No internet connection")),
// );
// }
// },
// ),
// ],
centerTitle: true,
title: Row(
children: [
SizedBox(width: 10),
Expanded(
child: Center(
child: Column(
children: [
Text(
'SIOPAS-ISTW',
textAlign: TextAlign.center,
),
Text(
'${user.fullname}',
style: TextStyle(
fontSize: 10,
),
),
],
),
),
),
],
),
),
body: ListView(
children: [
cardMenuSync(),
SizedBox(height: 10),
Container(
padding: EdgeInsets.all(10),
child: Text(
'Menu Aplikasi',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
return AbsorbPointer(
absorbing: _isFetchingData,
child: Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
elevation: 0,
automaticallyImplyLeading: false,
backgroundColor: Colors.indigo[700],
centerTitle: true,
title: Row(
children: [
SizedBox(width: 10),
Expanded(
child: cardMenuPeminjaman(),
),
Expanded(
child: cardMenuPengembalian(),
child: Center(
child: Column(
children: [
Text(
'SIOPAS-ISTW',
textAlign: TextAlign.center,
),
Text(
'${user.fullname}',
style: TextStyle(
fontSize: 10,
),
),
],
),
),
),
],
),
SizedBox(height: 10), // Add some space between rows
Row(
children: [
Expanded(
child: cardMenuTransfer(),
),
Expanded(
child: Container(),
// child: cardMenuPengembalian(),
),
body: ListView(
children: [
cardMenuSync(),
SizedBox(height: 10),
Container(
padding: EdgeInsets.all(10),
child: Text(
'Menu Aplikasi',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
],
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: cardMenuPeminjaman(),
),
Expanded(
child: cardMenuPengembalian(),
),
],
),
SizedBox(height: 10), // Add some space between rows
Row(
children: [
Expanded(
child: cardMenuTransfer(),
),
Expanded(
child: Container(),
// child: cardMenuPengembalian(),
),
],
),
],
),
),
);
}

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

File diff suppressed because it is too large Load Diff

1009
lib/pages/peminjaman_barang/create.dart

File diff suppressed because it is too large Load Diff

130
lib/pages/peminjaman_barang/peminjaman_stock_page.dart

@ -497,27 +497,33 @@ class AssetStatusPageState extends State<AssetStatusPage> {
// );
// }
return DefaultTabController(
length: 1,
child: Scaffold(
appBar: appBarPeminjaman(context),
body: _isLoading
? Column(
children: [
// shimmerSearch(),
Expanded(
child: ListView.builder(
itemCount:
4, // Set the number of shimmer cards based on your data count
itemBuilder: (context, index) {
return ShimmerLoadingAssetStatusCard();
},
return WillPopScope(
onWillPop: () async {
// Mencegah kembali ke halaman sebelumnya
return false;
},
child: DefaultTabController(
length: 1,
child: Scaffold(
appBar: appBarPeminjaman(context),
body: _isLoading
? Column(
children: [
// shimmerSearch(),
Expanded(
child: ListView.builder(
itemCount:
4, // Set the number of shimmer cards based on your data count
itemBuilder: (context, index) {
return ShimmerLoadingAssetStatusCard();
},
),
),
),
],
)
: bodyPeminjaman(),
bottomNavigationBar: bottomAppBar(context),
],
)
: bodyPeminjaman(),
bottomNavigationBar: bottomAppBar(context),
),
),
);
}
@ -560,55 +566,6 @@ class AssetStatusPageState extends State<AssetStatusPage> {
Column bodyPeminjaman() {
return Column(
children: [
// Container(
// margin: EdgeInsets.only(top: 7, bottom: 7),
// child: Padding(
// padding: const EdgeInsets.symmetric(horizontal: 16),
// child: TextField(
// style: TextStyle(fontSize: 16),
// decoration: InputDecoration(
// hintText: 'Masukkan data pencarian...',
// prefixIcon: Icon(Icons.search),
// border: InputBorder.none,
// enabledBorder: OutlineInputBorder(
// borderRadius: BorderRadius.circular(12),
// borderSide: BorderSide(color: Colors.grey, width: 1.0),
// ),
// focusedBorder: OutlineInputBorder(
// borderRadius: BorderRadius.circular(12),
// borderSide: BorderSide(color: Colors.indigo, width: 1.0),
// ),
// contentPadding: EdgeInsets.all(16),
// labelStyle: TextStyle(
// color: Colors.grey,
// fontSize: 16,
// ),
// hintStyle: TextStyle(
// color: Colors.grey,
// fontSize: 16,
// ),
// prefixIconConstraints: BoxConstraints(
// minWidth: 40,
// ),
// suffixIcon: _searchQuery.isNotEmpty
// ? IconButton(
// icon: Icon(Icons.clear),
// onPressed: () {
// setState(() {
// _searchQuery = '';
// });
// },
// )
// : null,
// ),
// onChanged: (value) {
// setState(() {
// _searchQuery = value;
// });
// },
// ),
// ),
// ),
Expanded(
child: TabBarView(
children: [
@ -664,25 +621,10 @@ class AssetStatusPageState extends State<AssetStatusPage> {
return AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text('Data Peminjaman Peti',
title: Text('Data Peti Out',
style: TextStyle(
fontSize: 16,
)),
// actions: [
// IconButton(
// icon: Icon(Icons.backup),
// onPressed: () async {
// if (await SyncronizationPeminjamanData.isInternet()) {
// // Display custom dialog when the IconButton is pressed
// showSyncDialog(context);
// } else {
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(content: Text("Tidak ada koneksi internet")),
// );
// }
// },
// ),
// ],
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
@ -722,16 +664,6 @@ class AssetStatusPageState extends State<AssetStatusPage> {
color: Colors.grey,
fontSize: 12,
),
// suffixIcon: _searchQuery.isNotEmpty
// ? IconButton(
// icon: Icon(Icons.clear),
// onPressed: () {
// setState(() {
// // _searchQuery = null; // Mengganti dengan null
// });
// },
// )
// : null,
),
onChanged: (value) {
setState(() {
@ -939,9 +871,9 @@ class AssetStatusCard extends StatelessWidget {
_buildAvatarAndIndex(index),
Divider(),
_buildInfoRow(
'Nama Peminjam:',
'Nama Customer:',
'${customerSqfliteApi?.name ?? '-'}',
'PIC:',
'PIC/PJ:',
'${assetStatus.exit_pic ?? '-'}',
13),
_buildInfoRow(
@ -950,8 +882,8 @@ class AssetStatusCard extends StatelessWidget {
'Estimasi Pengembalian:',
'${_formatDate(assetStatus.est_pengembalian.toString())}',
13),
_buildInfoRow('Tujuan Gudang:',
'${warehouseSqfliteApi?.name ?? '-'}', '', '', 13),
_buildInfoRow('Gudang:', '${warehouseSqfliteApi?.name ?? '-'}',
'', '', 13),
],
),
),

262
lib/pages/peminjaman_barang/show.dart

@ -233,150 +233,142 @@ class _DetailPeminjamanBarangPageState
);
}
return Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text(
'Detail Peminjaman Peti',
style: TextStyle(
color: Colors.white,
fontSize: 16,
return WillPopScope(
onWillPop: () async {
// Mencegah kembali ke halaman sebelumnya
return false;
},
child: Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text(
'Detail Peti Out',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
),
),
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back),
),
actions: [
IconButton(
icon: Icon(Icons.delete, color: Colors.redAccent),
leading: IconButton(
onPressed: () {
_showDeleteConfirmationDialog();
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back),
),
],
),
body: FutureBuilder<void>(
future: _dataFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return ShimmerShow();
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return Padding(
padding: EdgeInsets.all(16.0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
elevation: 5,
child: Column(
children: [
Card(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.vertical(top: Radius.circular(15.0)),
),
elevation: 0,
margin: EdgeInsets.all(0),
color: Colors.indigo[700],
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(
petiSqfliteApi != null &&
petiSqfliteApi.fix_lot != null
? petiSqfliteApi!.fix_lot.toString()
: '-',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.white,
actions: [
IconButton(
icon: Icon(Icons.delete, color: Colors.redAccent),
onPressed: () {
_showDeleteConfirmationDialog();
},
),
],
),
body: FutureBuilder<void>(
future: _dataFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return ShimmerShow();
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return Padding(
padding: EdgeInsets.all(16.0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
elevation: 5,
child: Column(
children: [
Card(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.vertical(top: Radius.circular(15.0)),
),
elevation: 0,
margin: EdgeInsets.all(0),
color: Colors.indigo[700],
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: [
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(
'PIC/PJ:', peminjamanInfo!.exit_pic.toString()),
Divider(thickness: 1),
_buildDetailItem(
' Gudang',
warehouseSqfliteApi != null &&
warehouseSqfliteApi.name != null
? warehouseSqfliteApi!.name.toString()
: '-'),
Divider(thickness: 1),
// ... tambahkan data lainnya sesuai kebutuhan
],
],
],
),
),
),
);
}
},
);
}
},
),
),
);
}

761
lib/pages/pengembalian_barang/edit-finish.dart

@ -0,0 +1,761 @@
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:siopas/pages/pengembalian_barang/controller/pengembalian_controller.dart';
import 'package:uuid/uuid.dart';
import '../../models/asset_status_model.dart';
import '../../models/condition_peti_model.dart';
import '../../models/disposal_model.dart';
import '../../models/m_asset_status_model.dart';
import '../../models/user_model.dart';
import '../../models/warehouse_mode.dart';
import '../../providers/auth_provider.dart';
import '../../services/controllerApi.dart';
class EditFinishPengembalian extends StatefulWidget {
final List<AssetStatusModel> temporaryDataList;
EditFinishPengembalian({required this.temporaryDataList});
@override
_EditFinishPengembalianState createState() => _EditFinishPengembalianState();
}
class _EditFinishPengembalianState extends State<EditFinishPengembalian> {
String? token;
// List<CustomerModel>? customerSqfliteApi;
PetiAssetModel? petiSqfliteApi;
WarehouseModel? warehouseSqfliteApi;
ConditionPetiModel? conditionSqfliteApi;
DisposalPetiModel? disposalSqfliteApi;
List<PetiAssetModel>? _valpeti; // Change this line
List<WarehouseModel>? _valwarehouse;
List<ConditionPetiModel>? _valcondition;
List<DisposalPetiModel>? _valdisposal;
List<PetiAssetModel> _allPetiList = [];
List<PetiAssetModel> _unrestrictedPetiList = [];
List<PetiAssetModel> _filteredPetiList = [];
bool isQRCodeScanned = false;
String searchText = '';
PetiAssetModel? selectedPeti;
TextEditingController searchBoxController = TextEditingController();
TextEditingController _enter_atController = 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 kondisiPetiListAPI();
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 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 kondisiPetiListAPI() async {
if (mounted) {
await ControllerApi().fetchKondisiPetiDataAPI().then((value) {
setState(() {
_valcondition = (value as List<dynamic>)
.map((item) => ConditionPetiModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
@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('petiListPengembalian');
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('petiListPengembalian', 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: ${_enter_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 = [];
List<AssetStatusModel> assetAddModels = [];
for (PetiAssetModel selectedPeti in selectedPetis) {
// print("Checking conditions for Peti ID: ${selectedPeti.id}");
// print("Enter_atController: ${_enter_atController.text.isNotEmpty}");
// print("warehouseSqfliteApi: ${warehouseSqfliteApi != null}");
if (selectedPeti == null) {
print("Selected Peti is null");
continue;
}
PetiAssetModel? peti =
_valpeti?.firstWhereOrNull((peti) => peti.id == selectedPeti.id);
if (peti != null) {
if (_enter_atController.text.isNotEmpty &&
warehouseSqfliteApi != null) {
print("All conditions met. Preparing data...");
AssetStatusModel assetAddModel = AssetStatusModel(
id: null,
peti_id: selectedPeti.id,
enter_warehouse: warehouseSqfliteApi?.id,
enter_at: parseDateTime(_enter_atController.text),
enter_pic: _penanggungJawabController.text,
kondisi_peti_id: conditionSqfliteApi?.id,
updated_by: user.fullname,
updated_at: parseDateTime(formattedDate),
mobile_id: uuid.v4(),
);
assetAddModels.add(assetAddModel);
savedPetiIds.add(selectedPeti.id!);
} else {
print("Conditions not met. Unable to save data.");
if (_enter_atController.text.isEmpty) {
print("Enter_atController is empty");
}
if (warehouseSqfliteApi == null) {
print("warehouseSqfliteApi is null");
}
}
} else {
print("Peti not found for ID: ${selectedPeti.id}");
}
}
// Save all AssetStatusModels
for (AssetStatusModel assetAddModel in assetAddModels) {
int result =
await ControllerPengembalian().addPengembalianData(assetAddModel);
if (result <= 0) {
print("Failed untuk Peti ID: ${assetAddModel.peti_id}");
}
}
// Clear controllers and make fields nullable
if (mounted) {
setState(() {
_enter_atController.text = '';
_penanggungJawabController.text = '';
warehouseSqfliteApi?.id = 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, '/pengembalian-barang');
}
return WillPopScope(
onWillPop: () async {
// Mencegah kembali ke halaman sebelumnya
return true;
},
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: true,
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text('Isikan Data Peti In',
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(
'Tanggal Pengembalian:',
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
FormBuilderDateTimePicker(
validator: (value) {
if (_enter_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 pengembalian harus diisi'),
],
),
duration: Duration(seconds: 2),
),
);
return null; // Return null jika ada kesalahan
}
return null; // Return null jika tidak ada kesalahan
},
controller: _enter_atController,
name: 'tanggal_pengembalian',
inputType: InputType.date,
format: DateFormat('yyyy-MM-dd', 'id_ID'),
decoration: InputDecoration(
hintText: 'Tanggal Pengembalian',
border: OutlineInputBorder(),
suffixIcon: Icon(Icons.calendar_today),
),
onChanged: (DateTime? selectedDate) {
if (selectedDate != null) {
// Mengisi tanggal estimasi 7 hari ke depan
DateTime tanggalPengembalian =
selectedDate.add(Duration(days: 7));
_enter_atController.text =
DateFormat('yyyy-MM-dd')
.format(tanggalPengembalian);
}
},
),
],
),
),
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',
),
),
],
),
value: warehouse,
);
}).toList() ??
[],
onChanged: (value) {
setState(() {
warehouseSqfliteApi = value;
});
},
),
],
),
),
SizedBox(height: 16),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Kondisi Barang:',
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
DropdownButtonFormField<ConditionPetiModel>(
validator: (value) {
if (value == null) {
return 'Harus diisi';
}
return null;
},
decoration: InputDecoration(
hintText: 'Pilih Kondisi Peti',
border: OutlineInputBorder(),
),
hint: Text("Pilih Kondisi Peti"),
value: conditionSqfliteApi,
items: (_valcondition ?? [])
.where((kondisi) =>
kondisi.deleted_at != true)
.map((ConditionPetiModel kondisi) {
return DropdownMenuItem<
ConditionPetiModel>(
child: Row(
children: [
Icon(
kondisi.id ==
conditionSqfliteApi?.id
? Icons.check_box
: Icons
.check_box_outline_blank,
color: kondisi.id ==
conditionSqfliteApi?.id
? Colors.teal[700]
: Colors.grey,
),
SizedBox(
width: 8,
),
Text(
'${kondisi.nama_kondisi}',
style: TextStyle(
fontSize: 16,
fontFamily: 'OpenSansCondensed',
),
),
],
),
value: kondisi,
);
}).toList() ??
[],
onChanged: (ConditionPetiModel? value) {
if (mounted) {
setState(() {
conditionSqfliteApi = value;
});
}
},
),
],
),
),
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
},
),
],
),
),
],
),
),
);
}
},
),
),
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 (_enter_atController.text.isNotEmpty &&
warehouseSqfliteApi != null) {
await saveAssetData(selectedPetis);
// Menampilkan Snackbar dengan pesan sukses
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Row(
children: [
Icon(
Icons.check,
color: Colors.white,
),
SizedBox(width: 5),
Text('Data berhasil disimpan'),
],
),
backgroundColor: Colors.greenAccent[700],
duration: Duration(seconds: 2),
),
);
} 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),
),
),
],
),
),
],
),
),
),
);
}
}

1514
lib/pages/pengembalian_barang/edit.dart

File diff suppressed because it is too large Load Diff

1077
lib/pages/pengembalian_barang/index.dart

File diff suppressed because it is too large Load Diff

266
lib/pages/pengembalian_barang/show.dart

@ -11,6 +11,7 @@ import 'package:collection/collection.dart';
import '../../models/warehouse_mode.dart';
import '../../services/controllerApi.dart';
import '../../widget/loading_shimmer_show.dart';
class DetailPengembalianBarangPage extends StatefulWidget {
final String pengembalianId;
@ -34,26 +35,36 @@ class _DetailPengembalianBarangPageState
List<ConditionPetiModel>? _valconditionPeti;
bool loading = true;
late Future<void> _dataFuture;
@override
void initState() {
super.initState();
// Pemanggilan fungsi-fungsi yang diperlukan
getPengembalianIdData();
customerListAPI();
petiListAPI();
warehouseListAPI();
kondisiPetiListAPI();
initializeDateFormatting('id_ID', null);
// Delay sejenak sebelum memanggil EasyLoading.dismiss()
// Set loading ke true pada awalnya
if (mounted) {
Future.delayed(Duration(seconds: 1), () {
if (mounted) {
setState(() {
loading = false; // Mengatur loading ke false setelah tugas selesai
loading = false;
});
EasyLoading.dismiss();
}
}
_dataFuture = fetchData();
}
Future<void> fetchData() async {
await getPengembalianIdData();
await customerListAPI();
await petiListAPI();
await warehouseListAPI();
await kondisiPetiListAPI();
initializeDateFormatting('id_ID', null);
// Tandai bahwa proses loading telah selesai
if (mounted) {
setState(() {
loading = false;
});
}
}
@ -135,7 +146,7 @@ class _DetailPengembalianBarangPageState
Future<void> _deletePengembalian() async {
try {
// Panggil fungsi untuk menghapus peminjaman berdasarkan ID
// Panggil fungsi untuk menghapus pengembalian berdasarkan ID
await ControllerPengembalian()
.deletePengembalianById(widget.pengembalianId);
// Navigasi kembali ke halaman sebelumnya atau halaman yang sesuai
@ -223,7 +234,7 @@ class _DetailPengembalianBarangPageState
child: ElevatedButton(
child: Text('Hapus'),
onPressed: () {
// Panggil fungsi untuk menghapus peminjaman berdasarkan ID
// Panggil fungsi untuk menghapus pengembalian berdasarkan ID
_deletePengembalian();
Navigator.pushNamed(context, '/pengembalian-barang');
EasyLoading.showSuccess(
@ -240,131 +251,138 @@ class _DetailPengembalianBarangPageState
);
}
return Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text(
'Detail Pengembalian Peti',
style: TextStyle(
color: Colors.white,
fontSize: 16,
return WillPopScope(
onWillPop: () async {
// Mencegah kembali ke halaman sebelumnya
return false;
},
child: Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text(
'Detail Peti In',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
),
),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
Navigator.pushNamed(context, '/pengembalian-barang');
},
),
actions: [
IconButton(
icon: Icon(Icons.delete, color: Colors.redAccent),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
_showDeleteConfirmationDialog();
Navigator.pop(context);
},
),
],
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
elevation: 5,
child: Column(
children: [
Card(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.vertical(top: Radius.circular(15.0)),
),
elevation: 0,
margin: EdgeInsets.all(0),
color: Colors.indigo[700],
child: Padding(
padding: const EdgeInsets.all(16.0),
actions: [
IconButton(
icon: Icon(Icons.delete, color: Colors.redAccent),
onPressed: () {
_showDeleteConfirmationDialog();
},
),
],
),
body: FutureBuilder<void>(
future: _dataFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return ShimmerShow();
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return Padding(
padding: EdgeInsets.all(16.0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
elevation: 5,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.article, size: 30, color: Colors.white),
SizedBox(width: 10),
Column(
Card(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.vertical(top: Radius.circular(15.0)),
),
elevation: 0,
margin: EdgeInsets.all(0),
color: Colors.indigo[700],
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'ID:',
style: TextStyle(
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,
),
Row(
children: [
Icon(Icons.article,
size: 30, color: Colors.white),
SizedBox(width: 10),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
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 (pengembalianInfo != null) ...[
_buildDetailItem(
'Kode Peti',
petiSqfliteApi != null &&
petiSqfliteApi.fix_lot != null
? petiSqfliteApi!.fix_lot.toString()
: '-',
),
Divider(thickness: 1),
_buildDetailItem('Tgl Pengembalian',
_formatDate(pengembalianInfo!.enter_at.toString())),
Divider(thickness: 1),
_buildDetailItem(
'PIC/PJ:', pengembalianInfo!.enter_pic.toString()),
Divider(thickness: 1),
_buildDetailItem(
'Gudang',
warehouseSqfliteApi != null &&
warehouseSqfliteApi.name != null
? warehouseSqfliteApi!.name.toString()
: '-'),
Divider(thickness: 1),
_buildDetailItem(
'Kondisi Barang',
conditionPetiSqfliteApi != null &&
conditionPetiSqfliteApi.nama_kondisi != null
? conditionPetiSqfliteApi!.nama_kondisi.toString()
: '-',
),
Divider(thickness: 1),
// ... tambahkan data lainnya sesuai kebutuhan
],
],
),
),
),
SizedBox(height: 10),
if (pengembalianInfo != null) ...[
_buildDetailItem(
'Kode Peti',
petiSqfliteApi != null && petiSqfliteApi.fix_lot != null
? petiSqfliteApi!.fix_lot.toString()
: '-',
),
Divider(thickness: 1),
_buildDetailItem('Tgl Pengembalian',
_formatDate(pengembalianInfo!.enter_at.toString())),
Divider(thickness: 1),
_buildDetailItem(
'PJ Pengembalian', pengembalianInfo!.enter_pic.toString()),
Divider(thickness: 1),
_buildDetailItem(
'Gudang',
warehouseSqfliteApi != null &&
warehouseSqfliteApi.name != null
? warehouseSqfliteApi!.name.toString()
: '-'),
Divider(thickness: 1),
_buildDetailItem(
'Kondisi Peti',
conditionPetiSqfliteApi != null &&
conditionPetiSqfliteApi.nama_kondisi != null
? conditionPetiSqfliteApi!.nama_kondisi.toString()
: '-',
),
Divider(thickness: 1),
_buildDetailItem(
'PIC',
pengembalianInfo!.enter_pic != null
? pengembalianInfo!.enter_pic.toString()
: '-'),
Divider(thickness: 1),
// ... tambahkan data lainnya sesuai kebutuhan
],
],
),
);
}
},
),
),
);

29
lib/pages/sign_in_page.dart

@ -168,19 +168,22 @@ class __FormContentState extends State<_FormContent> {
// Simpan token pengguna ke SharedPreferences
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('token', user.token!); // Pastikan user.token tidak null
// Role ID Operator
// final String roleId = 'A5C7B207-1A1C-43B8-89BF-222222222222';
print('token dapat login: ${user.token}');
if (user != null && user.role_id == 2) {
print('Berhasil login HALAMAN USER');
if (context != null) {
Navigator.pushReplacementNamed(context, '/home');
if (user != null) {
String roleName = user.role!.name!.toLowerCase();
if (roleName == 'operator' || roleName == 'Operator') {
print('Berhasil login HALAMAN USER');
if (context != null) {
Navigator.pushReplacementNamed(context, '/home');
} else {
print('Context is null');
}
} else {
print('Context is null');
print('Tidak ada informasi peran (roles) yang tersedia');
}
} else {
print('Tidak ada informasi peran (roles) yang tersedia');
print('User tidak valid');
}
} else {
ScaffoldMessenger.of(context).showSnackBar(
@ -218,8 +221,10 @@ class __FormContentState extends State<_FormContent> {
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
// mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_gap(),
TextFormField(
validator: (value) {
// add email validation
@ -238,7 +243,6 @@ class __FormContentState extends State<_FormContent> {
},
controller: emailController,
decoration: const InputDecoration(
labelText: 'Email',
hintText: 'Masukkan email Anda',
prefixIcon: Icon(Icons.email_outlined),
border: OutlineInputBorder(),
@ -260,7 +264,6 @@ class __FormContentState extends State<_FormContent> {
obscureText: !_isPasswordVisible,
controller: passwordController,
decoration: InputDecoration(
labelText: 'Password',
hintText: 'Masukkan kata sandi Anda',
prefixIcon: const Icon(Icons.lock_outline_rounded),
border: const OutlineInputBorder(),
@ -343,7 +346,7 @@ class __FormContentState extends State<_FormContent> {
);
}
Widget _gap() => const SizedBox(height: 16);
Widget _gap() => const SizedBox(height: 14);
}
class SettingsModal extends StatefulWidget {

899
lib/pages/transfer_peti/edit-finish.dart

@ -0,0 +1,899 @@
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:siopas/models/customer_model.dart';
import 'package:siopas/pages/transfer_peti/controller/transfer_peti_controller.dart';
import 'package:uuid/uuid.dart';
import '../../models/condition_peti_model.dart';
import '../../models/disposal_model.dart';
import '../../models/m_asset_status_model.dart';
import '../../models/transfer_peti_model.dart';
import '../../models/user_model.dart';
import '../../models/warehouse_mode.dart';
import '../../providers/auth_provider.dart';
import '../../services/controllerApi.dart';
class EditFinishTransferPeti extends StatefulWidget {
final List<TransferPetiModel> temporaryDataList;
EditFinishTransferPeti({required this.temporaryDataList});
@override
_EditFinishTransferPetiState createState() => _EditFinishTransferPetiState();
}
class _EditFinishTransferPetiState extends State<EditFinishTransferPeti> {
String? token;
// List<CustomerModel>? customerSqfliteApi;
PetiAssetModel? petiSqfliteApi;
WarehouseModel? warehouseSqfliteApi;
WarehouseModel? warehouseTujuanSqfliteApi;
ConditionPetiModel? conditionSqfliteApi;
CustomerModel? customerSqfliteApi;
DisposalPetiModel? disposalSqfliteApi;
List<PetiAssetModel>? _valpeti; // Change this line
List<WarehouseModel>? _valwarehouse;
List<WarehouseModel>? _valTujuanwarehouse;
List<ConditionPetiModel>? _valcondition;
List<DisposalPetiModel>? _valdisposal;
List<CustomerModel>? _valcustomer;
List<PetiAssetModel> _allPetiList = [];
List<PetiAssetModel> _unrestrictedPetiList = [];
List<PetiAssetModel> _filteredPetiList = [];
bool isQRCodeScanned = false;
String searchText = '';
PetiAssetModel? selectedPeti;
TextEditingController searchBoxController = TextEditingController();
TextEditingController _date_atController = TextEditingController();
TextEditingController _penanggungJawabController = TextEditingController();
List<PetiAssetModel> selectedPetiList = [];
List<TransferPetiModel>? _data;
List<TransferPetiModel> 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 kondisiPetiListAPI();
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 customerListAPI() async {
if (mounted) {
await ControllerApi().fetchCustomerDataAPI().then((value) {
setState(() {
_valcustomer = (value as List<dynamic>)
.map((item) => CustomerModel.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 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 kondisiPetiListAPI() async {
if (mounted) {
await ControllerApi().fetchKondisiPetiDataAPI().then((value) {
setState(() {
_valcondition = (value as List<dynamic>)
.map((item) => ConditionPetiModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
@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('menu2_transferPetiList');
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('menu2_transferPetiList', 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: ${_date_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 = [];
List<TransferPetiModel> assetAddModels = [];
for (PetiAssetModel selectedPeti in selectedPetis) {
print("Checking conditions for Peti ID: ${selectedPeti.id}");
print("Enter_atController: ${_date_atController.text.isNotEmpty}");
print("warehouseSqfliteApi: ${warehouseSqfliteApi != null}");
if (selectedPeti == null) {
print("Selected Peti is null");
continue;
}
PetiAssetModel? peti =
_valpeti?.firstWhereOrNull((peti) => peti.id == selectedPeti.id);
if (peti != null) {
if (_date_atController.text.isNotEmpty &&
warehouseSqfliteApi != null) {
print("All conditions met. Preparing data...");
TransferPetiModel assetAddModel = TransferPetiModel(
id: null,
peti_id: selectedPeti.id,
name_customer: customerSqfliteApi?.id,
source_warehouse: warehouseSqfliteApi?.id,
destination_warehouse: warehouseTujuanSqfliteApi?.id,
date: parseDateTime(_date_atController.text),
created_by: user.fullname,
created_at: parseDateTime(formattedDate),
mobile_id: uuid.v4(),
);
assetAddModels.add(assetAddModel);
savedPetiIds.add(selectedPeti.id!);
} else {
print("Conditions not met. Unable to save data.");
if (_date_atController.text.isEmpty) {
print("Enter_atController is empty");
}
if (warehouseSqfliteApi == null) {
print("warehouseSqfliteApi is null");
}
}
} else {
print("Peti not found for ID: ${selectedPeti.id}");
}
}
// Save all TransferPetiModels
for (TransferPetiModel assetAddModel in assetAddModels) {
int result = await ControllerTransferPeti().addData(assetAddModel);
if (result <= 0) {
print("Failed untuk Peti ID: ${assetAddModel.peti_id}");
}
}
// Clear controllers and make fields nullable
if (mounted) {
setState(() {
_date_atController.text = '';
_penanggungJawabController.text = '';
warehouseSqfliteApi?.id = 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, '/transfer-peti');
}
return WillPopScope(
onWillPop: () async {
// Mencegah kembali ke halaman sebelumnya
return true;
},
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: true,
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text('Isikan Data Transfer 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(
'Tanggal Transfer Peti:',
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
FormBuilderDateTimePicker(
validator: (value) {
if (_date_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 transfer peti harus diisi'),
],
),
duration: Duration(seconds: 2),
),
);
return null; // Return null jika ada kesalahan
}
return null; // Return null jika tidak ada kesalahan
},
controller: _date_atController,
name: 'tanggal_transfer_peti',
inputType: InputType.date,
format: DateFormat('yyyy-MM-dd', 'id_ID'),
decoration: InputDecoration(
hintText: 'Tanggal Transfer Peti',
border: OutlineInputBorder(),
suffixIcon: Icon(Icons.calendar_today),
),
onChanged: (DateTime? selectedDate) {
if (selectedDate != null) {
// Mengisi tanggal estimasi 7 hari ke depan
DateTime tanggalTransferPeti =
selectedDate.add(Duration(days: 7));
_date_atController.text =
DateFormat('yyyy-MM-dd')
.format(tanggalTransferPeti);
}
},
),
],
),
),
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(
'Asal 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: 'Asal Gudang',
border: OutlineInputBorder(),
),
hint: Text("Asal 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',
),
),
],
),
value: warehouse,
);
}).toList() ??
[],
onChanged: (value) {
setState(() {
warehouseSqfliteApi = value;
});
},
),
],
),
),
SizedBox(height: 16),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Tujuan 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: 'Tujuan Gudang',
border: OutlineInputBorder(),
),
hint: Text("Tujuan Gudang"),
value: warehouseTujuanSqfliteApi,
items: (_valwarehouse ?? [])
.where((warehouse) =>
warehouse.deleted_at != true)
.map((WarehouseModel warehouse)
// _valwarehouse?.map((WarehouseModel warehouse)
{
return DropdownMenuItem<WarehouseModel>(
child: Row(
children: [
Icon(
Icons.local_shipping,
color: warehouseTujuanSqfliteApi
?.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',
),
),
],
),
value: warehouse,
);
}).toList() ??
[],
onChanged: (value) {
setState(() {
warehouseTujuanSqfliteApi = value;
});
},
),
],
),
),
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
},
),
],
),
),
],
),
),
);
}
},
),
),
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 (_date_atController.text.isNotEmpty &&
warehouseSqfliteApi != null) {
await saveAssetData(selectedPetis);
// Menampilkan Snackbar dengan pesan sukses
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Row(
children: [
Icon(
Icons.check,
color: Colors.white,
),
SizedBox(width: 5),
Text('Data berhasil disimpan'),
],
),
backgroundColor: Colors.greenAccent[700],
duration: Duration(seconds: 2),
),
);
} 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),
),
),
],
),
),
],
),
),
),
);
}
}

1690
lib/pages/transfer_peti/edit.dart

File diff suppressed because it is too large Load Diff

1068
lib/pages/transfer_peti/index.dart

File diff suppressed because it is too large Load Diff

262
lib/pages/transfer_peti/show.dart

@ -12,6 +12,7 @@ import 'package:siopas/pages/transfer_peti/controller/transfer_peti_controller.d
import '../../models/warehouse_mode.dart';
import '../../services/controllerApi.dart';
import '../../widget/loading_shimmer_show.dart';
class DetailTransferPetiPage extends StatefulWidget {
final int transferPetiId;
@ -30,23 +31,39 @@ class _DetailTransferPetiPageState extends State<DetailTransferPetiPage> {
List<PetiAssetModel>? petiData;
List<CustomerModel>? customerData;
List<WarehouseModel>? warehouseData;
bool loading = true;
late Future<void> _dataFuture;
@override
void initState() {
super.initState();
// Pemanggilan fungsi-fungsi yang diperlukan
// Set loading ke true pada awalnya
if (mounted) {
if (mounted) {
setState(() {
loading = false;
});
}
}
_dataFuture = fetchData();
}
Future<void> fetchData() async {
getTransferIdData();
customerListAPI();
petiListAPI();
warehouseListAPI();
initializeDateFormatting('id_ID', null);
// Mengatur loading ke false setelah tugas selesai
setState(() {
loading = false;
});
// Tandai bahwa proses loading telah selesai
if (mounted) {
setState(() {
loading = false;
});
}
}
Future customerListAPI() async {
@ -217,130 +234,147 @@ class _DetailTransferPetiPageState extends State<DetailTransferPetiPage> {
);
}
return Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text(
'Detail Transfer Peti',
style: TextStyle(
color: Colors.white,
fontSize: 16,
return WillPopScope(
onWillPop: () async {
// Mencegah kembali ke halaman sebelumnya
return false;
},
child: Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text(
'Detail Transfer Peti',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
),
),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
Navigator.pushNamed(context, '/transfer-peti');
},
),
actions: [
IconButton(
icon: Icon(Icons.delete, color: Colors.redAccent),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
_showDeleteConfirmationDialog();
// Navigator.pushNamed(context, '/transfer-peti');
Navigator.pop(context);
},
),
],
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
elevation: 5,
child: Column(
children: [
Card(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.vertical(top: Radius.circular(15.0)),
),
elevation: 0,
margin: EdgeInsets.all(0),
color: Colors.indigo[700],
child: Padding(
padding: const EdgeInsets.all(16.0),
actions: [
IconButton(
icon: Icon(Icons.delete, color: Colors.redAccent),
onPressed: () {
_showDeleteConfirmationDialog();
},
),
],
),
body: FutureBuilder<void>(
future: _dataFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return ShimmerShow();
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return Padding(
padding: EdgeInsets.all(16.0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
elevation: 5,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.article, size: 30, color: Colors.white),
SizedBox(width: 10),
Column(
Card(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.vertical(top: Radius.circular(15.0)),
),
elevation: 0,
margin: EdgeInsets.all(0),
color: Colors.indigo[700],
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'ID:',
style: TextStyle(
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,
),
Row(
children: [
Icon(Icons.article,
size: 30, color: Colors.white),
SizedBox(width: 10),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
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 (transferInfo != 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(
'PIC/PJ:', transferInfo!.created_by.toString()),
Divider(thickness: 1),
_buildDetailItem('Tanggal Transfer Peti:',
_formatDate(transferInfo!.created_at.toString())),
Divider(thickness: 1),
_buildDetailItem(
'Asal Gudang',
warehouseSqfliteApi != null &&
warehouseSqfliteApi.name != null
? warehouseSqfliteApi!.name.toString()
: '-'),
Divider(thickness: 1),
_buildDetailItem(
'Tujuan Gudang',
warehouseTujuanSqfliteApi != null &&
warehouseTujuanSqfliteApi.name != null
? warehouseTujuanSqfliteApi!.name.toString()
: '-',
),
Divider(thickness: 1),
// ... tambahkan data lainnya sesuai kebutuhan
],
],
),
),
),
SizedBox(height: 10),
if (transferInfo != 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 Transfer', _formatDate(transferInfo!.date.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
],
],
),
);
}
},
),
),
);

13
lib/widget/component_query.dart

@ -1,13 +0,0 @@
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 '';
}
}

36
lib/widget/loading_shimmer_show.dart

@ -297,3 +297,39 @@ Widget shimmerSearch() {
),
);
}
class ShimmerLoadingReinit extends StatelessWidget {
const ShimmerLoadingReinit({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Column(
children: [
CircleAvatar(
backgroundColor:
Colors.grey, // Set a default color for the CircleAvatar
radius: 12,
child: Icon(Icons.circle,
size: 12,
color: Colors.white), // Use a default icon (you can change it)
),
SizedBox(height: 4),
Container(
width: 40,
height: 12,
color: Colors.white,
),
SizedBox(height: 4),
Container(
width: 20,
height: 12,
color: Colors.white,
),
],
),
);
}
}

Loading…
Cancel
Save