import 'dart:convert'; import 'dart:core'; import 'package:flutter/material.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:siopas/models/asset_status_model.dart'; import 'package:siopas/models/condition_peti_model.dart'; import 'package:siopas/models/customer_model.dart'; import 'package:siopas/models/type_peti_model.dart'; import 'package:siopas/pages/peminjaman_barang/conn/syncronize.dart'; import 'package:siopas/pages/pengembalian_barang/conn/syncronize.dart'; import 'package:siopas/pages/pengembalian_barang/controller/pengembalian_controller.dart'; import 'package:siopas/services/controllerApi.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:qr_code_scanner/qr_code_scanner.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:siopas/models/m_asset_status_model.dart'; import 'package:siopas/models/warehouse_mode.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:intl/date_symbol_data_local.dart'; // Import package intl import 'package:uuid/uuid.dart'; import 'package:dropdown_search/dropdown_search.dart'; import '../../connection/connection.dart'; import 'package:http/http.dart' as http; import '../../models/user_model.dart'; import '../../providers/auth_provider.dart'; import '../peminjaman_barang/controller/peminjaman_controller.dart'; import 'package:collection/collection.dart'; // import 'conn/syncronizeAPI.dart'; // import 'controller/peminjaman_controller.dart'; class CreatePengembalianBarangPage extends StatefulWidget { const CreatePengembalianBarangPage({Key? key}) : super(key: key); @override State createState() => _CreatePengembalianBarangPageState(); } class _CreatePengembalianBarangPageState extends State { List? _data; String? token; List? typePetiSqfliteApi; // List? customerSqfliteApi; PetiAssetModel? petiSqfliteApi; ConditionPetiModel? conditionPetiSqfliteApi; WarehouseModel? warehouseSqfliteApi; List? _valpeti; // Change this line List? _valwarehouse; List? _valconditionPeti; CustomerModel? customerSqfliteApi; List? _valcustomer; List _unrestrictedPetiList = []; List _filteredPetiList = []; bool isQRCodeScanned = false; TextEditingController searchBoxController = TextEditingController(); TextEditingController _enterAtController = TextEditingController(); // TextEditingController _enterPicController = TextEditingController(); // TextEditingController _kondisiPetiController = TextEditingController(); // TextEditingController _penanggungJawabController = TextEditingController(); final _formKey = GlobalKey(); final GlobalKey qrKey = GlobalKey(debugLabel: 'QR'); Barcode? result; QRViewController? controller; bool loading = true; @override void initState() { super.initState(); _getUserToken(); warehouseListAPI(); datatablesAssetStatusList(); // typePetiListAPI(); // customerListAPI(); petiListAPI(); kondisiPetiListAPI(); initializeDateFormatting('id_ID', null); setState(() { loading = false; // Mengatur loading ke false setelah tugas selesai }); } void _getUserToken() async { SharedPreferences prefs = await SharedPreferences.getInstance(); if (mounted) { setState(() { token = prefs.getString('token'); loading = false; }); } } Future warehouseListAPI() async { if (mounted) { await ControllerApi().fetchWarehouseDataAPI().then((value) { setState(() { _valwarehouse = (value as List) .map((item) => WarehouseModel.fromJson(item)) .toList(); loading = false; }); }); } } Future datatablesAssetStatusList() async { await Controller().fetchAssetStatusLocalController().then((value) { setState(() { _data = (value as List) .map((e) => AssetStatusModel.fromJson(e)) .toList(); loading = false; }); }); } Future petiListAPI() async { if (mounted) { await ControllerApi().fetchPetiDataAPI().then((value) { setState(() { _valpeti = (value as List) .map((item) => PetiAssetModel.fromJson(item)) .toList(); loading = false; }); }); } } Future kondisiPetiListAPI() async { if (mounted) { await ControllerApi().fetchKondisiPetiDataAPI().then((value) { setState(() { _valconditionPeti = (value as List) .map((item) => ConditionPetiModel.fromJson(item)) .toList(); loading = false; }); }); } } Future isInteret() async { await SyncronizationPengembalianData.isInternet().then((connection) { if (connection) { print("Internet connection available"); } else { ScaffoldMessenger.of(context) .showSnackBar(SnackBar(content: Text("No Internet"))); } }); } Future _onQRViewCreated(QRViewController controller) async { this.controller = controller; bool scanned = false; // code to auto focus kamera belakang controller.flipCamera(); await Future.delayed(const Duration(milliseconds: 400)); controller.flipCamera(); controller.scannedDataStream.listen( (scanData) { if (!scanned) { try { setState(() { result = scanData; List lines = result!.code!.split('\n'); String idPeti = ''; String idWarehouse = ''; for (String line in lines) { if (line.contains(';')) { List values = line.split(';'); if (values.length >= 3) { idPeti = values[1]; idWarehouse = values[2]; break; } } } int? petiId = int.tryParse(idPeti); int? warehouseId = int.tryParse(idWarehouse); // AuthProvider authProvider = Provider.of(context, listen: false); // UserModel user = authProvider.user; // Dalam fungsi yang menangani pemindaian QR code // Dalam fungsi yang menangani pemindaian QR code if (petiId != null && warehouseId != null) { // Check apakah peti dengan warehouse_id yang sesuai ada dalam daftar yang diizinkan PetiAssetModel? allowedPeti = _valpeti?.firstWhereOrNull( (peti) => peti.id == petiId && peti.deleted_at != true && peti.status == 'AKTIF', ); if (allowedPeti != null) { setState(() { isQRCodeScanned = true; // Mengisi _filteredPetiList untuk dropdown hasil QR Code _filteredPetiList = [ _valpeti!.firstWhere((peti) => peti.id == allowedPeti.id) ]; petiSqfliteApi = allowedPeti; }); } else { // Tampilkan pesan error jika data tidak sesuai dengan hak akses ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( 'Data Peti tidak ditemukan atau tidak sesuai dengan hak akses.', style: TextStyle( color: Colors.white, fontSize: 12, ), ), backgroundColor: Colors.red[700], action: SnackBarAction( label: 'Tutup', onPressed: () { ScaffoldMessenger.of(context).hideCurrentSnackBar(); }, ), ), ); setState(() { isQRCodeScanned = false; petiSqfliteApi = null; warehouseSqfliteApi = null; }); } } else { // Tampilkan pesan error jika nilai yang dipindai tidak sesuai ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Row( children: [ Icon( Icons.warning, color: Colors.black, ), SizedBox(width: 8), Text( 'Nilai QR Code tidak sesuai dengan yang diharapkan.', style: TextStyle( color: Colors.black, fontSize: 12, ), ), ], ), backgroundColor: Colors.yellow[700], ), ); setState(() { isQRCodeScanned = false; petiSqfliteApi = null; warehouseSqfliteApi = null; }); } scanned = true; }); controller.stopCamera(); Future.delayed(Duration(milliseconds: 500), () { if (mounted) { Navigator.of(context).pop(); } }); } catch (e) { controller.stopCamera(); // Reset nilai dropdown Peti dan Warehouse setState(() { petiSqfliteApi = null; warehouseSqfliteApi = null; }); print('Error scanning QR Code: $e'); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Row( children: [ Icon( Icons.error, color: Colors.red[400], ), SizedBox(width: 8), Flexible( child: Text( e.toString(), style: TextStyle( color: Colors.white, fontSize: 12, ), ), ), ], ), backgroundColor: Colors.red[700], ), ); } } }, ); } @override Widget build(BuildContext context) { AuthProvider authProvider = Provider.of(context, listen: false); UserModel user = authProvider.user; // 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 saveAssetData() async { DateTime now = DateTime.now().toLocal(); String formattedDate = DateFormat('yyyy-MM-dd HH:mm:ss.SSS').format(now); if (_enterAtController.text.isNotEmpty) { AssetStatusModel pengembalianAddModel = AssetStatusModel( id: null, peti_id: petiSqfliteApi!.id, enter_at: parseDateTime(_enterAtController.text), enter_pic: user.fullname, enter_warehouse: warehouseSqfliteApi!.id, kondisi_peti_id: conditionPetiSqfliteApi!.id, updated_by: user.fullname, updated_at: parseDateTime(formattedDate), ); // Call addData function int result = await ControllerPengembalian() .addPengembalianData(pengembalianAddModel); if (result > 0) { print("Success Tambah data"); // print(result); Navigator.pushNamed(context, '/pengembalian-barang'); EasyLoading.showSuccess("Data Berhasil Disimpan"); } else { print("Failed"); } } } var scanArea = (MediaQuery.of(context).size.width < 400 || MediaQuery.of(context).size.height < 400) ? 250.0 : 300.0; return Scaffold( appBar: AppBar( automaticallyImplyLeading: false, backgroundColor: Colors.indigo[700], elevation: 0, title: Text('Buat Pengembalian Peti', style: TextStyle( fontSize: 16, )), ), body: loading ? Center(child: CircularProgressIndicator()) : SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(8.0), child: Form( key: _formKey, child: Column( children: [ Row( children: [ Expanded( child: Card( elevation: 2, child: Container( margin: EdgeInsets.all(8), child: DropdownSearch( popupProps: PopupProps.bottomSheet( showSearchBox: true, itemBuilder: (context, PetiAssetModel? peti, bool? isSelected) { if (peti == null) { return SizedBox.shrink(); } // Tentukan warna dan ikon berdasarkan kondisi status Color bulletColor = peti.status == 'AKTIF' ? Colors.green : Colors.red; IconData bulletIcon = peti.status == 'AKTIF' ? Icons.circle : Icons.circle; return Container( child: Column( children: [ ListTile( title: Text( peti.fix_lot.toString(), style: TextStyle( fontSize: 16, fontFamily: 'OpenSansCondensed', ), ), leading: Icon( bulletIcon, color: bulletColor, size: 24, ), ), Divider( height: 1, color: Colors .grey, // Warna pembatas (divider) ), ], ), color: peti.id == petiSqfliteApi?.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 Peti', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold), ), IconButton( icon: Icon( Icons.close, color: Colors.red, ), onPressed: () { Navigator.pop(context); }, ), ], ), Divider(), ], ), ), ), dropdownDecoratorProps: DropDownDecoratorProps( dropdownSearchDecoration: InputDecoration( labelText: 'Pilih Peti', border: OutlineInputBorder( borderRadius: BorderRadius.all( Radius.circular(5.0), ), ), ), ), items: (isQRCodeScanned ? _filteredPetiList : (_valpeti ?? []).where((peti) => peti.deleted_at != true && (peti.warehouse_id == user.warehouse_id) && (peti.status == 'AKTIF'))) .where((peti) => peti.fix_lot! .toLowerCase() .contains(searchBoxController.text .toLowerCase())) .toList() ?? [], // searchBoxController: searchBoxController, itemAsString: (PetiAssetModel item) => item.fix_lot ?? "", // Ganti dengan properti yang sesuai selectedItem: petiSqfliteApi, onChanged: (PetiAssetModel? value) { setState(() { petiSqfliteApi = value; if (value != null) { // Perbarui _unrestrictedPetiList sesuai pemilihan manual _unrestrictedPetiList = [ _valpeti!.firstWhere( (peti) => peti.id == value.id) ]; } }); }, validator: (PetiAssetModel? value) { if (value == null) { return 'Harus diisi'; } return null; }, ), ), ), ), SizedBox(width: 8), // Spacer antara dua card Card( elevation: 2, child: Container( margin: EdgeInsets.all(8), height: MediaQuery.of(context).size.height / 10, decoration: BoxDecoration( color: Colors.indigoAccent, borderRadius: BorderRadius.circular(5), ), child: IconButton( onPressed: () { showModalBottomSheet( context: context, isScrollControlled: true, // Set modal menjadi fullscreen builder: (BuildContext context) { return Stack( alignment: Alignment.center, children: [ Container( height: double.infinity, width: double.infinity, child: QRView( key: qrKey, onQRViewCreated: _onQRViewCreated, overlay: QrScannerOverlayShape( borderColor: Colors.red, borderRadius: 10, borderLength: 30, borderWidth: 10, cutOutSize: scanArea, ), ), ), Positioned( bottom: 30, height: 60, child: Container( height: 60, // Lebar dan tinggi sesuai kebutuhan width: 60, decoration: BoxDecoration( shape: BoxShape.circle, color: Colors .red, // Warna merah untuk close ), child: IconButton( onPressed: () { Navigator.of(context).pop(); }, icon: Icon( Icons.close, size: 40, ), color: Colors.white, ), ), ), ], ); }, ); }, icon: Icon( Icons.qr_code, size: 30, ), color: Colors.white, // Warna ikon ), ), ), ], ), SizedBox(height: 16), Card( elevation: 2, child: Padding( padding: const EdgeInsets.all(8), child: FormBuilderDateTimePicker( validator: (value) { if (_enterAtController.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: _enterAtController, name: 'tanggal', inputType: InputType.date, // format: DateFormat('yyyy-MM-dd HH:mm:ss.SSS'), format: DateFormat('yyyy-MM-dd', 'id_ID'), // format: DateFormat('yyyy-MM-dd'), decoration: InputDecoration( labelText: 'Tanggal Pengembalian', border: OutlineInputBorder(), suffixIcon: Icon(Icons.calendar_today), ), ), ), ), SizedBox(height: 13), Card( child: Padding( padding: const EdgeInsets.all(8.0), child: DropdownButtonFormField( validator: (value) { if (value == null) { return 'Harus diisi'; } return null; }, decoration: InputDecoration( labelText: 'Gudang Pengembalian', border: OutlineInputBorder(), ), hint: Text("Gudang Pengembalian"), value: warehouseSqfliteApi, items: (_valwarehouse ?? []) .where((warehouse) => warehouse.deleted_at != true) .map((WarehouseModel warehouse) // _valwarehouse?.map((WarehouseModel warehouse) { return DropdownMenuItem( child: Row( children: [ Icon( Icons.edit_location_alt, color: warehouse.id == warehouseSqfliteApi?.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: (WarehouseModel? value) { setState(() { warehouseSqfliteApi = value; }); }, ), ), ), SizedBox(height: 13), Card( child: Padding( padding: const EdgeInsets.all(8.0), child: DropdownButtonFormField( validator: (value) { if (value == null) { return 'Harus diisi'; } return null; }, decoration: InputDecoration( labelText: 'Pilih Kondisi Peti', border: OutlineInputBorder(), ), hint: Text("Pilih Kondisi Peti"), value: conditionPetiSqfliteApi, items: (_valconditionPeti ?? []) .where( (kondisi) => kondisi.deleted_at != true) .map((ConditionPetiModel kondisi) { return DropdownMenuItem( child: Row( children: [ Icon( kondisi.id == conditionPetiSqfliteApi?.id ? Icons.check_box : Icons.check_box_outline_blank, color: kondisi.id == conditionPetiSqfliteApi?.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) { setState(() { conditionPetiSqfliteApi = value; }); }, ), ), ), // SizedBox(height: 16.0), // Card( // elevation: 2, // child: Padding( // padding: const EdgeInsets.all(8), // child: TextFormField( // controller: _kondisiPetiController, // decoration: InputDecoration( // labelText: 'Kondisi Barang', // border: OutlineInputBorder(), // ), // 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 / 8, color: Color.fromARGB(255, 5, 28, 158), // Warna latar belakang child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, 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.red, // Warna merah untuk close ), child: IconButton( onPressed: () { // Navigator.pop(context); Navigator.pushNamed(context, '/pengembalian-barang'); }, icon: Icon(Icons.close, color: Colors.white), ), ), ], ), ), 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 (_enterAtController.text.isNotEmpty && petiSqfliteApi != null && warehouseSqfliteApi != null) { await saveAssetData(); } } catch (e) { print('Error storing data: $e'); } } }, icon: Icon(Icons.save, color: Colors.white), ), ), ], ), ), ], ), ), ); } }