|
|
|
import 'dart:convert';
|
|
|
|
import 'dart:core';
|
|
|
|
|
|
|
|
import 'package:flutter/material.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 '../../connection/connection.dart';
|
|
|
|
import 'package:http/http.dart' as http;
|
|
|
|
|
|
|
|
import '../../models/user_model.dart';
|
|
|
|
import '../../providers/auth_provider.dart';
|
|
|
|
|
|
|
|
class CreatePeminjamanBarang extends StatefulWidget {
|
|
|
|
const CreatePeminjamanBarang({Key? key}) : super(key: key);
|
|
|
|
|
|
|
|
@override
|
|
|
|
State<CreatePeminjamanBarang> createState() => _CreatePeminjamanBarangState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
|
|
|
|
List<PetiAssetModel> _dataAsset = [];
|
|
|
|
List<WarehouseModel> _dataWarehouse = [];
|
|
|
|
bool _isLoading = false;
|
|
|
|
String? token;
|
|
|
|
PetiAssetModel? _valAsset;
|
|
|
|
WarehouseModel? _valWarehouse;
|
|
|
|
TextEditingController _exit_atController = TextEditingController();
|
|
|
|
TextEditingController _est_pengembalianController = TextEditingController();
|
|
|
|
TextEditingController _penanggungJawabController = TextEditingController();
|
|
|
|
final _formKey = GlobalKey<FormState>();
|
|
|
|
|
|
|
|
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
|
|
|
|
Barcode? result;
|
|
|
|
QRViewController? controller;
|
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
super.initState();
|
|
|
|
_getUserToken();
|
|
|
|
fetchDataWarehouse();
|
|
|
|
fetchDataAsset();
|
|
|
|
initializeDateFormatting('id_ID');
|
|
|
|
}
|
|
|
|
|
|
|
|
void _getUserToken() async {
|
|
|
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
|
|
if (mounted) {
|
|
|
|
setState(() {
|
|
|
|
token = prefs.getString('token');
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> fetchDataAsset() async {
|
|
|
|
setState(() {
|
|
|
|
_isLoading = true;
|
|
|
|
});
|
|
|
|
|
|
|
|
final response = await http.get(Uri.parse('$baseUrl/peti-asset'));
|
|
|
|
|
|
|
|
if (mounted) {
|
|
|
|
// Periksa apakah widget masih "mounted"
|
|
|
|
if (response.statusCode == 200) {
|
|
|
|
final jsonData = json.decode(response.body)['data']['petis'];
|
|
|
|
|
|
|
|
final List<PetiAssetModel> newDataAsset = (jsonData as List)
|
|
|
|
.map((item) => PetiAssetModel.fromJson(item))
|
|
|
|
.toList();
|
|
|
|
|
|
|
|
if (mounted) {
|
|
|
|
// Periksa lagi sebelum memanggil setState
|
|
|
|
setState(() {
|
|
|
|
_dataAsset.addAll(newDataAsset);
|
|
|
|
_isLoading = false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (mounted) {
|
|
|
|
setState(() {
|
|
|
|
_isLoading = false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
throw Exception('Failed to fetch data Asset Status');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> fetchDataWarehouse() async {
|
|
|
|
setState(() {
|
|
|
|
_isLoading = true;
|
|
|
|
});
|
|
|
|
|
|
|
|
final response = await http.get(Uri.parse('$baseUrl/m-warehouse'));
|
|
|
|
|
|
|
|
if (mounted) {
|
|
|
|
if (response.statusCode == 200) {
|
|
|
|
final jsonData = json.decode(response.body)['data']['warehouse'];
|
|
|
|
|
|
|
|
final List<WarehouseModel> newDataWarehouse = (jsonData as List)
|
|
|
|
.map((item) => WarehouseModel.fromJson(item))
|
|
|
|
.toList();
|
|
|
|
|
|
|
|
if (mounted) {
|
|
|
|
setState(() {
|
|
|
|
_dataWarehouse.addAll(newDataWarehouse);
|
|
|
|
_isLoading = false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (mounted) {
|
|
|
|
setState(() {
|
|
|
|
_isLoading = false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
throw Exception('Failed to fetch data Warehouse');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> _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<String> lines = result!.code!.split('\n');
|
|
|
|
|
|
|
|
String idPeti = '';
|
|
|
|
String idWarehouse = '';
|
|
|
|
|
|
|
|
for (String line in lines) {
|
|
|
|
if (line.contains(';')) {
|
|
|
|
List<String> values = line.split(';');
|
|
|
|
if (values.length >= 3) {
|
|
|
|
idPeti = values[1];
|
|
|
|
idWarehouse = values[2];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int? petiId = int.tryParse(idPeti);
|
|
|
|
int? warehouseId = int.tryParse(idWarehouse);
|
|
|
|
|
|
|
|
if (petiId != null && warehouseId != null) {
|
|
|
|
_valAsset = _dataAsset.firstWhere(
|
|
|
|
(peti) => peti.id == petiId,
|
|
|
|
orElse: () => _valAsset!,
|
|
|
|
);
|
|
|
|
|
|
|
|
_valWarehouse = _dataWarehouse.firstWhere(
|
|
|
|
(warehouse) => warehouse.id == warehouseId,
|
|
|
|
orElse: () => _valWarehouse!,
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
// Jika nilai yang dipindai tidak sesuai, tampilkan pesan kesalahan
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
|
|
SnackBar(
|
|
|
|
content: Row(
|
|
|
|
children: [
|
|
|
|
Icon(
|
|
|
|
Icons.warning,
|
|
|
|
color: Colors.black, // Warna ikon
|
|
|
|
),
|
|
|
|
SizedBox(width: 8), // Jarak antara ikon dan teks
|
|
|
|
Text(
|
|
|
|
'Nilai QR Code tidak sesuai dengan yang diharapkan.',
|
|
|
|
style: TextStyle(
|
|
|
|
color: Colors.black,
|
|
|
|
fontSize: 12,
|
|
|
|
), // Warna teks
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
backgroundColor:
|
|
|
|
Colors.yellow[700], // Warna latar belakang SnackBar
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
scanned = true;
|
|
|
|
});
|
|
|
|
|
|
|
|
controller.stopCamera();
|
|
|
|
|
|
|
|
Future.delayed(Duration(milliseconds: 500), () {
|
|
|
|
if (mounted) {
|
|
|
|
Navigator.of(context).pop();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} catch (e) {
|
|
|
|
print('Error scanning QR Code: $e');
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
|
|
SnackBar(
|
|
|
|
content: Text('Error scanning QR Code: $e'),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// void _onQRViewCreated(QRViewController controller) {
|
|
|
|
// this.controller = controller;
|
|
|
|
// bool scanned = false;
|
|
|
|
|
|
|
|
// controller.scannedDataStream.listen((scanData) {
|
|
|
|
// if (!scanned) {
|
|
|
|
// try {
|
|
|
|
// setState(() {
|
|
|
|
// result = scanData;
|
|
|
|
|
|
|
|
// List<String> lines = result!.code!.split('\n');
|
|
|
|
|
|
|
|
// for (String line in lines) {
|
|
|
|
// if (line.startsWith('ID Peti')) {
|
|
|
|
// String idPeti = line.split(': ')[1];
|
|
|
|
// // Isi formulir dropdown asset
|
|
|
|
// _valAsset = _dataAsset
|
|
|
|
// .firstWhere((peti) => peti.id == int.parse(idPeti));
|
|
|
|
// } else if (line.startsWith('Date:')) {
|
|
|
|
// String datePeminjaman = line.split(': ')[1];
|
|
|
|
// try {
|
|
|
|
// DateTime parsedDate =
|
|
|
|
// DateFormat('dd-MM-yyyy').parse(datePeminjaman);
|
|
|
|
// String formattedDate =
|
|
|
|
// DateFormat('yyyy-MM-dd HH:mm:ss.SSS').format(parsedDate);
|
|
|
|
// _exit_atController.text = formattedDate;
|
|
|
|
// } catch (e) {
|
|
|
|
// print('Error parsing date: $e');
|
|
|
|
// // Lakukan penanganan jika format tanggal tidak sesuai
|
|
|
|
// }
|
|
|
|
// } else if (line.startsWith('ID Warehouse')) {
|
|
|
|
// String idWarehouse = line.split(': ')[1];
|
|
|
|
// // Isi formulir dropdown gudang
|
|
|
|
// _valWarehouse = _dataWarehouse.firstWhere(
|
|
|
|
// (warehouse) => warehouse.id == int.parse(idWarehouse));
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
// scanned = true;
|
|
|
|
// });
|
|
|
|
|
|
|
|
// controller.stopCamera();
|
|
|
|
|
|
|
|
// Future.delayed(Duration(milliseconds: 500), () {
|
|
|
|
// if (mounted) {
|
|
|
|
// Navigator.of(context).pop();
|
|
|
|
// }
|
|
|
|
// });
|
|
|
|
// } catch (e) {
|
|
|
|
// print('Error scanning QR Code: $e');
|
|
|
|
// ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
|
|
|
// content: Text('Error scanning QR Code: $e'),
|
|
|
|
// ));
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// });
|
|
|
|
// }
|
|
|
|
|
|
|
|
@override
|
|
|
|
void dispose() {
|
|
|
|
super.dispose();
|
|
|
|
controller?.dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
AuthProvider authProvider =
|
|
|
|
Provider.of<AuthProvider>(context, listen: false);
|
|
|
|
UserModel user = authProvider.user;
|
|
|
|
var scanArea = (MediaQuery.of(context).size.width < 400 ||
|
|
|
|
MediaQuery.of(context).size.height < 400)
|
|
|
|
? 150.0
|
|
|
|
: 300.0;
|
|
|
|
|
|
|
|
// var now = DateTime.now();
|
|
|
|
// var dt = DateTime(DateTime.now().year, DateTime.now().month,
|
|
|
|
// DateTime.now().day, DateTime.now().hour, DateTime.now().minute);
|
|
|
|
|
|
|
|
// // _exit_atController.text = DateFormat('yyyy-MM-dd HH:mm:ss').format(dt);
|
|
|
|
// _exit_atController.text = DateFormat('dd-MM-yyyy').format(dt);
|
|
|
|
|
|
|
|
Future<void> _storePeminjaman() async {
|
|
|
|
setState(() {
|
|
|
|
_isLoading = true;
|
|
|
|
});
|
|
|
|
|
|
|
|
try {
|
|
|
|
final response = await http.post(
|
|
|
|
Uri.parse('$baseUrl/asset-status/store'),
|
|
|
|
headers: {
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
'Authorization': token!,
|
|
|
|
},
|
|
|
|
body: jsonEncode({
|
|
|
|
'peti_id': _valAsset!.id,
|
|
|
|
'exit_at': _exit_atController.text,
|
|
|
|
'exit_pic': _penanggungJawabController.text,
|
|
|
|
'exit_warehouse': _valWarehouse!.id,
|
|
|
|
'est_pengembalian': _est_pengembalianController.text,
|
|
|
|
'created_by': user.fullname,
|
|
|
|
// 'updated_by': user.fullname,
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
|
|
|
|
if (response.statusCode == 200) {
|
|
|
|
final jsonData = json.decode(response.body)['data']['peminjam'];
|
|
|
|
|
|
|
|
print('Berhasil menyimpan data: $jsonData');
|
|
|
|
|
|
|
|
// Tampilkan snackbar
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
|
|
SnackBar(
|
|
|
|
backgroundColor: Colors.greenAccent[700],
|
|
|
|
content: Row(
|
|
|
|
children: [
|
|
|
|
Icon(
|
|
|
|
Icons.check_circle_outline,
|
|
|
|
color: Colors.white,
|
|
|
|
),
|
|
|
|
SizedBox(width: 5),
|
|
|
|
Text('Data berhasil disimpan'),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
duration: Duration(seconds: 3), // Durasi tampilan snackbar
|
|
|
|
),
|
|
|
|
);
|
|
|
|
|
|
|
|
// Reset form input
|
|
|
|
_exit_atController.text = '';
|
|
|
|
_valAsset = null;
|
|
|
|
_valWarehouse = null;
|
|
|
|
result = null;
|
|
|
|
} else {
|
|
|
|
// Reset form input
|
|
|
|
_exit_atController.text = '';
|
|
|
|
_valAsset = null;
|
|
|
|
_valWarehouse = null;
|
|
|
|
result = null;
|
|
|
|
throw Exception('Gagal menyimpan data Asset Status');
|
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
print('Error storing data: $e');
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
|
|
SnackBar(
|
|
|
|
backgroundColor: Colors.redAccent[700],
|
|
|
|
content: Row(
|
|
|
|
children: [
|
|
|
|
Icon(
|
|
|
|
Icons.error_outline,
|
|
|
|
color: Colors.white,
|
|
|
|
),
|
|
|
|
SizedBox(width: 5),
|
|
|
|
Text('Gagal menyimpan data'),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
duration: Duration(seconds: 2), // Durasi tampilan snackbar
|
|
|
|
),
|
|
|
|
);
|
|
|
|
} finally {
|
|
|
|
if (mounted) {
|
|
|
|
setState(() {
|
|
|
|
_isLoading = false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Scaffold(
|
|
|
|
appBar: AppBar(
|
|
|
|
automaticallyImplyLeading: false,
|
|
|
|
backgroundColor: Colors.indigo[700],
|
|
|
|
elevation: 0,
|
|
|
|
title: Text('Buat Peminjaman Barang',
|
|
|
|
style: TextStyle(
|
|
|
|
fontSize: 16,
|
|
|
|
)),
|
|
|
|
leading: IconButton(
|
|
|
|
icon: Icon(Icons.arrow_back),
|
|
|
|
onPressed: () {
|
|
|
|
Navigator.pushNamed(context, '/peminjaman-barang');
|
|
|
|
},
|
|
|
|
),
|
|
|
|
),
|
|
|
|
body: _isLoading
|
|
|
|
? const Center(child: CircularProgressIndicator())
|
|
|
|
: SingleChildScrollView(
|
|
|
|
child: Padding(
|
|
|
|
padding: const EdgeInsets.all(16),
|
|
|
|
child: Form(
|
|
|
|
key: _formKey,
|
|
|
|
child: Column(
|
|
|
|
children: [
|
|
|
|
Row(
|
|
|
|
children: [
|
|
|
|
Expanded(
|
|
|
|
child: Card(
|
|
|
|
elevation: 2,
|
|
|
|
child: Container(
|
|
|
|
margin: EdgeInsets.all(8),
|
|
|
|
child: DropdownButtonFormField<PetiAssetModel>(
|
|
|
|
validator: (value) {
|
|
|
|
if (value == null) {
|
|
|
|
return 'Harus diisi';
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
},
|
|
|
|
decoration: InputDecoration(
|
|
|
|
labelText: 'Peti',
|
|
|
|
border: OutlineInputBorder(),
|
|
|
|
),
|
|
|
|
hint: Text("Pilih Peti"),
|
|
|
|
value: _valAsset,
|
|
|
|
items: _dataAsset.map((PetiAssetModel item) {
|
|
|
|
return DropdownMenuItem<PetiAssetModel>(
|
|
|
|
child: Text('${item.fix_lot}'),
|
|
|
|
value: item,
|
|
|
|
);
|
|
|
|
}).toList(),
|
|
|
|
onChanged: (PetiAssetModel? value) {
|
|
|
|
setState(() {
|
|
|
|
_valAsset = value;
|
|
|
|
if (value != null) {
|
|
|
|
// Set _valWarehouse berdasarkan warehouse_id dari PetiAssetModel
|
|
|
|
_valWarehouse =
|
|
|
|
_dataWarehouse.firstWhere(
|
|
|
|
(warehouse) =>
|
|
|
|
warehouse.id ==
|
|
|
|
int.parse(value.warehouse_id
|
|
|
|
.toString()),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
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 (_exit_atController.text.isEmpty) {
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
|
|
SnackBar(
|
|
|
|
backgroundColor: Colors.redAccent[700],
|
|
|
|
content: Row(
|
|
|
|
children: [
|
|
|
|
Icon(
|
|
|
|
Icons.error_outline,
|
|
|
|
color: Colors.white,
|
|
|
|
),
|
|
|
|
SizedBox(width: 5),
|
|
|
|
Text('Tanggal Peminjaman harus diisi'),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
duration: Duration(seconds: 2),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
return null; // Return null jika ada kesalahan
|
|
|
|
}
|
|
|
|
return null; // Return null jika tidak ada kesalahan
|
|
|
|
},
|
|
|
|
controller: _exit_atController,
|
|
|
|
name: 'tanggal',
|
|
|
|
inputType: InputType.date,
|
|
|
|
// format: DateFormat('yyyy-MM-dd HH:mm:ss.SSS'),
|
|
|
|
format: DateFormat('yyyy-MM-dd', 'id_ID'),
|
|
|
|
decoration: InputDecoration(
|
|
|
|
labelText: 'Tanggal Peminjaman',
|
|
|
|
border: OutlineInputBorder(),
|
|
|
|
suffixIcon: Icon(Icons.calendar_today),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
SizedBox(height: 16),
|
|
|
|
Card(
|
|
|
|
elevation: 2,
|
|
|
|
child: Padding(
|
|
|
|
padding: const EdgeInsets.all(8),
|
|
|
|
child: FormBuilderDateTimePicker(
|
|
|
|
validator: (value) {
|
|
|
|
if (_est_pengembalianController.text.isEmpty) {
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
|
|
SnackBar(
|
|
|
|
backgroundColor: Colors.redAccent[700],
|
|
|
|
content: Row(
|
|
|
|
children: [
|
|
|
|
Icon(
|
|
|
|
Icons.error_outline,
|
|
|
|
color: Colors.white,
|
|
|
|
),
|
|
|
|
SizedBox(width: 5),
|
|
|
|
Text(
|
|
|
|
'Estimasi Tanggal Pengembalian harus diisi'),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
duration: Duration(seconds: 2),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
return null; // Return null jika ada kesalahan
|
|
|
|
}
|
|
|
|
return null; // Return null jika tidak ada kesalahan
|
|
|
|
},
|
|
|
|
controller: _est_pengembalianController,
|
|
|
|
name: 'tanggal',
|
|
|
|
inputType: InputType.date,
|
|
|
|
// format: DateFormat('yyyy-MM-dd HH:mm:ss.SSS'),
|
|
|
|
format: DateFormat('yyyy-MM-dd', 'id_ID'),
|
|
|
|
decoration: InputDecoration(
|
|
|
|
labelText: 'Estimasi Tanggal Pengembalian',
|
|
|
|
border: OutlineInputBorder(),
|
|
|
|
suffixIcon: Icon(Icons.calendar_today),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
SizedBox(height: 16),
|
|
|
|
Card(
|
|
|
|
elevation: 2,
|
|
|
|
child: Padding(
|
|
|
|
padding: const EdgeInsets.all(8),
|
|
|
|
child: TextFormField(
|
|
|
|
controller: _penanggungJawabController =
|
|
|
|
TextEditingController(text: user.fullname),
|
|
|
|
decoration: InputDecoration(
|
|
|
|
labelText: 'Penanggung Jawab',
|
|
|
|
border: OutlineInputBorder(),
|
|
|
|
),
|
|
|
|
validator: (value) {
|
|
|
|
if (value == null || value.isEmpty) {
|
|
|
|
return 'Harus diisi';
|
|
|
|
}
|
|
|
|
return null; // Return null jika tidak ada kesalahan
|
|
|
|
},
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
SizedBox(height: 16),
|
|
|
|
Card(
|
|
|
|
elevation: 2,
|
|
|
|
child: Padding(
|
|
|
|
padding: const EdgeInsets.all(8),
|
|
|
|
child: DropdownButtonFormField<WarehouseModel>(
|
|
|
|
validator: (value) {
|
|
|
|
if (value == null) {
|
|
|
|
return 'Harus diisi';
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
},
|
|
|
|
decoration: InputDecoration(
|
|
|
|
labelText: 'Pilih Gudang',
|
|
|
|
border: OutlineInputBorder(),
|
|
|
|
),
|
|
|
|
hint: Text("Pilih Gudang"),
|
|
|
|
value: _valWarehouse,
|
|
|
|
items:
|
|
|
|
_dataWarehouse.map((WarehouseModel warehouse) {
|
|
|
|
return DropdownMenuItem<WarehouseModel>(
|
|
|
|
child: Text('${warehouse.name}'),
|
|
|
|
value: warehouse,
|
|
|
|
);
|
|
|
|
}).toList(),
|
|
|
|
onChanged: (WarehouseModel? value) {
|
|
|
|
setState(() {
|
|
|
|
_valWarehouse = value;
|
|
|
|
});
|
|
|
|
},
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
SizedBox(height: 16),
|
|
|
|
// FractionallySizedBox(
|
|
|
|
// widthFactor: 1.0, // Lebar penuh
|
|
|
|
// child: Card(
|
|
|
|
// elevation: 1,
|
|
|
|
// child: Padding(
|
|
|
|
// padding: const EdgeInsets.all(8),
|
|
|
|
// child: Column(
|
|
|
|
// children: [
|
|
|
|
// Text(
|
|
|
|
// 'Data dari QR Code:',
|
|
|
|
// style: TextStyle(
|
|
|
|
// fontSize: 16,
|
|
|
|
// fontWeight: FontWeight.bold,
|
|
|
|
// ),
|
|
|
|
// ),
|
|
|
|
// SizedBox(height: 8),
|
|
|
|
// Text(
|
|
|
|
// result != null
|
|
|
|
// ? result!.code ??
|
|
|
|
// 'Belum ada data QR Code terpindai'
|
|
|
|
// : 'Belum ada data QR Code terpindai',
|
|
|
|
// style: TextStyle(fontSize: 14),
|
|
|
|
// ),
|
|
|
|
// ],
|
|
|
|
// ),
|
|
|
|
// ),
|
|
|
|
// ),
|
|
|
|
// ),
|
|
|
|
Visibility(
|
|
|
|
visible: false,
|
|
|
|
child: FractionallySizedBox(
|
|
|
|
widthFactor: 1.0,
|
|
|
|
child: Card(
|
|
|
|
elevation: 1,
|
|
|
|
child: Padding(
|
|
|
|
padding: const EdgeInsets.all(8),
|
|
|
|
child: Column(
|
|
|
|
children: [
|
|
|
|
Text(
|
|
|
|
'Data dari QR Code:',
|
|
|
|
style: TextStyle(
|
|
|
|
fontSize: 16,
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
SizedBox(height: 8),
|
|
|
|
Text(
|
|
|
|
result != null && result!.code != null
|
|
|
|
? result!.code!
|
|
|
|
: 'Belum ada data QR Code terpindai',
|
|
|
|
style: TextStyle(fontSize: 14),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
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, '/peminjaman-barang');
|
|
|
|
},
|
|
|
|
icon: Icon(Icons.close, color: Colors.white),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
// Container(
|
|
|
|
// // width: 50, // Lebar sesuai kebutuhan
|
|
|
|
// width: 65.0,
|
|
|
|
// height: 50, // Tinggi sesuai kebutuhan
|
|
|
|
// decoration: BoxDecoration(
|
|
|
|
// color: Colors.indigoAccent, // Warna latar belakang
|
|
|
|
// shape: BoxShape.circle, // Membuat lingkaran
|
|
|
|
// ),
|
|
|
|
// child: IconButton(
|
|
|
|
// onPressed: () {
|
|
|
|
// showModalBottomSheet(
|
|
|
|
// context: context,
|
|
|
|
// 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: 300,
|
|
|
|
// ),
|
|
|
|
// ),
|
|
|
|
// ),
|
|
|
|
// Positioned(
|
|
|
|
// bottom: 16,
|
|
|
|
// child: ElevatedButton(
|
|
|
|
// onPressed: () {
|
|
|
|
// Navigator.of(context).pop();
|
|
|
|
// },
|
|
|
|
// child: Text('Tutup'),
|
|
|
|
// ),
|
|
|
|
// ),
|
|
|
|
// ],
|
|
|
|
// );
|
|
|
|
// },
|
|
|
|
// );
|
|
|
|
// },
|
|
|
|
// icon: Icon(
|
|
|
|
// Icons.qr_code,
|
|
|
|
// size: 30,
|
|
|
|
// ),
|
|
|
|
// color: Colors.white, // Warna ikon
|
|
|
|
// ),
|
|
|
|
// ),
|
|
|
|
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: () {
|
|
|
|
if (_formKey.currentState!.validate()) {
|
|
|
|
try {
|
|
|
|
if (_exit_atController.text.isNotEmpty) {
|
|
|
|
_storePeminjaman();
|
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
print('Error storing data: $e');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
icon: Icon(Icons.save, color: Colors.white),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|