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. 135
      lib/pages/home/home_page.dart
  5. 117
      lib/pages/peminjaman_barang/create-finish.dart
  6. 99
      lib/pages/peminjaman_barang/create.dart
  7. 92
      lib/pages/peminjaman_barang/peminjaman_stock_page.dart
  8. 34
      lib/pages/peminjaman_barang/show.dart
  9. 761
      lib/pages/pengembalian_barang/edit-finish.dart
  10. 1016
      lib/pages/pengembalian_barang/edit.dart
  11. 931
      lib/pages/pengembalian_barang/index.dart
  12. 90
      lib/pages/pengembalian_barang/show.dart
  13. 19
      lib/pages/sign_in_page.dart
  14. 899
      lib/pages/transfer_peti/edit-finish.dart
  15. 1164
      lib/pages/transfer_peti/edit.dart
  16. 938
      lib/pages/transfer_peti/index.dart
  17. 80
      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,
};
}
}

135
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,13 +277,20 @@ 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 {
// Set _isFetchingData back to false when the process finishes
if (mounted) {
setState(() {
_isFetchingData = false;
});
EasyLoading.dismiss();
}
}
}
Future syncToGlobal(String type) async {
try {
@ -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,8 +692,9 @@ class _HomePageState extends State<HomePage> {
Container(
width: double.infinity,
child: TextButton(
onPressed: () {
Navigator.pop(context); // Close dialog
onPressed: _isFetchingData
? null
: () {
fetchDataFromApiAndSync();
},
child: Text(
@ -688,23 +738,29 @@ class _HomePageState extends State<HomePage> {
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildCountTile(
_isLoading
? ShimmerLoadingReinit()
: _buildCountTile(
Icons.vertical_align_top,
_peminjamanCount,
Colors.green[700]!,
'Peminjaman',
'Peti Out',
),
_buildCountTile(
_isLoading
? ShimmerLoadingReinit()
: _buildCountTile(
Icons.vertical_align_bottom,
_pengembalianCount,
Colors.blue[700]!,
'Pengembalian',
'Peti In',
),
_buildCountTile(
_isLoading
? ShimmerLoadingReinit()
: _buildCountTile(
Icons.input_outlined,
_transferCount,
Colors.yellow[700]!,
'Transfer',
'Transfer Peti',
),
],
),
@ -712,7 +768,9 @@ class _HomePageState extends State<HomePage> {
// Re-init Button
ElevatedButton(
onPressed: () {
onPressed: () async {
bool hasInternet = await ControllerApi.isInternetApi();
if (hasInternet) {
showDialog(
context: context,
builder: (BuildContext context) {
@ -731,7 +789,8 @@ class _HomePageState extends State<HomePage> {
width: double.infinity,
color: Colors.indigo[700], // Indigo background
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.all(16.0),
@ -776,11 +835,15 @@ class _HomePageState extends State<HomePage> {
),
// 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],
@ -799,6 +862,9 @@ class _HomePageState extends State<HomePage> {
);
},
);
} else {
EasyLoading.showError("Tidak ada koneksi internet");
}
},
style: ElevatedButton.styleFrom(
primary: Colors.blue[700],
@ -829,30 +895,14 @@ class _HomePageState extends State<HomePage> {
);
}
return Scaffold(
return AbsorbPointer(
absorbing: _isFetchingData,
child: 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: [
@ -917,6 +967,7 @@ class _HomePageState extends State<HomePage> {
),
],
),
),
);
}
}

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

@ -24,16 +24,16 @@ import '../../services/controllerApi.dart';
import 'conn/syncronize.dart';
import 'controller/peminjaman_controller.dart';
class InformasiDataEntryPage extends StatefulWidget {
class CreateFinishPeminjaman extends StatefulWidget {
final List<AssetStatusModel> temporaryDataList;
InformasiDataEntryPage({required this.temporaryDataList});
CreateFinishPeminjaman({required this.temporaryDataList});
@override
_InformasiDataEntryPageState createState() => _InformasiDataEntryPageState();
_CreateFinishPeminjamanState createState() => _CreateFinishPeminjamanState();
}
class _InformasiDataEntryPageState extends State<InformasiDataEntryPage> {
class _CreateFinishPeminjamanState extends State<CreateFinishPeminjaman> {
String? token;
// List<CustomerModel>? customerSqfliteApi;
PetiAssetModel? petiSqfliteApi;
@ -63,6 +63,7 @@ class _InformasiDataEntryPageState extends State<InformasiDataEntryPage> {
List<AssetStatusModel> temporaryDataList = [];
final _formKey = GlobalKey<FormState>();
bool loading = true;
late Future<void> _dataFuture;
// bool _isLoading = false;
@ -256,10 +257,10 @@ class _InformasiDataEntryPageState extends State<InformasiDataEntryPage> {
.map((data) {
PetiAssetModel? peti =
_valpeti?.firstWhereOrNull((peti) => peti.id == data.peti_id);
print("Checking conditions for Peti ID: ${data.peti_id}");
print("Exit_atController: ${_exit_atController.text.isNotEmpty}");
print("petiSqfliteApi: ${peti != null}");
print("warehouseSqfliteApi: ${warehouseSqfliteApi != null}");
// print("Checking conditions for Peti ID: ${data.peti_id}");
// print("Exit_atController: ${_exit_atController.text.isNotEmpty}");
// print("petiSqfliteApi: ${peti != null}");
// print("warehouseSqfliteApi: ${warehouseSqfliteApi != null}");
if (peti != null) {
return peti;
} else {
@ -359,12 +360,17 @@ class _InformasiDataEntryPageState extends State<InformasiDataEntryPage> {
Navigator.pushNamed(context, '/peminjaman-barang');
}
return Scaffold(
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 Peminjaman Peti',
title: Text('Isikan Data Peti Out',
style: TextStyle(
fontSize: 16,
)),
@ -486,7 +492,8 @@ class _InformasiDataEntryPageState extends State<InformasiDataEntryPage> {
),
popupProps: PopupProps.bottomSheet(
showSearchBox: true,
itemBuilder: (context, CustomerModel? customer,
itemBuilder: (context,
CustomerModel? customer,
bool? isSelected) {
if (customer == null) {
return SizedBox.shrink();
@ -518,7 +525,8 @@ class _InformasiDataEntryPageState extends State<InformasiDataEntryPage> {
),
],
),
color: customer.id == customerSqfliteApi?.id
color:
customer.id == customerSqfliteApi?.id
? Colors.grey.withOpacity(0.7)
: Colors.white,
);
@ -661,7 +669,8 @@ class _InformasiDataEntryPageState extends State<InformasiDataEntryPage> {
SizedBox(height: 8),
FormBuilderDateTimePicker(
validator: (value) {
if (_est_pengembalianController.text.isEmpty) {
if (_est_pengembalianController
.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent[700],
@ -672,7 +681,8 @@ class _InformasiDataEntryPageState extends State<InformasiDataEntryPage> {
color: Colors.white,
),
SizedBox(width: 5),
Text('Tanggal Estimasi Pengembalian'),
Text(
'Tanggal Estimasi Pengembalian'),
],
),
duration: Duration(seconds: 2),
@ -696,34 +706,6 @@ class _InformasiDataEntryPageState extends State<InformasiDataEntryPage> {
),
),
SizedBox(height: 16),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Penanggung Jawab:',
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
TextFormField(
controller: _penanggungJawabController =
TextEditingController(text: user.fullname),
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'Penanggung Jawab',
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Harus diisi';
}
return null; // Return null jika tidak ada kesalahan
},
),
],
),
),
SizedBox(height: 16),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -772,11 +754,6 @@ class _InformasiDataEntryPageState extends State<InformasiDataEntryPage> {
style: TextStyle(
fontSize: 16,
fontFamily: 'OpenSansCondensed',
fontWeight:
warehouseSqfliteApi?.id ==
warehouse.id
? FontWeight.bold
: FontWeight.normal,
),
),
],
@ -794,6 +771,34 @@ class _InformasiDataEntryPageState extends State<InformasiDataEntryPage> {
],
),
),
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
},
),
],
),
),
],
),
),
@ -827,6 +832,23 @@ class _InformasiDataEntryPageState extends State<InformasiDataEntryPage> {
if (_exit_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(
@ -859,6 +881,7 @@ class _InformasiDataEntryPageState extends State<InformasiDataEntryPage> {
],
),
),
),
);
}
}

99
lib/pages/peminjaman_barang/create.dart

@ -42,9 +42,9 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
PetiAssetModel? petiSqfliteApi;
WarehouseModel? warehouseSqfliteApi;
List<PetiAssetModel>? _valpeti; // Change this line
List<WarehouseModel>? _valwarehouse;
List<DisposalPetiModel>? _valdisposal;
List<PetiAssetModel> _allPetiList = [];
// List<WarehouseModel>? _valwarehouse;
// List<DisposalPetiModel>? _valdisposal;
// List<PetiAssetModel> _allPetiList = [];
List<PetiAssetModel> _unrestrictedPetiList = [];
List<PetiAssetModel> _filteredPetiList = [];
bool isQRCodeScanned = false;
@ -381,43 +381,6 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
return petiList.map((item) => PetiAssetModel.fromJson(item)).toList();
}
// Future<List<PetiAssetModel>> _petiListAPI() async {
// // Fetch data from the API
// dynamic apiPetiList = await ControllerApi().fetchPetiDataAPI();
// // Ensure apiPetiList is of type List
// List<PetiAssetModel> petiList = [];
// if (apiPetiList is List) {
// petiList =
// apiPetiList.map((item) => PetiAssetModel.fromJson(item)).toList();
// }
// // Fetch data from SharedPreferences
// List<PetiAssetModel> sharedPreferencesPetiList =
// await getSelectedPetiListFromSharedPreferences();
// // Merge the lists, ensuring no duplicates
// List<PetiAssetModel> mergedPetiList = [];
// Set<int> petiIds = Set();
// for (PetiAssetModel peti in petiList) {
// if (!petiIds.contains(peti.id)) {
// mergedPetiList.add(peti);
// petiIds.add(int.parse(peti.id.toString()));
// }
// }
// for (PetiAssetModel peti in sharedPreferencesPetiList) {
// if (!petiIds.contains(peti.id)) {
// mergedPetiList.add(peti);
// petiIds.add(int.parse(peti.id.toString()));
// }
// }
// return mergedPetiList;
// }
@override
Widget build(BuildContext context) {
AuthProvider authProvider =
@ -465,7 +428,7 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => InformasiDataEntryPage(
builder: (context) => CreateFinishPeminjaman(
temporaryDataList: temporaryDataList,
),
),
@ -544,7 +507,9 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
void removePeti(int index) async {
PetiAssetModel? selectedPeti =
selectedPetiList != null ? selectedPetiList![index] : null;
selectedPetiList != null && selectedPetiList!.isNotEmpty
? selectedPetiList![index]
: null;
print(
'Before Remove: ${selectedPeti?.fix_lot}'); // Cetak atribut tertentu sebelum penghapusan
@ -577,13 +542,18 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
? 250.0
: 300.0;
return Scaffold(
return WillPopScope(
onWillPop: () async {
// Mencegah kembali ke halaman sebelumnya
return false;
},
child: Scaffold(
backgroundColor: Colors.grey[100],
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text('Buat Peminjaman Peti',
title: Text('Buat Peti Out',
style: TextStyle(
fontSize: 16,
)),
@ -613,7 +583,7 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
margin:
EdgeInsets.only(left: 8, right: 8, top: 13),
child: Text(
'Add List Peti / Scan Peti:',
'Tambah List Peti / Scan Peti:',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
@ -625,7 +595,8 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
Expanded(
child: Container(
margin: EdgeInsets.only(left: 8),
child: FutureBuilder<List<PetiAssetModel>>(
child:
FutureBuilder<List<PetiAssetModel>>(
future: _petiListAPI(),
builder: (context,
AsyncSnapshot<List<PetiAssetModel>>
@ -633,7 +604,8 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
child:
CircularProgressIndicator(),
);
} else if (snapshot.hasError) {
return Text(
@ -646,11 +618,14 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
.contains(
peti.id) &&
!scannedPetiList
.contains(peti.id);
.contains(
peti.id);
}).toList() ??
[];
return DropdownSearch<PetiAssetModel>(
popupProps: PopupProps.bottomSheet(
return DropdownSearch<
PetiAssetModel>(
popupProps:
PopupProps.bottomSheet(
showSearchBox: true,
itemBuilder: (context,
PetiAssetModel? peti,
@ -668,7 +643,8 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
itemAsString(peti);
// Check if the selected item is already in the list obtained from SharedPreferences
bool isPetiInSharedPreferences =
bool
isPetiInSharedPreferences =
localSelectedPetiList.any(
(selectedPeti) =>
itemAsString(
@ -711,7 +687,8 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
),
leading: Icon(
bulletIcon,
color: bulletColor,
color:
bulletColor,
size: 24,
),
),
@ -789,8 +766,8 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
itemAsString:
(PetiAssetModel item) =>
item.fix_lot ?? '',
onBeforeChange:
(PetiAssetModel? from,
onBeforeChange: (PetiAssetModel?
from,
PetiAssetModel? to) async {
// The logic here should remain the same
bool isPetiInSharedPreferences =
@ -815,10 +792,11 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
return true; // Allow the change
},
onChanged:
(PetiAssetModel? value) async {
onChanged: (PetiAssetModel?
value) async {
if (value != null) {
bool isPetiInSharedPreferences =
bool
isPetiInSharedPreferences =
localSelectedPetiList
.contains(value);
bool isPetiInScannedList =
@ -835,7 +813,8 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
);
} else {
// Move the asynchronous work outside the setState
await checkAndAddPeti(value);
await checkAndAddPeti(
value);
}
}
},
@ -977,7 +956,8 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(5.0),
BorderRadius.circular(
5.0),
border: Border.all(
color: Colors.grey),
),
@ -1104,6 +1084,7 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
],
),
),
),
);
}
}

92
lib/pages/peminjaman_barang/peminjaman_stock_page.dart

@ -497,7 +497,12 @@ class AssetStatusPageState extends State<AssetStatusPage> {
// );
// }
return DefaultTabController(
return WillPopScope(
onWillPop: () async {
// Mencegah kembali ke halaman sebelumnya
return false;
},
child: DefaultTabController(
length: 1,
child: Scaffold(
appBar: appBarPeminjaman(context),
@ -519,6 +524,7 @@ class AssetStatusPageState extends State<AssetStatusPage> {
: 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),
],
),
),

34
lib/pages/peminjaman_barang/show.dart

@ -233,13 +233,18 @@ class _DetailPeminjamanBarangPageState
);
}
return Scaffold(
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 Peminjaman Peti',
'Detail Peti Out',
style: TextStyle(
color: Colors.white,
fontSize: 16,
@ -296,16 +301,9 @@ class _DetailPeminjamanBarangPageState
size: 30, color: Colors.white),
SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
'ID:',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
SizedBox(height: 5),
Text(
petiSqfliteApi != null &&
@ -330,7 +328,8 @@ class _DetailPeminjamanBarangPageState
if (peminjamanInfo != null) ...[
_buildDetailItem(
'Kode Peti',
petiSqfliteApi != null && petiSqfliteApi.fix_lot != null
petiSqfliteApi != null &&
petiSqfliteApi.fix_lot != null
? petiSqfliteApi!.fix_lot.toString()
: '-',
),
@ -352,7 +351,7 @@ class _DetailPeminjamanBarangPageState
peminjamanInfo!.est_pengembalian.toString())),
Divider(thickness: 1),
_buildDetailItem(
'PJ Peminjaman', peminjamanInfo!.exit_pic.toString()),
'PIC/PJ:', peminjamanInfo!.exit_pic.toString()),
Divider(thickness: 1),
_buildDetailItem(
' Gudang',
@ -360,14 +359,6 @@ class _DetailPeminjamanBarangPageState
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
],
@ -378,6 +369,7 @@ class _DetailPeminjamanBarangPageState
}
},
),
),
);
}

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),
),
),
],
),
),
],
),
),
),
);
}
}

