Browse Source

Update: Perbaiki Scan QR Code, Alert fungsi Scan QR Code nullable, penambahan fitur Transfer Peti

master
unknown 11 months ago
parent
commit
c76ecacb92
  1. 2
      lib/connection/connection.dart
  2. 15
      lib/main.dart
  3. 37
      lib/pages/home/home_page.dart
  4. 2
      lib/pages/home/main_page.dart
  5. 160
      lib/pages/peminjaman_barang/create.dart
  6. 2
      lib/pages/peminjaman_barang/peminjaman_stock_page.dart
  7. 136
      lib/pages/pengembalian_barang/edit.dart
  8. 3
      lib/pages/pengembalian_barang/pengembalian_index.dart
  9. 629
      lib/pages/transfer_peti/edit.dart
  10. 175
      lib/pages/transfer_peti/show.dart
  11. 287
      lib/pages/transfer_peti/transfer_peti_index.dart

2
lib/connection/connection.dart

@ -2,5 +2,3 @@ import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
String baseUrl = 'http://192.168.0.20:8000/api/v1';
// String baseUrl = 'http://10.0.0.2:8000/api/v1';
// String baseUrl = 'https://gps.sap-samara.com/api/v1';

15
lib/main.dart

@ -2,14 +2,17 @@ import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:siopas/pages/pengembalian_barang/create.dart';
import 'package:siopas/pages/pengembalian_barang/pengembalian-index.dart';
import 'package:siopas/pages/pengembalian_barang/edit.dart';
import 'package:siopas/pages/pengembalian_barang/pengembalian_index.dart';
import 'package:siopas/pages/transfer_peti/edit.dart';
import 'package:siopas/pages/transfer_peti/transfer_peti_index.dart';
import 'pages/home/main_page.dart';
import 'pages/home/peminjaman_stock_page.dart';
import 'pages/peminjaman_barang/peminjaman_stock_page.dart';
import 'pages/peminjaman_barang/create.dart';
import 'pages/peminjaman_barang/show.dart';
import 'pages/sign_in_page.dart';
import 'pages/splash_page.dart';
import 'pages/transfer_peti/show.dart';
import 'providers/asset_status_provider.dart';
import 'providers/auth_provider.dart';
import 'providers/m_status_provider.dart';
@ -57,10 +60,8 @@ class MyApp extends StatelessWidget {
'/pengembalian-barang': (context) => PengembalianBarangPage(),
'/pengembalian-barang/create': (context) =>
CreatePengembalianBarangPage(),
// '/peminjaman-barang/show': (context) =>
// DetailPeminjamanBarangPage(assetId: 0),
// '/category': (context) => SurveyDetailPage(),
// '/map': (context) => GeoMapPage(),
'/transfer-peti': (context) => TransferPetiPage(),
'/transfer-peti/edit': (context) => EditTransferPetiPage(),
},
),
);

37
lib/pages/home/home_page.dart

