Browse Source

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

master
unknown 1 year 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 { try {
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
String ipAddress = 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 port = prefs.getString('port') ?? '8000'; // Default value
String baseUrl = 'http://$ipAddress:$port/api/v1'; String baseUrl = 'http://$ipAddress:$port/api/v1';

7
lib/models/user_model.dart

@ -1,5 +1,7 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'user_role_model.dart';
class UserModel { class UserModel {
String? id; String? id;
String? username; String? username;
@ -14,6 +16,8 @@ class UserModel {
int? warehouse_id; int? warehouse_id;
String? token; String? token;
UserRoleModel? role;
UserModel({ UserModel({
this.id, this.id,
this.username, this.username,
@ -27,6 +31,7 @@ class UserModel {
this.role_id, this.role_id,
this.warehouse_id, this.warehouse_id,
this.token, this.token,
this.role,
}); });
UserModel.fromJson(Map<String, dynamic> json) { UserModel.fromJson(Map<String, dynamic> json) {
@ -45,6 +50,7 @@ class UserModel {
? int.parse(json['warehouse_id'].toString()) ? int.parse(json['warehouse_id'].toString())
: null; : null;
token = json['token'].toString(); token = json['token'].toString();
role = json['role'] != null ? UserRoleModel.fromJson(json['role']) : null;
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -61,6 +67,7 @@ class UserModel {
'role_id': role_id.toString(), 'role_id': role_id.toString(),
'warehouse_id': warehouse_id.toString(), 'warehouse_id': warehouse_id.toString(),
'token': token.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/controllerApi.dart';
import '../../services/syncronizeAPI.dart'; import '../../services/syncronizeAPI.dart';
import '../../theme.dart'; import '../../theme.dart';
import '../../widget/loading_shimmer_show.dart';
import '../peminjaman_barang/conn/syncronize.dart'; import '../peminjaman_barang/conn/syncronize.dart';
import '../peminjaman_barang/controller/peminjaman_controller.dart'; import '../peminjaman_barang/controller/peminjaman_controller.dart';
import '../pengembalian_barang/conn/syncronize.dart'; import '../pengembalian_barang/conn/syncronize.dart';
@ -46,6 +47,7 @@ class _HomePageState extends State<HomePage> {
List<PetiAssetModel>? _valpeti; // Change this line List<PetiAssetModel>? _valpeti; // Change this line
List<WarehouseModel>? _valwarehouse; List<WarehouseModel>? _valwarehouse;
List<ConditionPetiModel>? _valcondition;
// Datatable // Datatable
int _currentPage = 1; int _currentPage = 1;
@ -61,15 +63,23 @@ class _HomePageState extends State<HomePage> {
int _pengembalianCount = 0; int _pengembalianCount = 0;
int _transferCount = 0; int _transferCount = 0;
bool _isLoading = true; bool _isLoading = false;
bool _isFetchingData = false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_getUserToken(); _getUserToken();
_initData();
// Menerapkan Future untuk menangani tugas asinkronus // Mengatur _isLoading ke true sebelum tugas dimulai
if (mounted) {
setState(() {
_isLoading = true;
});
}
Future.wait([ Future.wait([
_initData(),
warehouseListAPI(), warehouseListAPI(),
typePetiListAPI(), typePetiListAPI(),
customerListAPI(), customerListAPI(),
@ -79,16 +89,15 @@ class _HomePageState extends State<HomePage> {
datatablesTipePetiList(), datatablesTipePetiList(),
datatablesCustomerList(), datatablesCustomerList(),
datatablesWarehouseList(), datatablesWarehouseList(),
initializeDateFormatting('id_ID', null),
]).then((_) { ]).then((_) {
// Selesaikan loading setelah semua tugas selesai // Mengatur _isLoading ke false setelah semua tugas selesai
if (mounted) { if (mounted) {
setState(() { setState(() {
_isLoading = false; _isLoading = false;
}); });
} }
}); });
// Inisialisasi _data di sini jika diperlukan
_data = <AssetStatusModel>[]; _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 { Future<void> reinitWarehouseApi() async {
EasyLoading.show(status: 'Mengambil data Warehouse...'); EasyLoading.show(status: 'Mengambil data Warehouse...');
List<WarehouseModel> warehouseApiData = List<WarehouseModel> warehouseApiData =
@ -223,9 +245,26 @@ class _HomePageState extends State<HomePage> {
} }
Future<void> fetchDataFromApiAndSync() async { 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...'); EasyLoading.show(status: 'Mengambil data dari Server...');
try { 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('Peminjaman');
await syncToGlobal('Pengembalian'); await syncToGlobal('Pengembalian');
await syncToGlobal('Transfer'); await syncToGlobal('Transfer');
@ -238,11 +277,18 @@ class _HomePageState extends State<HomePage> {
await reinitConditionPetiApi(); await reinitConditionPetiApi();
await datatablesAssetStatusList(); await datatablesAssetStatusList();
Navigator.pushNamed(context, '/home');
EasyLoading.showSuccess('Data berhasil diperbarui'); EasyLoading.showSuccess('Data berhasil diperbarui');
} catch (e) { } catch (e) {
EasyLoading.showError('Gagal memperbarui data: $e'); EasyLoading.showError('Gagal memperbarui data: $e');
} finally { } 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), SizedBox(height: 5),
Text( Text(
'Peminjaman', 'Peminjaman (Peti Out)',
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
), ),
], ],
@ -449,7 +495,7 @@ class _HomePageState extends State<HomePage> {
), ),
SizedBox(height: 5), SizedBox(height: 5),
Text( Text(
'Pengembalian', 'Pengembalian (Peti In)',
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
), ),
], ],
@ -624,9 +670,12 @@ class _HomePageState extends State<HomePage> {
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
_buildCountTile(Icons.vertical_align_top, peminjamanCount, _buildCountTile(Icons.vertical_align_top, peminjamanCount,
Colors.green[700]!, 'Peminjaman'), Colors.green[700]!, 'Peminjaman (Peti Out)'),
_buildCountTile(Icons.vertical_align_bottom, _buildCountTile(
pengembalianCount, Colors.blue[700]!, 'Pengembalian'), Icons.vertical_align_bottom,
pengembalianCount,
Colors.blue[700]!,
'Pengembalian (Peti In)'),
_buildCountTile(Icons.input_outlined, transferCount, _buildCountTile(Icons.input_outlined, transferCount,
Colors.yellow[700]!, 'Transfer'), Colors.yellow[700]!, 'Transfer'),
], ],
@ -643,10 +692,11 @@ class _HomePageState extends State<HomePage> {
Container( Container(
width: double.infinity, width: double.infinity,
child: TextButton( child: TextButton(
onPressed: () { onPressed: _isFetchingData
Navigator.pop(context); // Close dialog ? null
fetchDataFromApiAndSync(); : () {
}, fetchDataFromApiAndSync();
},
child: Text( child: Text(
"Upload + Download", "Upload + Download",
style: TextStyle( style: TextStyle(
@ -688,117 +738,133 @@ class _HomePageState extends State<HomePage> {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
_buildCountTile( _isLoading
Icons.vertical_align_top, ? ShimmerLoadingReinit()
_peminjamanCount, : _buildCountTile(
Colors.green[700]!, Icons.vertical_align_top,
'Peminjaman', _peminjamanCount,
), Colors.green[700]!,
_buildCountTile( 'Peti Out',
Icons.vertical_align_bottom, ),
_pengembalianCount, _isLoading
Colors.blue[700]!, ? ShimmerLoadingReinit()
'Pengembalian', : _buildCountTile(
), Icons.vertical_align_bottom,
_buildCountTile( _pengembalianCount,
Icons.input_outlined, Colors.blue[700]!,
_transferCount, 'Peti In',
Colors.yellow[700]!, ),
'Transfer', _isLoading
), ? ShimmerLoadingReinit()
: _buildCountTile(
Icons.input_outlined,
_transferCount,
Colors.yellow[700]!,
'Transfer Peti',
),
], ],
), ),
SizedBox(height: 10), SizedBox(height: 10),
// Re-init Button // Re-init Button
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () async {
showDialog( bool hasInternet = await ControllerApi.isInternetApi();
context: context, if (hasInternet) {
builder: (BuildContext context) { showDialog(
return Dialog( context: context,
backgroundColor: builder: (BuildContext context) {
Colors.grey[100], // Set the background color return Dialog(
shape: RoundedRectangleBorder( backgroundColor:
borderRadius: BorderRadius.circular(16), Colors.grey[100], // Set the background color
), shape: RoundedRectangleBorder(
elevation: 0, borderRadius: BorderRadius.circular(16),
child: Column( ),
mainAxisSize: MainAxisSize.min, elevation: 0,
children: [ child: Column(
// Dialog title with close button mainAxisSize: MainAxisSize.min,
Container( children: [
width: double.infinity, // Dialog title with close button
color: Colors.indigo[700], // Indigo background Container(
child: Row( width: double.infinity,
mainAxisAlignment: MainAxisAlignment.spaceBetween, color: Colors.indigo[700], // Indigo background
children: [ child: Row(
Padding( mainAxisAlignment:
padding: const EdgeInsets.all(16.0), MainAxisAlignment.spaceBetween,
child: Text( children: [
"Konfirmasi Sync", Padding(
style: TextStyle( padding: const EdgeInsets.all(16.0),
color: Colors.white, child: Text(
fontWeight: FontWeight.bold, "Konfirmasi Sync",
fontSize: 16.0, style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 16.0,
),
), ),
), ),
), IconButton(
IconButton( icon: Icon(
icon: Icon( Icons.close,
Icons.close, color: Colors.white,
color: Colors.white, ),
onPressed: () {
Navigator.pop(context); // Close dialog
},
), ),
onPressed: () { ],
Navigator.pop(context); // Close dialog ),
},
),
],
), ),
),
// Divider // Divider
Divider( Divider(
height: 1, height: 1,
thickness: 1, thickness: 1,
color: Colors.black, // Black divider color: Colors.black, // Black divider
), ),
// Description text // Description text
Container( Container(
padding: EdgeInsets.all(16.0), padding: EdgeInsets.all(16.0),
child: Text( child: Text(
"Apakah Anda yakin ingin mengunggah dan mengunduh data?", "Apakah Anda yakin ingin mengunggah dan mengunduh data?",
style: TextStyle( style: TextStyle(
fontSize: 16.0, fontSize: 16.0,
),
), ),
), ),
),
// Re-init Button with blue background // Re-init Button with blue background
ElevatedButton(
ElevatedButton( onPressed: () {
onPressed: () { if (hasInternet) {
Navigator.pop(context); // Close dialog Navigator.pop(context); // Close dialog
fetchDataFromApiAndSync(); fetchDataFromApiAndSync();
}, } else {
style: TextButton.styleFrom( EasyLoading.showError(
backgroundColor: Colors.blue[700], "Tidak ada koneksi internet");
), }
child: Text( },
"Upload + Download", style: TextButton.styleFrom(
style: TextStyle( backgroundColor: Colors.blue[700],
color: Colors.white, ),
fontSize: 16.0, child: Text(
fontFamily: 'Poppins', "Upload + Download",
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
fontFamily: 'Poppins',
),
), ),
), ),
), ],
], ),
), );
); },
}, );
); } else {
EasyLoading.showError("Tidak ada koneksi internet");
}
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
primary: Colors.blue[700], primary: Colors.blue[700],
@ -829,93 +895,78 @@ class _HomePageState extends State<HomePage> {
); );
} }
return Scaffold( return AbsorbPointer(
backgroundColor: Colors.grey[200], absorbing: _isFetchingData,
appBar: AppBar( child: Scaffold(
elevation: 0, backgroundColor: Colors.grey[200],
automaticallyImplyLeading: false, appBar: AppBar(
backgroundColor: Colors.indigo[700], elevation: 0,
// actions: [ automaticallyImplyLeading: false,
// IconButton( backgroundColor: Colors.indigo[700],
// icon: Icon( centerTitle: true,
// Icons.cloud_sync, title: Row(
// 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,
children: [ children: [
SizedBox(width: 10),
Expanded( Expanded(
child: cardMenuPeminjaman(), child: Center(
), child: Column(
Expanded( children: [
child: cardMenuPengembalian(), Text(
'SIOPAS-ISTW',
textAlign: TextAlign.center,
),
Text(
'${user.fullname}',
style: TextStyle(
fontSize: 10,
),
),
],
),
),
), ),
], ],
), ),
SizedBox(height: 10), // Add some space between rows ),
Row( body: ListView(
children: [ children: [
Expanded( cardMenuSync(),
child: cardMenuTransfer(), SizedBox(height: 10),
), Container(
Expanded( padding: EdgeInsets.all(10),
child: Container(), child: Text(
// child: cardMenuPengembalian(), '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( return WillPopScope(
length: 1, onWillPop: () async {
child: Scaffold( // Mencegah kembali ke halaman sebelumnya
appBar: appBarPeminjaman(context), return false;
body: _isLoading },
? Column( child: DefaultTabController(
children: [ length: 1,
// shimmerSearch(), child: Scaffold(
Expanded( appBar: appBarPeminjaman(context),
child: ListView.builder( body: _isLoading
itemCount: ? Column(
4, // Set the number of shimmer cards based on your data count children: [
itemBuilder: (context, index) { // shimmerSearch(),
return ShimmerLoadingAssetStatusCard(); Expanded(
}, child: ListView.builder(
itemCount:
4, // Set the number of shimmer cards based on your data count
itemBuilder: (context, index) {
return ShimmerLoadingAssetStatusCard();
},
),
), ),
), ],
], )
) : bodyPeminjaman(),
: bodyPeminjaman(), bottomNavigationBar: bottomAppBar(context),
bottomNavigationBar: bottomAppBar(context), ),
), ),
); );
} }
@ -560,55 +566,6 @@ class AssetStatusPageState extends State<AssetStatusPage> {
Column bodyPeminjaman() { Column bodyPeminjaman() {
return Column( return Column(
children: [ 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( Expanded(
child: TabBarView( child: TabBarView(
children: [ children: [
@ -664,25 +621,10 @@ class AssetStatusPageState extends State<AssetStatusPage> {
return AppBar( return AppBar(
backgroundColor: Colors.indigo[700], backgroundColor: Colors.indigo[700],
elevation: 0, elevation: 0,
title: Text('Data Peminjaman Peti', title: Text('Data Peti Out',
style: TextStyle( style: TextStyle(
fontSize: 16, 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( leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white), icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () { onPressed: () {
@ -722,16 +664,6 @@ class AssetStatusPageState extends State<AssetStatusPage> {
color: Colors.grey, color: Colors.grey,
fontSize: 12, fontSize: 12,
), ),
// suffixIcon: _searchQuery.isNotEmpty
// ? IconButton(
// icon: Icon(Icons.clear),
// onPressed: () {
// setState(() {
// // _searchQuery = null; // Mengganti dengan null
// });
// },
// )
// : null,
), ),
onChanged: (value) { onChanged: (value) {
setState(() { setState(() {
@ -939,9 +871,9 @@ class AssetStatusCard extends StatelessWidget {
_buildAvatarAndIndex(index), _buildAvatarAndIndex(index),
Divider(), Divider(),
_buildInfoRow( _buildInfoRow(
'Nama Peminjam:', 'Nama Customer:',
'${customerSqfliteApi?.name ?? '-'}', '${customerSqfliteApi?.name ?? '-'}',
'PIC:', 'PIC/PJ:',
'${assetStatus.exit_pic ?? '-'}', '${assetStatus.exit_pic ?? '-'}',
13), 13),
_buildInfoRow( _buildInfoRow(
@ -950,8 +882,8 @@ class AssetStatusCard extends StatelessWidget {
'Estimasi Pengembalian:', 'Estimasi Pengembalian:',
'${_formatDate(assetStatus.est_pengembalian.toString())}', '${_formatDate(assetStatus.est_pengembalian.toString())}',
13), 13),
_buildInfoRow('Tujuan Gudang:', _buildInfoRow('Gudang:', '${warehouseSqfliteApi?.name ?? '-'}',
'${warehouseSqfliteApi?.name ?? '-'}', '', '', 13), '', '', 13),
], ],
), ),
), ),

262
lib/pages/peminjaman_barang/show.dart

@ -233,150 +233,142 @@ class _DetailPeminjamanBarangPageState
); );
} }
return Scaffold( return WillPopScope(
backgroundColor: Colors.grey[200], onWillPop: () async {
appBar: AppBar( // Mencegah kembali ke halaman sebelumnya
backgroundColor: Colors.indigo[700], return false;
elevation: 0, },
title: Text( child: Scaffold(
'Detail Peminjaman Peti', backgroundColor: Colors.grey[200],
style: TextStyle( appBar: AppBar(
color: Colors.white, backgroundColor: Colors.indigo[700],
fontSize: 16, elevation: 0,
title: Text(
'Detail Peti Out',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
), ),
), leading: IconButton(
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back),
),
actions: [
IconButton(
icon: Icon(Icons.delete, color: Colors.redAccent),
onPressed: () { onPressed: () {
_showDeleteConfirmationDialog(); Navigator.pop(context);
}, },
icon: Icon(Icons.arrow_back),
), ),
], actions: [
), IconButton(
body: FutureBuilder<void>( icon: Icon(Icons.delete, color: Colors.redAccent),
future: _dataFuture, onPressed: () {
builder: (context, snapshot) { _showDeleteConfirmationDialog();
if (snapshot.connectionState == ConnectionState.waiting) { },
return ShimmerShow(); ),
} else if (snapshot.hasError) { ],
return Text('Error: ${snapshot.error}'); ),
} else { body: FutureBuilder<void>(
return Padding( future: _dataFuture,
padding: EdgeInsets.all(16.0), builder: (context, snapshot) {
child: Card( if (snapshot.connectionState == ConnectionState.waiting) {
shape: RoundedRectangleBorder( return ShimmerShow();
borderRadius: BorderRadius.circular(15.0), } else if (snapshot.hasError) {
), return Text('Error: ${snapshot.error}');
elevation: 5, } else {
child: Column( return Padding(
children: [ padding: EdgeInsets.all(16.0),
Card( child: Card(
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: borderRadius: BorderRadius.circular(15.0),
BorderRadius.vertical(top: Radius.circular(15.0)), ),
), elevation: 5,
elevation: 0, child: Column(
margin: EdgeInsets.all(0), children: [
color: Colors.indigo[700], Card(
child: Padding( shape: RoundedRectangleBorder(
padding: const EdgeInsets.all(16.0), borderRadius:
child: Column( BorderRadius.vertical(top: Radius.circular(15.0)),
crossAxisAlignment: CrossAxisAlignment.start, ),
children: [ elevation: 0,
Row( margin: EdgeInsets.all(0),
children: [ color: Colors.indigo[700],
Icon(Icons.article, child: Padding(
size: 30, color: Colors.white), padding: const EdgeInsets.all(16.0),
SizedBox(width: 10), child: Column(
Column( crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ Row(
Text( children: [
'ID:', Icon(Icons.article,
style: TextStyle( size: 30, color: Colors.white),
fontSize: 12, SizedBox(width: 10),
fontWeight: FontWeight.bold, Column(
color: Colors.white, crossAxisAlignment:
), CrossAxisAlignment.start,
), children: [
SizedBox(height: 5), SizedBox(height: 5),
Text( Text(
petiSqfliteApi != null && petiSqfliteApi != null &&
petiSqfliteApi.fix_lot != null petiSqfliteApi.fix_lot != null
? petiSqfliteApi!.fix_lot.toString() ? petiSqfliteApi!.fix_lot.toString()
: '-', : '-',
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Colors.white, color: Colors.white,
),
), ),
), ],
], ),
), ],
], ),
), ],
], ),
), ),
), ),
), SizedBox(height: 10),
SizedBox(height: 10), if (peminjamanInfo != null) ...[
if (peminjamanInfo != null) ...[ _buildDetailItem(
_buildDetailItem( 'Kode Peti',
'Kode Peti', petiSqfliteApi != null &&
petiSqfliteApi != null && petiSqfliteApi.fix_lot != null petiSqfliteApi.fix_lot != null
? petiSqfliteApi!.fix_lot.toString() ? petiSqfliteApi!.fix_lot.toString()
: '-', : '-',
), ),
Divider(thickness: 1), Divider(thickness: 1),
_buildDetailItem( _buildDetailItem(
'Nama Customer', 'Nama Customer',
customerSqfliteApi != null && customerSqfliteApi != null &&
customerSqfliteApi.name != null customerSqfliteApi.name != null
? customerSqfliteApi!.name.toString() ? customerSqfliteApi!.name.toString()
: '-', : '-',
), ),
Divider(thickness: 1), Divider(thickness: 1),
_buildDetailItem('Tgl Peminjaman', _buildDetailItem('Tgl Peminjaman',
_formatDate(peminjamanInfo!.exit_at.toString())), _formatDate(peminjamanInfo!.exit_at.toString())),
Divider(thickness: 1), Divider(thickness: 1),
_buildDetailItem( _buildDetailItem(
'Est Peminjaman', 'Est Peminjaman',
_formatDate( _formatDate(
peminjamanInfo!.est_pengembalian.toString())), peminjamanInfo!.est_pengembalian.toString())),
Divider(thickness: 1), Divider(thickness: 1),
_buildDetailItem( _buildDetailItem(
'PJ Peminjaman', peminjamanInfo!.exit_pic.toString()), 'PIC/PJ:', peminjamanInfo!.exit_pic.toString()),
Divider(thickness: 1), Divider(thickness: 1),
_buildDetailItem( _buildDetailItem(
' Gudang', ' Gudang',
warehouseSqfliteApi != null && warehouseSqfliteApi != null &&
warehouseSqfliteApi.name != null warehouseSqfliteApi.name != null
? warehouseSqfliteApi!.name.toString() ? warehouseSqfliteApi!.name.toString()
: '-'), : '-'),
Divider(thickness: 1),
Divider(thickness: 1), // ... tambahkan data lainnya sesuai kebutuhan
_buildDetailItem( ],
'PIC',
peminjamanInfo!.exit_pic != null
? peminjamanInfo!.exit_pic.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 '../../models/warehouse_mode.dart';
import '../../services/controllerApi.dart'; import '../../services/controllerApi.dart';
import '../../widget/loading_shimmer_show.dart';
class DetailPengembalianBarangPage extends StatefulWidget { class DetailPengembalianBarangPage extends StatefulWidget {
final String pengembalianId; final String pengembalianId;
@ -34,26 +35,36 @@ class _DetailPengembalianBarangPageState
List<ConditionPetiModel>? _valconditionPeti; List<ConditionPetiModel>? _valconditionPeti;
bool loading = true; bool loading = true;
late Future<void> _dataFuture;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
// Pemanggilan fungsi-fungsi yang diperlukan // Set loading ke true pada awalnya
getPengembalianIdData();
customerListAPI();
petiListAPI();
warehouseListAPI();
kondisiPetiListAPI();
initializeDateFormatting('id_ID', null);
// Delay sejenak sebelum memanggil EasyLoading.dismiss()
if (mounted) { if (mounted) {
Future.delayed(Duration(seconds: 1), () { if (mounted) {
setState(() { 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 { Future<void> _deletePengembalian() async {
try { try {
// Panggil fungsi untuk menghapus peminjaman berdasarkan ID // Panggil fungsi untuk menghapus pengembalian berdasarkan ID
await ControllerPengembalian() await ControllerPengembalian()
.deletePengembalianById(widget.pengembalianId); .deletePengembalianById(widget.pengembalianId);
// Navigasi kembali ke halaman sebelumnya atau halaman yang sesuai // Navigasi kembali ke halaman sebelumnya atau halaman yang sesuai
@ -223,7 +234,7 @@ class _DetailPengembalianBarangPageState
child: ElevatedButton( child: ElevatedButton(
child: Text('Hapus'), child: Text('Hapus'),
onPressed: () { onPressed: () {
// Panggil fungsi untuk menghapus peminjaman berdasarkan ID // Panggil fungsi untuk menghapus pengembalian berdasarkan ID
_deletePengembalian(); _deletePengembalian();
Navigator.pushNamed(context, '/pengembalian-barang'); Navigator.pushNamed(context, '/pengembalian-barang');
EasyLoading.showSuccess( EasyLoading.showSuccess(
@ -240,131 +251,138 @@ class _DetailPengembalianBarangPageState
); );
} }
return Scaffold( return WillPopScope(
backgroundColor: Colors.grey[200], onWillPop: () async {
appBar: AppBar( // Mencegah kembali ke halaman sebelumnya
backgroundColor: Colors.indigo[700], return false;
elevation: 0, },
title: Text( child: Scaffold(
'Detail Pengembalian Peti', backgroundColor: Colors.grey[200],
style: TextStyle( appBar: AppBar(
color: Colors.white, backgroundColor: Colors.indigo[700],
fontSize: 16, elevation: 0,
title: Text(
'Detail Peti In',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
), ),
), leading: IconButton(
leading: IconButton( icon: Icon(Icons.arrow_back, color: Colors.white),
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
Navigator.pushNamed(context, '/pengembalian-barang');
},
),
actions: [
IconButton(
icon: Icon(Icons.delete, color: Colors.redAccent),
onPressed: () { onPressed: () {
_showDeleteConfirmationDialog(); Navigator.pop(context);
}, },
), ),
], actions: [
), IconButton(
body: Padding( icon: Icon(Icons.delete, color: Colors.redAccent),
padding: EdgeInsets.all(16.0), onPressed: () {
child: Card( _showDeleteConfirmationDialog();
shape: RoundedRectangleBorder( },
borderRadius: BorderRadius.circular(15.0), ),
), ],
elevation: 5, ),
child: Column( body: FutureBuilder<void>(
children: [ future: _dataFuture,
Card( builder: (context, snapshot) {
shape: RoundedRectangleBorder( if (snapshot.connectionState == ConnectionState.waiting) {
borderRadius: return ShimmerShow();
BorderRadius.vertical(top: Radius.circular(15.0)), } else if (snapshot.hasError) {
), return Text('Error: ${snapshot.error}');
elevation: 0, } else {
margin: EdgeInsets.all(0), return Padding(
color: Colors.indigo[700], padding: EdgeInsets.all(16.0),
child: Padding( child: Card(
padding: const EdgeInsets.all(16.0), shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
elevation: 5,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( Card(
children: [ shape: RoundedRectangleBorder(
Icon(Icons.article, size: 30, color: Colors.white), borderRadius:
SizedBox(width: 10), BorderRadius.vertical(top: Radius.circular(15.0)),
Column( ),
elevation: 0,
margin: EdgeInsets.all(0),
color: Colors.indigo[700],
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Row(
'ID:', children: [
style: TextStyle( Icon(Icons.article,
fontSize: 12, size: 30, color: Colors.white),
fontWeight: FontWeight.bold, SizedBox(width: 10),
color: Colors.white, Column(
), crossAxisAlignment:
), CrossAxisAlignment.start,
SizedBox(height: 5), children: [
Text( SizedBox(height: 5),
petiSqfliteApi != null && Text(
petiSqfliteApi.fix_lot != null petiSqfliteApi != null &&
? petiSqfliteApi!.fix_lot.toString() petiSqfliteApi.fix_lot != null
: '-', ? petiSqfliteApi!.fix_lot.toString()
style: TextStyle( : '-',
fontSize: 12, style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 12,
color: Colors.white, 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 // Simpan token pengguna ke SharedPreferences
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('token', user.token!); // Pastikan user.token tidak null 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}'); print('token dapat login: ${user.token}');
if (user != null && user.role_id == 2) {
print('Berhasil login HALAMAN USER'); if (user != null) {
if (context != null) { String roleName = user.role!.name!.toLowerCase();
Navigator.pushReplacementNamed(context, '/home'); if (roleName == 'operator' || roleName == 'Operator') {
print('Berhasil login HALAMAN USER');
if (context != null) {
Navigator.pushReplacementNamed(context, '/home');
} else {
print('Context is null');
}
} else { } else {
print('Context is null'); print('Tidak ada informasi peran (roles) yang tersedia');
} }
} else { } else {
print('Tidak ada informasi peran (roles) yang tersedia'); print('User tidak valid');
} }
} else { } else {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
@ -218,8 +221,10 @@ class __FormContentState extends State<_FormContent> {
key: _formKey, key: _formKey,
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center, // mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
_gap(),
TextFormField( TextFormField(
validator: (value) { validator: (value) {
// add email validation // add email validation
@ -238,7 +243,6 @@ class __FormContentState extends State<_FormContent> {
}, },
controller: emailController, controller: emailController,
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: 'Email',
hintText: 'Masukkan email Anda', hintText: 'Masukkan email Anda',
prefixIcon: Icon(Icons.email_outlined), prefixIcon: Icon(Icons.email_outlined),
border: OutlineInputBorder(), border: OutlineInputBorder(),
@ -260,7 +264,6 @@ class __FormContentState extends State<_FormContent> {
obscureText: !_isPasswordVisible, obscureText: !_isPasswordVisible,
controller: passwordController, controller: passwordController,
decoration: InputDecoration( decoration: InputDecoration(
labelText: 'Password',
hintText: 'Masukkan kata sandi Anda', hintText: 'Masukkan kata sandi Anda',
prefixIcon: const Icon(Icons.lock_outline_rounded), prefixIcon: const Icon(Icons.lock_outline_rounded),
border: const OutlineInputBorder(), 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 { 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 '../../models/warehouse_mode.dart';
import '../../services/controllerApi.dart'; import '../../services/controllerApi.dart';
import '../../widget/loading_shimmer_show.dart';
class DetailTransferPetiPage extends StatefulWidget { class DetailTransferPetiPage extends StatefulWidget {
final int transferPetiId; final int transferPetiId;
@ -30,23 +31,39 @@ class _DetailTransferPetiPageState extends State<DetailTransferPetiPage> {
List<PetiAssetModel>? petiData; List<PetiAssetModel>? petiData;
List<CustomerModel>? customerData; List<CustomerModel>? customerData;
List<WarehouseModel>? warehouseData; List<WarehouseModel>? warehouseData;
bool loading = true; bool loading = true;
late Future<void> _dataFuture;
@override @override
void initState() { void initState() {
super.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(); getTransferIdData();
customerListAPI(); customerListAPI();
petiListAPI(); petiListAPI();
warehouseListAPI(); warehouseListAPI();
initializeDateFormatting('id_ID', null); initializeDateFormatting('id_ID', null);
// Mengatur loading ke false setelah tugas selesai // Tandai bahwa proses loading telah selesai
setState(() { if (mounted) {
loading = false; setState(() {
}); loading = false;
});
}
} }
Future customerListAPI() async { Future customerListAPI() async {
@ -217,130 +234,147 @@ class _DetailTransferPetiPageState extends State<DetailTransferPetiPage> {
); );
} }
return Scaffold( return WillPopScope(
backgroundColor: Colors.grey[200], onWillPop: () async {
appBar: AppBar( // Mencegah kembali ke halaman sebelumnya
backgroundColor: Colors.indigo[700], return false;
elevation: 0, },
title: Text( child: Scaffold(
'Detail Transfer Peti', backgroundColor: Colors.grey[200],
style: TextStyle( appBar: AppBar(
color: Colors.white, backgroundColor: Colors.indigo[700],
fontSize: 16, elevation: 0,
title: Text(
'Detail Transfer Peti',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
), ),
), leading: IconButton(
leading: IconButton( icon: Icon(Icons.arrow_back, color: Colors.white),
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
Navigator.pushNamed(context, '/transfer-peti');
},
),
actions: [
IconButton(
icon: Icon(Icons.delete, color: Colors.redAccent),
onPressed: () { onPressed: () {
_showDeleteConfirmationDialog(); // Navigator.pushNamed(context, '/transfer-peti');
Navigator.pop(context);
}, },
), ),
], actions: [
), IconButton(
body: Padding( icon: Icon(Icons.delete, color: Colors.redAccent),
padding: EdgeInsets.all(16.0), onPressed: () {
child: Card( _showDeleteConfirmationDialog();
shape: RoundedRectangleBorder( },
borderRadius: BorderRadius.circular(15.0), ),
), ],
elevation: 5, ),
child: Column( body: FutureBuilder<void>(
children: [ future: _dataFuture,
Card( builder: (context, snapshot) {
shape: RoundedRectangleBorder( if (snapshot.connectionState == ConnectionState.waiting) {
borderRadius: return ShimmerShow();
BorderRadius.vertical(top: Radius.circular(15.0)), } else if (snapshot.hasError) {
), return Text('Error: ${snapshot.error}');
elevation: 0, } else {
margin: EdgeInsets.all(0), return Padding(
color: Colors.indigo[700], padding: EdgeInsets.all(16.0),
child: Padding( child: Card(
padding: const EdgeInsets.all(16.0), shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
elevation: 5,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( Card(
children: [ shape: RoundedRectangleBorder(
Icon(Icons.article, size: 30, color: Colors.white), borderRadius:
SizedBox(width: 10), BorderRadius.vertical(top: Radius.circular(15.0)),
Column( ),
elevation: 0,
margin: EdgeInsets.all(0),
color: Colors.indigo[700],
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Row(
'ID:', children: [
style: TextStyle( Icon(Icons.article,
fontSize: 12, size: 30, color: Colors.white),
fontWeight: FontWeight.bold, SizedBox(width: 10),
color: Colors.white, Column(
), crossAxisAlignment:
), CrossAxisAlignment.start,
SizedBox(height: 5), children: [
Text( SizedBox(height: 5),
petiSqfliteApi != null && Text(
petiSqfliteApi.fix_lot != null petiSqfliteApi != null &&
? petiSqfliteApi!.fix_lot.toString() petiSqfliteApi.fix_lot != null
: '-', ? petiSqfliteApi!.fix_lot.toString()
style: TextStyle( : '-',
fontSize: 12, style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 12,
color: Colors.white, 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