1016
lib/pages/pengembalian_barang/edit.dart

File diff suppressed because it is too large Load Diff

931
lib/pages/pengembalian_barang/index.dart

File diff suppressed because it is too large Load Diff

90
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();
// Set loading ke true pada awalnya
if (mounted) {
if (mounted) {
setState(() {
loading = false;
});
}
}
_dataFuture = fetchData();
}
Future<void> fetchData() async {
await getPengembalianIdData();
await customerListAPI();
await petiListAPI();
await warehouseListAPI();
await kondisiPetiListAPI();
initializeDateFormatting('id_ID', null);
// Delay sejenak sebelum memanggil EasyLoading.dismiss()
// Tandai bahwa proses loading telah selesai
if (mounted) {
Future.delayed(Duration(seconds: 1), () {
setState(() {
loading = false; // Mengatur loading ke false setelah tugas selesai
});
EasyLoading.dismiss();
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,13 +251,18 @@ class _DetailPengembalianBarangPageState
);
}
return Scaffold(
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 Pengembalian Peti',
'Detail Peti In',
style: TextStyle(
color: Colors.white,
fontSize: 16,
@ -255,7 +271,7 @@ class _DetailPengembalianBarangPageState
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
Navigator.pushNamed(context, '/pengembalian-barang');
Navigator.pop(context);
},
),
actions: [
@ -267,7 +283,15 @@ class _DetailPengembalianBarangPageState
),
],
),
body: Padding(
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(
@ -291,19 +315,13 @@ class _DetailPengembalianBarangPageState
children: [
Row(
children: [
Icon(Icons.article, size: 30, color: Colors.white),
Icon(Icons.article,
size: 30, color: Colors.white),
SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
'ID:',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
SizedBox(height: 5),
Text(
petiSqfliteApi != null &&
@ -328,7 +346,8 @@ class _DetailPengembalianBarangPageState
if (pengembalianInfo != null) ...[
_buildDetailItem(
'Kode Peti',
petiSqfliteApi != null && petiSqfliteApi.fix_lot != null
petiSqfliteApi != null &&
petiSqfliteApi.fix_lot != null
? petiSqfliteApi!.fix_lot.toString()
: '-',
),
@ -338,7 +357,7 @@ class _DetailPengembalianBarangPageState
_formatDate(pengembalianInfo!.enter_at.toString())),
Divider(thickness: 1),
_buildDetailItem(
'PJ Pengembalian', pengembalianInfo!.enter_pic.toString()),
'PIC/PJ:', pengembalianInfo!.enter_pic.toString()),
Divider(thickness: 1),
_buildDetailItem(
'Gudang',
@ -348,24 +367,23 @@ class _DetailPengembalianBarangPageState
: '-'),
Divider(thickness: 1),
_buildDetailItem(
'Kondisi Peti',
'Kondisi Barang',
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
],
],
),
),
);
}
},
),
),
);
}