@ -316,6 +316,42 @@ class _HomePageState extends State<HomePage> {
);
}
Widget cardMenuTransfer() {
return Container(
margin: EdgeInsets.all(10),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
elevation: 5,
child: InkWell(
onTap: () {
// Aksi ketika card diklik
Navigator.pushNamed(context, '/transfer-peti');
},
child: Container(
padding: EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.input_outlined,
size: 50,
color: Colors.yellow[700],
),
SizedBox(height: 10),
Text(
'Transfer Peti',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
],
),
),
),
),
);
}
Widget cardRow() {
return Column(
children: [
@ -479,6 +515,7 @@ class _HomePageState extends State<HomePage> {
children: [
cardMenuPeminjaman(),
cardMenuPengembalian(),
cardMenuTransfer(),
],
),
],

2
lib/pages/home/main_page.dart

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../providers/auth_provider.dart';
import 'home_page.dart';
import 'peminjaman_stock_page.dart';
import '../peminjaman_barang/peminjaman_stock_page.dart';
import 'setting_page.dart';
class MainPage extends StatefulWidget {

160
lib/pages/peminjaman_barang/create.dart

@ -2,24 +2,20 @@ import 'dart:convert';
import 'dart:core';
import 'package:flutter/material.dart';
// import 'package:flutter_form_builder/flutter_form_builder.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:siopas/providers/asset_status_provider.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/asset_status_model.dart';
import '../../models/user_model.dart';
import '../../providers/auth_provider.dart';
import '../../theme.dart';
class CreatePeminjamanBarang extends StatefulWidget {
const CreatePeminjamanBarang({Key? key}) : super(key: key);
@ -72,7 +68,7 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
if (mounted) {
// Periksa apakah widget masih "mounted"
if (response.statusCode == 200) {
final jsonData = json.decode(response.body)['data']['asset'];
final jsonData = json.decode(response.body)['data']['petis'];
final List<PetiAssetModel> newDataAsset = (jsonData as List)
.map((item) => PetiAssetModel.fromJson(item))
@ -128,10 +124,15 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
}
}
void _onQRViewCreated(QRViewController controller) {
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 {
@ -140,32 +141,59 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
List<String> lines = result!.code!.split('\n');
String idPeti = '';
String idWarehouse = '';
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
if (line.contains(';')) {
List<String> values = line.split(';');
if (values.length >= 3) {
idPeti = values[1];
idWarehouse = values[2];
break;
}
} else if (line.startsWith('ID Warehouse')) {
String idWarehouse = line.split(': ')[1];
// Isi formulir dropdown gudang
_valWarehouse = _dataWarehouse.firstWhere(
(warehouse) => warehouse.id == int.parse(idWarehouse));
}
}
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;
});
@ -178,14 +206,74 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
});
} catch (e) {
print('Error scanning QR Code: $e');
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('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();
@ -197,6 +285,10 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
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,
@ -300,6 +392,12 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
style: TextStyle(
fontSize: 16,
)),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.pushNamed(context, '/peminjaman-barang');
},
),
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
@ -386,7 +484,7 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
borderRadius: 10,
borderLength: 30,
borderWidth: 10,
cutOutSize: 300,
cutOutSize: scanArea,
),
),
),

2
lib/pages/home/peminjaman_stock_page.dart → lib/pages/peminjaman_barang/peminjaman_stock_page.dart

