You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
874 lines
36 KiB
874 lines
36 KiB
11 months ago
|
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:uuid/uuid.dart';
|
||
|
|
||
|
import '../../models/asset_status_model.dart';
|
||
|
import '../../models/customer_model.dart';
|
||
|
import '../../models/disposal_model.dart';
|
||
|
import '../../models/m_asset_status_model.dart';
|
||
|
import '../../models/type_peti_model.dart';
|
||
|
import '../../models/user_model.dart';
|
||
|
import '../../models/warehouse_mode.dart';
|
||
|
import '../../providers/auth_provider.dart';
|
||
|
import '../../services/controllerApi.dart';
|
||
|
import 'conn/syncronize.dart';
|
||
|
import 'controller/peminjaman_controller.dart';
|
||
|
|
||
|
class InformasiDataEntryPage extends StatefulWidget {
|
||
|
final List<AssetStatusModel> temporaryDataList;
|
||
|
|
||
|
InformasiDataEntryPage({required this.temporaryDataList});
|
||
|
|
||
|
@override
|
||
|
_InformasiDataEntryPageState createState() => _InformasiDataEntryPageState();
|
||
|
}
|
||
|
|
||
|
class _InformasiDataEntryPageState extends State<InformasiDataEntryPage> {
|
||
|
String? token;
|
||
|
// List<CustomerModel>? customerSqfliteApi;
|
||
|
PetiAssetModel? petiSqfliteApi;
|
||
|
WarehouseModel? warehouseSqfliteApi;
|
||
|
WarehouseModel? warehouseTujuanSqfliteApi;
|
||
|
DisposalPetiModel? disposalSqfliteApi;
|
||
|
CustomerModel? customerSqfliteApi;
|
||
|
List<PetiAssetModel>? _valpeti; // Change this line
|
||
|
List<WarehouseModel>? _valwarehouse;
|
||
|
List<WarehouseModel>? _valwarehouseTujuan;
|
||
|
List<CustomerModel>? _valcustomer;
|
||
|
List<DisposalPetiModel>? _valdisposal;
|
||
|
List<PetiAssetModel> _allPetiList = [];
|
||
|
List<PetiAssetModel> _unrestrictedPetiList = [];
|
||
|
List<PetiAssetModel> _filteredPetiList = [];
|
||
|
bool isQRCodeScanned = false;
|
||
|
String searchText = '';
|
||
|
PetiAssetModel? selectedPeti;
|
||
|
TextEditingController searchBoxController = TextEditingController();
|
||
|
TextEditingController _exit_atController = TextEditingController();
|
||
|
TextEditingController _est_pengembalianController = 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 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 disposalListAPI() async {
|
||
|
if (mounted) {
|
||
|
await ControllerApi().fetchDisposalDataAPI().then((value) {
|
||
|
setState(() {
|
||
|
_valdisposal = (value as List<dynamic>)
|
||
|
.map((item) => DisposalPetiModel.fromJson(item))
|
||
|
.toList();
|
||
|
loading = false;
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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 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<void> isInteret() async {
|
||
|
await SyncronizationPeminjamanData.isInternet().then((connection) {
|
||
|
if (connection) {
|
||
|
print("Internet connection available");
|
||
|
} else {
|
||
|
ScaffoldMessenger.of(context)
|
||
|
.showSnackBar(SnackBar(content: Text("No Internet")));
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
@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('selectedPetiList');
|
||
|
|
||
|
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('selectedPetiList', 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: ${_exit_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 = [];
|
||
|
|
||
|
for (PetiAssetModel selectedPeti in selectedPetis) {
|
||
|
// print("Checking conditions for Peti ID: ${selectedPeti.id}");
|
||
|
// print("Exit_atController: ${_exit_atController.text.isNotEmpty}");
|
||
|
// print("petiSqfliteApi: ${petiSqfliteApi != null}");
|
||
|
// print("warehouseSqfliteApi: ${warehouseSqfliteApi != null}");
|
||
|
|
||
|
if (selectedPeti == null) {
|
||
|
print("Selected Peti is null");
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// Ensure that _valpeti is not null before trying to find the PetiAssetModel
|
||
|
if (_valpeti == null) {
|
||
|
print("_valpeti is null");
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
petiSqfliteApi =
|
||
|
_valpeti?.firstWhereOrNull((peti) => peti.id == selectedPeti.id);
|
||
|
|
||
|
if (petiSqfliteApi == null) {
|
||
|
print("Peti not found for ID: ${selectedPeti.id}");
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (_exit_atController.text.isNotEmpty &&
|
||
|
petiSqfliteApi != null &&
|
||
|
warehouseSqfliteApi != null) {
|
||
|
print("All conditions met. Saving data...");
|
||
|
|
||
|
AssetStatusModel assetAddModel = AssetStatusModel(
|
||
|
id: null,
|
||
|
peti_id: selectedPeti.id,
|
||
|
customer_id: customerSqfliteApi?.id,
|
||
|
warehouse_id: warehouseSqfliteApi?.id,
|
||
|
exit_at: parseDateTime(_exit_atController.text),
|
||
|
exit_pic: _penanggungJawabController.text,
|
||
|
est_pengembalian: parseDateTime(_est_pengembalianController.text),
|
||
|
created_by: user.fullname,
|
||
|
created_at: parseDateTime(formattedDate),
|
||
|
mobile_id: uuid.v4(),
|
||
|
);
|
||
|
|
||
|
// Call addData function
|
||
|
int result = await Controller().addPeminjamanData(assetAddModel);
|
||
|
|
||
|
if (result > 0) {
|
||
|
savedPetiIds.add(selectedPeti.id!);
|
||
|
if (mounted) {
|
||
|
setState(() {
|
||
|
_exit_atController.text = '';
|
||
|
_penanggungJawabController.text = '';
|
||
|
_est_pengembalianController.text = '';
|
||
|
warehouseSqfliteApi?.id = null;
|
||
|
customerSqfliteApi?.id = null;
|
||
|
});
|
||
|
}
|
||
|
print("Success Tambah data untuk Peti ID: ${selectedPeti.id}");
|
||
|
EasyLoading.showSuccess("Data Berhasil Disimpan");
|
||
|
// Reset controllers and make fields nullable
|
||
|
} else {
|
||
|
print("Failed untuk Peti ID: ${selectedPeti.id}");
|
||
|
}
|
||
|
} else {
|
||
|
print("Conditions not met. Unable to save data.");
|
||
|
if (_exit_atController.text.isEmpty) {
|
||
|
print("Exit_atController is empty");
|
||
|
}
|
||
|
if (petiSqfliteApi == null) {
|
||
|
print("petiSqfliteApi is null");
|
||
|
}
|
||
|
if (warehouseSqfliteApi == null) {
|
||
|
print("warehouseSqfliteApi is 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, '/peminjaman-barang');
|
||
|
}
|
||
|
|
||
|
return Scaffold(
|
||
|
appBar: AppBar(
|
||
|
automaticallyImplyLeading: true,
|
||
|
backgroundColor: Colors.indigo[700],
|
||
|
elevation: 0,
|
||
|
title: Text('Isikan Data Peminjaman 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(
|
||
|
'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(
|
||
|
'Tanggal Peminjaman:',
|
||
|
style: TextStyle(
|
||
|
fontSize: 14, fontWeight: FontWeight.bold),
|
||
|
),
|
||
|
SizedBox(height: 8),
|
||
|
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_peminjaman',
|
||
|
inputType: InputType.date,
|
||
|
format: DateFormat('yyyy-MM-dd', 'id_ID'),
|
||
|
decoration: InputDecoration(
|
||
|
hintText: 'Tanggal Peminjaman',
|
||
|
border: OutlineInputBorder(),
|
||
|
suffixIcon: Icon(Icons.calendar_today),
|
||
|
),
|
||
|
onChanged: (DateTime? selectedDate) {
|
||
|
if (selectedDate != null) {
|
||
|
// Mengisi tanggal estimasi 7 hari ke depan
|
||
|
DateTime estimasiPengembalian =
|
||
|
selectedDate.add(Duration(days: 7));
|
||
|
_est_pengembalianController.text =
|
||
|
DateFormat('yyyy-MM-dd')
|
||
|
.format(estimasiPengembalian);
|
||
|
}
|
||
|
},
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
SizedBox(height: 16),
|
||
|
Container(
|
||
|
child: Column(
|
||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||
|
children: [
|
||
|
Text(
|
||
|
'Estimasi Pengembalian:',
|
||
|
style: TextStyle(
|
||
|
fontSize: 14, fontWeight: FontWeight.bold),
|
||
|
),
|
||
|
SizedBox(height: 4),
|
||
|
Text(
|
||
|
'* Terisi otomatis 7 hari setelah tanggal peminjaman',
|
||
|
style: TextStyle(
|
||
|
fontSize: 12,
|
||
|
color: Colors.red,
|
||
|
fontStyle: FontStyle.italic),
|
||
|
),
|
||
|
SizedBox(height: 8),
|
||
|
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('Tanggal Estimasi Pengembalian'),
|
||
|
],
|
||
|
),
|
||
|
duration: Duration(seconds: 2),
|
||
|
),
|
||
|
);
|
||
|
return null; // Return null jika ada kesalahan
|
||
|
}
|
||
|
return null; // Return null jika tidak ada kesalahan
|
||
|
},
|
||
|
controller: _est_pengembalianController,
|
||
|
name: 'estimasi_pengembalian',
|
||
|
inputType: InputType.date,
|
||
|
format: DateFormat('yyyy-MM-dd', 'id_ID'),
|
||
|
decoration: InputDecoration(
|
||
|
hintText: 'Estimasi Tanggal Pengembalian',
|
||
|
border: OutlineInputBorder(),
|
||
|
suffixIcon: Icon(Icons.calendar_today),
|
||
|
),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
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,
|
||
|
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',
|
||
|
fontWeight:
|
||
|
warehouseSqfliteApi?.id ==
|
||
|
warehouse.id
|
||
|
? FontWeight.bold
|
||
|
: FontWeight.normal,
|
||
|
),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
value: warehouse,
|
||
|
);
|
||
|
}).toList() ??
|
||
|
[],
|
||
|
onChanged: (value) {
|
||
|
setState(() {
|
||
|
warehouseSqfliteApi = value;
|
||
|
});
|
||
|
},
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
},
|
||
|
),
|
||
|
),
|
||
|
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 (_exit_atController.text.isNotEmpty &&
|
||
|
warehouseSqfliteApi != null) {
|
||
|
await saveAssetData(selectedPetis);
|
||
|
} 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),
|
||
|
),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
}
|