|
|
|
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/transfer_peti_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/transfer_peti/controller/transfer_peti_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 '../../models/user_model.dart';
|
|
|
|
import '../../providers/auth_provider.dart';
|
|
|
|
import 'package:collection/collection.dart';
|
|
|
|
|
|
|
|
// import 'conn/syncronizeAPI.dart';
|
|
|
|
// import 'controller/peminjaman_controller.dart';
|
|
|
|
|
|
|
|
class EditTransferPetiPage extends StatefulWidget {
|
|
|
|
const EditTransferPetiPage({Key? key}) : super(key: key);
|
|
|
|
|
|
|
|
@override
|
|
|
|
State<EditTransferPetiPage> createState() => _EditTransferPetiPageState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _EditTransferPetiPageState extends State<EditTransferPetiPage> {
|
|
|
|
List<TransferPetiModel>? _data;
|
|
|
|
|
|
|
|
String? token;
|
|
|
|
List<TypePetiModel>? typePetiSqfliteApi;
|
|
|
|
// List<CustomerModel>? customerSqfliteApi;
|
|
|
|
// List<WarehouseModel>? warehouseTujuanSqfliteApi;
|
|
|
|
|
|
|
|
PetiAssetModel? petiSqfliteApi;
|
|
|
|
ConditionPetiModel? conditionPetiSqfliteApi;
|
|
|
|
WarehouseModel? warehouseSqfliteApi;
|
|
|
|
WarehouseModel? warehouseTujuanSqfliteApi;
|
|
|
|
CustomerModel? customerItemSqfliteApi;
|
|
|
|
|
|
|
|
List<PetiAssetModel>? _valpeti; // Change this line
|
|
|
|
List<WarehouseModel>? _valwarehouse;
|
|
|
|
List<WarehouseModel>? _valWarehouse_tujuan_gudang;
|
|
|
|
List<ConditionPetiModel>? _valconditionPeti;
|
|
|
|
|
|
|
|
CustomerModel? customerSqfliteApi;
|
|
|
|
List<CustomerModel>? _valcustomer;
|
|
|
|
|
|
|
|
List<PetiAssetModel> _unrestrictedPetiList = [];
|
|
|
|
List<PetiAssetModel> _filteredPetiList = [];
|
|
|
|
bool isQRCodeScanned = false;
|
|
|
|
|
|
|
|
TextEditingController searchBoxController = TextEditingController();
|
|
|
|
TextEditingController _dateController = TextEditingController();
|
|
|
|
// TextEditingController _enterPicController = TextEditingController();
|
|
|
|
// TextEditingController _kondisiPetiController = TextEditingController();
|
|
|
|
// TextEditingController _penanggungJawabController = TextEditingController();
|
|
|
|
final _formKey = GlobalKey<FormState>();
|
|
|
|
|
|
|
|
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
|
|
|
|
Barcode? result;
|
|
|
|
QRViewController? controller;
|
|
|
|
|
|
|
|
bool loading = true;
|
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
super.initState();
|
|
|
|
_getUserToken();
|
|
|
|
warehouseListAPI();
|
|
|
|
|
|
|
|
// Memulai loading
|
|
|
|
setState(() {
|
|
|
|
loading = true;
|
|
|
|
});
|
|
|
|
|
|
|
|
datatablesTransferPetiList();
|
|
|
|
// typePetiListAPI();
|
|
|
|
customerListAPI();
|
|
|
|
petiListAPI();
|
|
|
|
kondisiPetiListAPI();
|
|
|
|
|
|
|
|
initializeDateFormatting('id_ID', null);
|
|
|
|
|
|
|
|
// Mengakhiri loading setelah tugas selesai
|
|
|
|
setState(() {
|
|
|
|
loading = false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
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<dynamic>)
|
|
|
|
.map((item) => WarehouseModel.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 datatablesTransferPetiList() async {
|
|
|
|
await ControllerTransferPeti()
|
|
|
|
.fetchTransferPetiLocalController()
|
|
|
|
.then((value) {
|
|
|
|
setState(() {
|
|
|
|
_data = (value as List<dynamic>)
|
|
|
|
.map((e) => TransferPetiModel.fromJson(e))
|
|
|
|
.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(() {
|
|
|
|
_valconditionPeti = (value as List<dynamic>)
|
|
|
|
.map((item) => ConditionPetiModel.fromJson(item))
|
|
|
|
.toList();
|
|
|
|
loading = false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> isInteret() async {
|
|
|
|
await SyncronizationPengembalianData.isInternet().then((connection) {
|
|
|
|
if (connection) {
|
|
|
|
print("Internet connection available");
|
|
|
|
} else {
|
|
|
|
ScaffoldMessenger.of(context)
|
|
|
|
.showSnackBar(SnackBar(content: Text("No Internet")));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
// AuthProvider authProvider = Provider.of<AuthProvider>(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;
|
|
|
|
|
|
|
|
warehouseSqfliteApi = _valwarehouse?.firstWhereOrNull(
|
|
|
|
(warehouse) => warehouse.id == allowedPeti.warehouse_id,
|
|
|
|
);
|
|
|
|
|
|
|
|
customerSqfliteApi = _valcustomer?.firstWhereOrNull(
|
|
|
|
(customer) => customer.id == allowedPeti.customer_id,
|
|
|
|
);
|
|
|
|
});
|
|
|
|
} 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<AuthProvider>(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<void> saveAssetData() async {
|
|
|
|
DateTime now = DateTime.now().toLocal();
|
|
|
|
String formattedDate = DateFormat('yyyy-MM-dd HH:mm:ss.SSS').format(now);
|
|
|
|
|
|
|
|
if (_dateController.text.isNotEmpty) {
|
|
|
|
TransferPetiModel transferPetiAddModel = TransferPetiModel(
|
|
|
|
id: null,
|
|
|
|
mobile_id: uuid.v4(),
|
|
|
|
peti_id: petiSqfliteApi!.id,
|
|
|
|
name_customer: customerSqfliteApi!.id,
|
|
|
|
source_warehouse: warehouseSqfliteApi!.id,
|
|
|
|
destination_warehouse: warehouseTujuanSqfliteApi!.id,
|
|
|
|
date: parseDateTime(_dateController.text),
|
|
|
|
created_by: user.fullname,
|
|
|
|
created_at: parseDateTime(formattedDate),
|
|
|
|
);
|
|
|
|
|
|
|
|
// Call addData function
|
|
|
|
int result =
|
|
|
|
await ControllerTransferPeti().addData(transferPetiAddModel);
|
|
|
|
if (result > 0) {
|
|
|
|
print("Success Tambah data");
|
|
|
|
// print(result);
|
|
|
|
Navigator.pushNamed(context, '/transfer-peti');
|
|
|
|
EasyLoading.showSuccess("Data Berhasil Disimpan Transfer Peti");
|
|
|
|
} 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 Transfer 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<PetiAssetModel>(
|
|
|
|
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) {
|
|
|
|
warehouseSqfliteApi = _valwarehouse
|
|
|
|
?.firstWhere((warehouse) =>
|
|
|
|
warehouse.id ==
|
|
|
|
value.warehouse_id);
|
|
|
|
customerSqfliteApi = _valcustomer
|
|
|
|
?.firstWhereOrNull((customer) =>
|
|
|
|
customer.id ==
|
|
|
|
value.customer_id);
|
|
|
|
|
|
|
|
// 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 (_dateController.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: _dateController,
|
|
|
|
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 Transfer Peti',
|
|
|
|
border: OutlineInputBorder(),
|
|
|
|
suffixIcon: Icon(Icons.calendar_today),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
SizedBox(height: 13),
|
|
|
|
Card(
|
|
|
|
child: Padding(
|
|
|
|
padding: const EdgeInsets.all(8.0),
|
|
|
|
child: DropdownSearch<CustomerModel>(
|
|
|
|
dropdownDecoratorProps: DropDownDecoratorProps(
|
|
|
|
dropdownSearchDecoration: InputDecoration(
|
|
|
|
labelText: '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: 13),
|
|
|
|
Card(
|
|
|
|
child: Padding(
|
|
|
|
padding: const EdgeInsets.all(8.0),
|
|
|
|
child: DropdownButtonFormField<WarehouseModel>(
|
|
|
|
validator: (value) {
|
|
|
|
if (value == null) {
|
|
|
|
return 'Harus diisi';
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
},
|
|
|
|
decoration: InputDecoration(
|
|
|
|
labelText: '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: 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<WarehouseModel>(
|
|
|
|
validator: (value) {
|
|
|
|
if (value == null) {
|
|
|
|
return 'Harus diisi';
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
},
|
|
|
|
decoration: InputDecoration(
|
|
|
|
labelText: 'Tujuan Transfer Gudang',
|
|
|
|
border: OutlineInputBorder(),
|
|
|
|
),
|
|
|
|
hint: Text("Tujuan Transfer Gudang"),
|
|
|
|
value: warehouseTujuanSqfliteApi,
|
|
|
|
items: (_valwarehouse ?? [])
|
|
|
|
.where((warehouseTujuan) =>
|
|
|
|
warehouseTujuan.deleted_at != true)
|
|
|
|
.map((WarehouseModel warehouseTujuan)
|
|
|
|
// _valwarehouse?.map((WarehouseModel warehouse)
|
|
|
|
{
|
|
|
|
return DropdownMenuItem<WarehouseModel>(
|
|
|
|
child: Row(
|
|
|
|
children: [
|
|
|
|
Icon(
|
|
|
|
Icons.local_shipping,
|
|
|
|
color: warehouseTujuan.id ==
|
|
|
|
warehouseTujuanSqfliteApi?.id
|
|
|
|
? Colors.green[700]
|
|
|
|
: Colors.grey,
|
|
|
|
),
|
|
|
|
SizedBox(
|
|
|
|
width:
|
|
|
|
8), // Jarak antara ikon dan teks
|
|
|
|
Text(
|
|
|
|
'${warehouseTujuan.name}',
|
|
|
|
style: TextStyle(
|
|
|
|
fontSize: 16,
|
|
|
|
fontFamily: 'OpenSansCondensed',
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
value: warehouseTujuan,
|
|
|
|
);
|
|
|
|
}).toList() ??
|
|
|
|
[],
|
|
|
|
onChanged: (WarehouseModel? value) {
|
|
|
|
setState(() {
|
|
|
|
warehouseTujuanSqfliteApi = value;
|
|
|
|
});
|
|
|
|
},
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
// 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 Tujuan Gudang',
|
|
|
|
// border: OutlineInputBorder(),
|
|
|
|
// ),
|
|
|
|
// hint: Text("Pilih Tujuan Gudang"),
|
|
|
|
// value: warehouseTujuanSqfliteApi,
|
|
|
|
// items: (_valWarehouse_tujuan_gudang ?? [])
|
|
|
|
// .where(
|
|
|
|
// (warehouse) => warehouse.deleted_at != true)
|
|
|
|
// .map((WarehouseModel warehouse)
|
|
|
|
// // _valWarehouse_tujuan_gudang?.map((warehouse)
|
|
|
|
// {
|
|
|
|
// return DropdownMenuItem<WarehouseModel>(
|
|
|
|
// child: Text('${warehouse.name}'),
|
|
|
|
// value: warehouse,
|
|
|
|
// );
|
|
|
|
// }).toList(),
|
|
|
|
// onChanged: (WarehouseModel? value) {
|
|
|
|
// setState(() {
|
|
|
|
// warehouseTujuanSqfliteApi = value;
|
|
|
|
// });
|
|
|
|
// },
|
|
|
|
// ),
|
|
|
|
// ),
|
|
|
|
// ),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
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, '/transfer-peti');
|
|
|
|
},
|
|
|
|
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 (_dateController.text.isNotEmpty &&
|
|
|
|
petiSqfliteApi != null &&
|
|
|
|
warehouseSqfliteApi != null) {
|
|
|
|
await saveAssetData();
|
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
print('Error storing data: $e');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
icon: Icon(Icons.save, color: Colors.white),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|