@ -11,7 +11,7 @@ import 'package:siopas/providers/asset_status_provider.dart';
import 'package:http/http.dart' as http;
import '../../connection/connection.dart';
import '../peminjaman_barang/show.dart';
import 'show.dart';
class AssetStatusPage extends StatefulWidget {
const AssetStatusPage({super.key});

136
lib/pages/pengembalian_barang/create.dart → lib/pages/pengembalian_barang/edit.dart

@ -64,7 +64,7 @@ class _CreatePengembalianBarangPageState
});
final response =
await http.get(Uri.parse('$baseUrl/asset-status/pengembalian'));
await http.get(Uri.parse('$baseUrl/asset-status/pengembalian/create'));
if (mounted) {
// Periksa apakah widget masih "mounted"
@ -125,10 +125,15 @@ class _CreatePengembalianBarangPageState
}
}
void _onQRViewCreated(QRViewController controller) {
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 {
@ -137,31 +142,48 @@ class _CreatePengembalianBarangPageState
List<String> lines = result!.code!.split('\n');
String idPeti = '';
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);
_enterAtController.text = formattedDate;
} catch (e) {
print('Error parsing date: $e');
// Lakukan penanganan jika format tanggal tidak sesuai
if (line.contains(';')) {
List<String> values = line.split(';');
if (values.length >= 3) {
idPeti = values[1];
break;
}
}
// else if (line.startsWith('ID Warehouse')) {
// String idWarehouse = line.split(': ')[1];
// // Isi formulir dropdown gudang
// _valWarehouse = _dataWarehouse.firstWhere(
// (warehouse) => warehouse.id == int.parse(idWarehouse));
// }
}
int? petiId = int.tryParse(idPeti);
if (petiId != null) {
_valAsset = _dataAsset.firstWhere(
(peminjaman) => peminjaman.peti_id == petiId,
orElse: () => _valAsset!,
);
} 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],
),
);
}
scanned = true;
@ -171,14 +193,40 @@ class _CreatePengembalianBarangPageState
Future.delayed(Duration(milliseconds: 500), () {
if (mounted) {
Navigator.of(context).pop();
Navigator.pop(context);
}
});
} catch (e) {
controller.stopCamera();
if (mounted) {
Navigator.pushNamed(context, '/pengembalian-barang/create');
}
print('Error scanning QR Code: $e');
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Error scanning QR Code: $e'),
));
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Row(
children: [
Icon(
Icons.error, // Icon error
color: Colors.red[400], // Warna merah
),
SizedBox(width: 8),
Flexible(
// Menggunakan Flexible untuk menghindari overflow
child: Text(
'Peti ini belum ada di menu pinjaman, silahkan untuk mengecek kembali.',
style: TextStyle(
color: Colors.white,
fontSize: 12,
), // Warna teks merah
),
),
],
),
backgroundColor: Colors.red[700],
),
);
}
}
});
@ -195,6 +243,10 @@ class _CreatePengembalianBarangPageState
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;
Future<void> _updatePeminjaman() async {
setState(() {
@ -235,7 +287,7 @@ class _CreatePengembalianBarangPageState
color: Colors.white,
),
SizedBox(width: 5),
Text('Data berhasil diperbarui'),
Text('Data berhasil dikembalikan'),
],
),
duration: Duration(seconds: 3), // Durasi tampilan snackbar
@ -243,6 +295,7 @@ class _CreatePengembalianBarangPageState
);
// Reset form input
_valAsset = null;
_enterAtController.text = '';
_enterPicController.text = '';
_kondisiPetiController.text = '';
@ -279,15 +332,16 @@ class _CreatePengembalianBarangPageState
return Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Color.fromARGB(255, 5, 28, 158),
title: Text('Pengembalian Barang'),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.pushNamed(context, '/pengembalian-barang');
},
)),
elevation: 0,
backgroundColor: Color.fromARGB(255, 5, 28, 158),
title: Text('Pengembalian Barang'),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.pushNamed(context, '/pengembalian-barang');
},
),
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: SingleChildScrollView(
@ -347,6 +401,10 @@ class _CreatePengembalianBarangPageState
),
child: IconButton(
onPressed: () {
setState(() {
_valAsset =
null; // Mengatur _valAsset menjadi null
});
showModalBottomSheet(
context: context,
isScrollControlled:
@ -366,7 +424,7 @@ class _CreatePengembalianBarangPageState
borderRadius: 10,
borderLength: 30,
borderWidth: 10,
cutOutSize: 300,
cutOutSize: scanArea,
),
),
),

3
lib/pages/pengembalian_barang/pengembalian-index.dart → lib/pages/pengembalian_barang/pengembalian_index.dart