19
lib/pages/sign_in_page.dart

@ -168,11 +168,11 @@ 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) {
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');
@ -182,6 +182,9 @@ class __FormContentState extends State<_FormContent> {
} else {
print('Tidak ada informasi peran (roles) yang tersedia');
}
} else {
print('User tidak valid');
}
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
@ -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),
),
),
],
),
),
],
),
),
),
);
}
}

1164
lib/pages/transfer_peti/edit.dart

File diff suppressed because it is too large Load Diff

938
lib/pages/transfer_peti/index.dart

File diff suppressed because it is too large Load Diff

80
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,24 +31,40 @@ 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
// Tandai bahwa proses loading telah selesai
if (mounted) {
setState(() {
loading = false;
});
}
}
Future customerListAPI() async {
if (mounted) {
@ -217,7 +234,12 @@ class _DetailTransferPetiPageState extends State<DetailTransferPetiPage> {
);
}
return Scaffold(
return WillPopScope(
onWillPop: () async {
// Mencegah kembali ke halaman sebelumnya
return false;
},
child: Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
backgroundColor: Colors.indigo[700],
@ -232,7 +254,8 @@ class _DetailTransferPetiPageState extends State<DetailTransferPetiPage> {
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
Navigator.pushNamed(context, '/transfer-peti');
// Navigator.pushNamed(context, '/transfer-peti');
Navigator.pop(context);
},
),
actions: [
@ -244,7 +267,15 @@ class _DetailTransferPetiPageState extends State<DetailTransferPetiPage> {
),
],
),
body: Padding(
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(
@ -268,19 +299,13 @@ class _DetailTransferPetiPageState extends State<DetailTransferPetiPage> {
children: [
Row(
children: [
Icon(Icons.article, size: 30, color: Colors.white),
Icon(Icons.article,
size: 30, color: Colors.white),
SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
'ID:',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
SizedBox(height: 5),
Text(
petiSqfliteApi != null &&
@ -305,25 +330,29 @@ class _DetailTransferPetiPageState extends State<DetailTransferPetiPage> {
if (transferInfo != null) ...[
_buildDetailItem(
'Kode Peti',
petiSqfliteApi != null && petiSqfliteApi.fix_lot != null
petiSqfliteApi != null &&
petiSqfliteApi.fix_lot != null
? petiSqfliteApi!.fix_lot.toString()
: '-',
),
Divider(thickness: 1),
_buildDetailItem(
'Nama Customer',
customerSqfliteApi != null && customerSqfliteApi.name != null
customerSqfliteApi != null &&
customerSqfliteApi.name != null
? customerSqfliteApi!.name.toString()
: '-',
),
: '-'),
Divider(thickness: 1),
_buildDetailItem(
'Tgl Transfer', _formatDate(transferInfo!.date.toString())),
'PIC/PJ:', transferInfo!.created_by.toString()),
Divider(thickness: 1),
_buildDetailItem('Tanggal Transfer Peti:',
_formatDate(transferInfo!.created_at.toString())),
Divider(thickness: 1),
_buildDetailItem(
'Asal Gudang',
// peminjamanInfo!.exit_warehouse.toString()),
warehouseSqfliteApi != null &&
warehouseSqfliteApi.name != null
? warehouseSqfliteApi!.name.toString()
@ -331,17 +360,22 @@ class _DetailTransferPetiPageState extends State<DetailTransferPetiPage> {
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