@ -51,7 +51,8 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
});
try {
final response = await http.get(Uri.parse('$baseUrl/asset-status'));
final response =
await http.get(Uri.parse('$baseUrl/asset-status/pengembalian'));
if (response.statusCode == 200) {
final jsonData = json.decode(response.body)['data']['asset_status'];

629
lib/pages/transfer_peti/edit.dart

@ -0,0 +1,629 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:intl/date_symbol_data_local.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/connection/connection.dart';
import 'package:http/http.dart' as http;
import 'package:siopas/models/asset_status_model.dart';
import 'package:siopas/models/m_asset_status_model.dart';
// import 'package:siopas/models/m_asset_status_model.dart';
import 'package:siopas/models/user_model.dart';
import 'package:siopas/models/warehouse_mode.dart';
import 'package:siopas/providers/auth_provider.dart';
class EditTransferPetiPage extends StatefulWidget {
const EditTransferPetiPage({super.key});
@override
State<EditTransferPetiPage> createState() => EditTransferPetiPageState();
}
class EditTransferPetiPageState extends State<EditTransferPetiPage> {
List<PetiAssetModel> _dataAsset = [];
List<WarehouseModel> _dataWarehouse = [];
bool _isLoading = false;
String? token;
PetiAssetModel? _valAsset;
WarehouseModel? _valWarehouse_asal_gudang;
WarehouseModel? _valWarehouse_tujuan_gudang;
// 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_asal_gudang = _dataWarehouse.firstWhere(
(warehouse) => warehouse.id == warehouseId,
orElse: () => _valWarehouse_asal_gudang!,
);
} 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'),
),
);
}
}
});
}
@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> _updateTransferPeti() async {
setState(() {
_isLoading = true;
});
try {
final response = await http.put(
Uri.parse('$baseUrl/peti-asset/update/${_valAsset!.id}'),
headers: {
'Content-Type': 'application/json',
'Authorization': token!,
},
body: jsonEncode({
'warehouse_id': _valWarehouse_tujuan_gudang!.id,
'updated_by': user.fullname,
}),
);
print(response.body);
if (response.statusCode == 200) {
final jsonData = json.decode(response.body)['data']['petis'];
print('Berhasil memperbarui 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 ditransferkan'),
],
),
duration: Duration(seconds: 3), // Durasi tampilan snackbar
),
);
// Reset form input
_valAsset = null;
_valWarehouse_asal_gudang = null;
_valWarehouse_tujuan_gudang = null;
// _enterAtController.text = '';
// _enterPicController.text = '';
// _kondisiPetiController.text = '';
// _valWarehouse = null;
} else {
_valAsset = null;
_valWarehouse_asal_gudang = null;
_valWarehouse_tujuan_gudang = null;
throw Exception('Gagal memperbarui data Asset Status');
}
} catch (e) {
print('Error updating 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 memperbarui 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,
)),
),
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_asal_gudang =
_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: DropdownButtonFormField<WarehouseModel>(
validator: (value) {
if (value == null) {
return 'Harus diisi';
}
return null;
},
decoration: InputDecoration(
labelText: 'Asal Gudang',
border: OutlineInputBorder(),
),
hint: Text("Asal Gudang"),
value: _valWarehouse_asal_gudang,
items:
_dataWarehouse.map((WarehouseModel warehouse) {
return DropdownMenuItem<WarehouseModel>(
child: Text('${warehouse.name}'),
value: warehouse,
);
}).toList(),
onChanged: null,
// (WarehouseModel? value) {
// setState(() {
// _valWarehouse_asal_gudang = 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: 'Tujuan Gudang',
border: OutlineInputBorder(),
),
hint: Text("Tujuan Gudang"),
value: _valWarehouse_tujuan_gudang,
items:
_dataWarehouse.map((WarehouseModel warehouse) {
return DropdownMenuItem<WarehouseModel>(
child: Text('${warehouse.name}'),
value: warehouse,
);
}).toList(),
onChanged: (WarehouseModel? value) {
setState(() {
_valWarehouse_tujuan_gudang = value;
});
},
),
),
),
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, '/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: () {
if (_formKey.currentState!.validate()) {
try {
_updateTransferPeti();
} catch (e) {
print('Error storing data: $e');
}
}
},
icon: Icon(Icons.save, color: Colors.white),
),
),
],
),
),
],
),
),
);
}
}

175
lib/pages/transfer_peti/show.dart

@ -0,0 +1,175 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:siopas/connection/connection.dart';
import 'package:http/http.dart' as http;
class DetailTransferPetiPage extends StatefulWidget {
final int petiId;
const DetailTransferPetiPage({Key? key, required this.petiId})
: super(key: key);
@override
State<DetailTransferPetiPage> createState() => _DetailTransferPetiPageState();
}
class _DetailTransferPetiPageState extends State<DetailTransferPetiPage> {
Map<String, dynamic>? petiStatusData;
String _formatDate(String date) {
DateTime parsedDate = DateTime.parse(date);
String formattedDate =
DateFormat('EEEE, dd MMMM yyyy', 'id_ID').format(parsedDate);
return formattedDate;
}
@override
void initState() {
super.initState();
_fetchAssetStatusDataPengembalian();
}
Future<void> _fetchAssetStatusDataPengembalian() async {
try {
final response = await http.get(
Uri.parse('$baseUrl/peti-asset/show/${widget.petiId}'),
headers: {
'Content-Type': 'application/json',
},
);
if (response.statusCode == 200) {
setState(() {
petiStatusData = json.decode(response.body)['data']['peti'];
});
} else {
throw Exception('Failed to load data');
}
} catch (e) {
print('Error fetching data: $e');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text('Detail Peti',
style: TextStyle(
color: Colors.white,
fontSize: 16,
)),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
Navigator.pushNamed(context, '/transfer-peti');
},
),
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
elevation: 5,
child: Column(
children: [
Card(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.vertical(top: Radius.circular(15.0)),
),
elevation: 0,
margin: EdgeInsets.all(0),
color: Colors.indigo[700],
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
children: [
Icon(Icons.article,
size: 40,
color: Colors.white), // Ganti ikon sesuai kebutuhan
SizedBox(width: 10),
Text(
'ID: ${widget.petiId}',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
],
),
),
),
SizedBox(height: 10),
if (petiStatusData != null) ...[
_buildDetailItem(
'Tipe Peti',
petiStatusData!['tipe_peti']['type'],
),
Divider(thickness: 1),
_buildDetailItem(
'Warna Peti',
petiStatusData!['warna'] != null
? petiStatusData!['warna'].toString()
: '-'),
Divider(thickness: 1),
_buildDetailItem(
'Customer',
petiStatusData!['customer']['name'] != null
? petiStatusData!['customer']['name'].toString()
: '-'),
Divider(thickness: 1),
_buildDetailItem(
'Warehouse',
petiStatusData!['warehouse']['name'] != null
? petiStatusData!['warehouse']['name'].toString()
: '-'),
Divider(thickness: 1),
_buildDetailItem(
'Status Peti',
petiStatusData!['status_disposal'] != null
? petiStatusData!['status_disposal'].toString()
: '-'),
Divider(thickness: 1),
_buildDetailItem(
'Jumlah Peti',
petiStatusData!['jumlah'] != null
? petiStatusData!['jumlah'].toString()
: '-',
),
Divider(thickness: 1),
_buildDetailItem(
'Tgl Pembuatan Peti',
petiStatusData!['created_at'] != null
? _formatDate(petiStatusData!['created_at'])
: '-'),
],
],
),
),
),
);
}
Widget _buildDetailItem(String label, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
label,
style: TextStyle(fontSize: 12.5, fontWeight: FontWeight.bold),
),
Text(value),
],
),
);
}
}

287
lib/pages/transfer_peti/transfer_peti_index.dart

@ -0,0 +1,287 @@
import 'dart:convert';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:data_table_2/data_table_2.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:siopas/models/asset_status_model.dart';
import 'package:siopas/models/m_asset_status_model.dart';
import 'package:siopas/pages/pengembalian_barang/show.dart';
import 'package:siopas/pages/transfer_peti/show.dart';
import 'package:siopas/providers/asset_status_provider.dart';
import 'package:http/http.dart' as http;
import '../../connection/connection.dart';
import '../peminjaman_barang/show.dart';
class TransferPetiPage extends StatefulWidget {
const TransferPetiPage({super.key});
@override
State<TransferPetiPage> createState() => TransferPetiPageState();
}
class TransferPetiPageState extends State<TransferPetiPage> {
String? token;
int _currentPage = 1;
int _pageSize = 10;
List<PetiAssetModel> _data = [];
bool _isLoading = false;
@override
void initState() {
super.initState();
_getUserToken();
fetchData();
}
void _getUserToken() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
if (mounted) {
setState(() {
token = prefs.getString('token');
});
}
}
Future<void> fetchData() async {
if (mounted) {
setState(() {
_isLoading = true;
});
try {
final response = await http.get(Uri.parse('$baseUrl/peti-asset'));
if (response.statusCode == 200) {
final jsonData = json.decode(response.body)['data']['petis'];
final List<PetiAssetModel> newData = (jsonData as List)
.map((item) => PetiAssetModel.fromJson(item))
.toList();
if (mounted) {
setState(() {
_data.addAll(newData);
_isLoading = false;
});
}
} else {
if (mounted) {
setState(() {
_isLoading = false;
});
}
throw Exception('Failed to fetch data');
}
} catch (e) {
if (mounted) {
setState(() {
_isLoading = false;
});
}
print('Error fetching data: $e');
}
}
}
void _loadMoreData() {
if (mounted && !_isLoading) {
setState(() {
_currentPage++;
});
fetchData();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text('Data Peti (Transfer Peti)',
style: TextStyle(
fontSize: 16,
)),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
Navigator.pushNamed(context, '/home');
},
),
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: SingleChildScrollView(
child: SizedBox(
width: double.infinity,
child: PaginatedDataTable(
header: const Text('Menu Peti'),
rowsPerPage: _pageSize,
availableRowsPerPage: const [10, 25, 50],
onRowsPerPageChanged: (value) {
setState(() {
_pageSize = value!;
});
},
columns: const [
DataColumn(label: Text('No')),
DataColumn(label: Text('')),
DataColumn(label: Text('Customer')),
DataColumn(label: Text('Gudang')),
DataColumn(label: Text('Fix Lot')),
DataColumn(label: Text('Tipe Peti')),
DataColumn(label: Text('Ukuran Peti')),
DataColumn(label: Text('Lot No')),
DataColumn(label: Text('Status Peti')),
DataColumn(label: Text('Packing No')),
],
source: _DataSource(data: _data, context: context),
),
),
),
bottomNavigationBar: BottomAppBar(
color: Color.fromARGB(255, 5, 28, 158), // Warna latar belakang
child: Container(
height: 65.0,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
InkWell(
customBorder: CircleBorder(),
onTap: () {
// Aksi ketika ikon diklik
Navigator.pushNamed(context, '/transfer-peti/edit');
},
child: Container(
width: 45,
height: 45,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.yellow[800],
),
child: Icon(
Icons.local_shipping,
size: 30,
color: Colors.white,
),
),
),
],
),
),
),
);
}
}
class _DataSource extends DataTableSource {
final List<PetiAssetModel> data;
final BuildContext context;
_DataSource({required this.data, required this.context});
@override
DataRow? getRow(int index) {
if (index >= data.length) {
return null;
}
final item = data[index];
return DataRow(cells: [
DataCell(
Text(
(index + 1).toString(),
),
),
DataCell(
GestureDetector(
onTap: () {
if (item.id != null) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailTransferPetiPage(
petiId: item.id!,
),
),
);
print('asset id: ${item.id}');
}
},
child: Icon(
Icons.article_outlined,
size: 30,
color: Colors.indigo[700],
),
),
),
DataCell(
Text(
item.customer!.name!.toString() != 'null'
? item.customer!.name.toString()
: '-',
),
),
DataCell(
Text(
item.warehouse!.name!.toString() != 'null'
? item.warehouse!.name.toString()
: '-',
),
),
DataCell(
Text(
item.fix_lot.toString() != 'null' ? item.fix_lot.toString() : '-',
),
),
DataCell(
Text(
item.tipe_peti!.type.toString() != 'null'
? item.tipe_peti!.type.toString()
: '-',
),
),
DataCell(
Text(item.tipe_peti!.size_peti.toString() != 'null'
? item.tipe_peti!.size_peti.toString()
: '-'),
),
DataCell(
Text(
item.customer!.lot_no.toString() != 'null'
? item.customer!.lot_no.toString()
: '-',
),
),
DataCell(
Text(
item.status_disposal.toString() != 'null'
? item.status_disposal.toString()
: '-',
),
),
DataCell(
Text(
item.packing_no.toString() != 'null'
? item.packing_no.toString()
: '-',
),
),
]);
}
@override
bool get isRowCountApproximate => false;
@override
int get rowCount => data.length;
@override
int get selectedRowCount => 0;
}
Loading…
Cancel
Save