Browse Source

perbaikan, tampilan login, ubah loading, ubah showAlertModal, Search peti dan customer, perbaikan pada warehouse dropdown dan kondisi, perbaikan transfer

master
unknown 1 year ago
parent
commit
35cd0f2f5f
  1. 36
      android/app/build.gradle
  2. 1
      android/app/src/main/AndroidManifest.xml
  3. BIN
      android/app/src/main/res/drawable-hdpi/ic_launcher_background.png
  4. BIN
      android/app/src/main/res/drawable-mdpi/ic_launcher_background.png
  5. BIN
      android/app/src/main/res/drawable-xhdpi/ic_launcher_background.png
  6. BIN
      android/app/src/main/res/drawable-xxhdpi/ic_launcher_background.png
  7. BIN
      android/app/src/main/res/drawable-xxxhdpi/ic_launcher_background.png
  8. 2
      android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
  9. BIN
      android/app/src/main/res/mipmap-hdpi/ic_launcher.png
  10. BIN
      android/app/src/main/res/mipmap-mdpi/ic_launcher.png
  11. BIN
      android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  12. BIN
      android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  13. BIN
      android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  14. 4
      android/app/src/main/res/values/colors.xml
  15. BIN
      assets/img/logo_siopas_apps.png
  16. BIN
      assets/img/putih.png
  17. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  18. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
  19. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
  20. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
  21. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
  22. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
  23. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
  24. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
  25. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
  26. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
  27. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png
  28. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png
  29. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png
  30. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png
  31. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
  32. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
  33. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png
  34. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png
  35. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
  36. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
  37. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
  38. 8
      lib/migrations/databasehelper.dart
  39. 19
      lib/models/m_asset_status_model.dart
  40. 43
      lib/pages/home/home_page.dart
  41. 68
      lib/pages/home/setting_page.dart
  42. 101
      lib/pages/peminjaman_barang/conn/syncronize.dart
  43. 14
      lib/pages/peminjaman_barang/controller/peminjaman_controller.dart
  44. 429
      lib/pages/peminjaman_barang/create.dart
  45. 78
      lib/pages/peminjaman_barang/peminjaman_stock_page.dart
  46. 117
      lib/pages/peminjaman_barang/show.dart
  47. 90
      lib/pages/pengembalian_barang/conn/syncronize.dart
  48. 14
      lib/pages/pengembalian_barang/controller/pengembalian_controller.dart
  49. 207
      lib/pages/pengembalian_barang/edit.dart
  50. 61
      lib/pages/pengembalian_barang/index.dart
  51. 106
      lib/pages/pengembalian_barang/show.dart
  52. 55
      lib/pages/sign_in_page.dart
  53. 6
      lib/pages/splash_page.dart
  54. 97
      lib/pages/transfer_peti/conn/syncronize.dart
  55. 16
      lib/pages/transfer_peti/controller/transfer_peti_controller.dart
  56. 340
      lib/pages/transfer_peti/edit.dart
  57. 78
      lib/pages/transfer_peti/index.dart
  58. 367
      lib/pages/transfer_peti/show.dart
  59. 114
      lib/services/controllerApi.dart
  60. 51
      lib/services/syncronizeAPI.dart
  61. 24
      pubspec.lock
  62. 14
      pubspec.yaml

36
android/app/build.gradle

@ -22,6 +22,13 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
// // baru push apps
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
namespace "com.example.siopas"
compileSdkVersion flutter.compileSdkVersion
@ -46,17 +53,34 @@ android {
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
// minSdkVersion flutter.minSdkVersion
minSdkVersion 20
minSdkVersion 21
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
// original
// buildTypes {
// release {
// // TODO: Add your own signing config for the release build.
// // Signing with the debug keys for now, so `flutter run --release` works.
// signingConfig signingConfigs.debug
// }
// }
// baru push apps
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
signingConfig signingConfigs.release
}
}
}
@ -65,4 +89,6 @@ flutter {
source '../..'
}
dependencies {}
dependencies {
implementation 'com.google.android.material:material:1.9.0'
}

1
android/app/src/main/AndroidManifest.xml

@ -1,5 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:label="SIOPAS ISTW"

BIN
android/app/src/main/res/drawable-hdpi/ic_launcher_background.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 585 B

BIN
android/app/src/main/res/drawable-mdpi/ic_launcher_background.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 B

BIN
android/app/src/main/res/drawable-xhdpi/ic_launcher_background.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 851 B

BIN
android/app/src/main/res/drawable-xxhdpi/ic_launcher_background.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
android/app/src/main/res/drawable-xxxhdpi/ic_launcher_background.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

2
android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

BIN
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 22 KiB

4
android/app/src/main/res/values/colors.xml

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#ffffff</color>
</resources>

BIN
assets/img/logo_siopas_apps.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
assets/img/putih.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 KiB

After

Width:  |  Height:  |  Size: 259 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 869 B

After

Width:  |  Height:  |  Size: 725 B

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 10 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 10 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 20 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 15 KiB

BIN
ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 18 KiB

8
lib/migrations/databasehelper.dart

@ -196,22 +196,14 @@ class SqfliteDatabaseHelper {
await db.execute("""
CREATE TABLE $petiTable (
id INTEGER PRIMARY KEY AUTOINCREMENT,
tipe_peti_id INTEGER NULL,
warna TEXT NULL,
fix_lot TEXT NULL,
packing_no INTEGER NULL,
customer_id INTEGER NULL,
jumlah INTEGER NULL,
date_pembuatan DATETIME NULL,
warehouse_id INTEGER NULL,
kondisipeti_id INTEGER NULL,
status TEXT NULL,
created_at TIMESTAMP NULL,
updated_at TIMESTAMP NULL,
deleted_at TIMESTAMP NULL,
created_by TEXT NULL,
updated_by TEXT NULL,
FOREIGN KEY (tipe_peti_id) REFERENCES $typePetiTable(id),
FOREIGN KEY (customer_id) REFERENCES $customerTable(id),
FOREIGN KEY (warehouse_id) REFERENCES $warehouseTable(id)
);

19
lib/models/m_asset_status_model.dart

@ -14,9 +14,6 @@ class PetiAssetModel {
int? warehouse_id;
int? kondisipeti_id;
String? status;
// WarehouseModel? warehouse;
// TypePetiModel? tipe_peti;
// CustomerModel? customer;
String? created_by;
String? updated_by;
@ -33,9 +30,6 @@ class PetiAssetModel {
this.customer_id,
this.jumlah,
this.date_pembuatan,
// this.warehouse,
// this.tipe_peti,
// this.customer,
this.warehouse_id,
this.kondisipeti_id,
this.status,
@ -44,7 +38,6 @@ class PetiAssetModel {
this.created_at,
this.updated_at,
this.deleted_at,
// required this.warehouse,
});
factory PetiAssetModel.fromJson(Map<String, dynamic> json) {
@ -73,15 +66,6 @@ class PetiAssetModel {
date_pembuatan: json['date_pembuatan'] != null
? DateTime.parse(json['date_pembuatan'].toString())
: null,
// warehouse: json['warehouse'] != null
// ? WarehouseModel.fromJson(json['warehouse'])
// : null,
// tipe_peti: json['tipe_peti'] != null
// ? TypePetiModel.fromJson(json['tipe_peti'])
// : null,
// customer: json['customer'] != null
// ? CustomerModel.fromJson(json['customer'])
// : null,
created_by: json['created_by'] != null
? json['created_by'].toString()
: json['created_by'],
@ -112,9 +96,6 @@ class PetiAssetModel {
'status': status,
'jumlah': jumlah,
'date_pembuatan': date_pembuatan!.toIso8601String(),
// 'warehouse': warehouse != null ? warehouse!.toJson() : null,
// 'customer': customer != null ? customer!.toJson() : null,
// 'tipe_peti': tipe_peti != null ? tipe_peti!.toJson() : null,
'created_by': created_by,
'updated_by': updated_by,
'created_at': created_at!.toIso8601String(),

43
lib/pages/home/home_page.dart

@ -53,25 +53,34 @@ class _HomePageState extends State<HomePage> {
List<TypePetiModel>? _tipePetiData;
List<CustomerModel>? _customerData;
List<WarehouseModel>? _warehouseData;
bool _isLoading = false;
Timer? _timer;
bool _isLoading = true;
@override
void initState() {
super.initState();
_getUserToken();
warehouseListAPI();
typePetiListAPI();
customerListAPI();
petiListAPI();
// Tampil data Datatables
datatablesAssetStatusList();
datatablesPetiList();
datatablesTipePetiList();
datatablesCustomerList();
datatablesWarehouseList();
// Menerapkan Future untuk menangani tugas asinkronus
Future.wait([
warehouseListAPI(),
typePetiListAPI(),
customerListAPI(),
petiListAPI(),
datatablesAssetStatusList(),
datatablesPetiList(),
datatablesTipePetiList(),
datatablesCustomerList(),
datatablesWarehouseList(),
]).then((_) {
// Selesaikan loading setelah semua tugas selesai
setState(() {
_isLoading = false;
});
});
// Inisialisasi _data di sini jika diperlukan
_data = <AssetStatusModel>[];
}
@ -152,10 +161,16 @@ class _HomePageState extends State<HomePage> {
EasyLoading.show(status: 'Mengambil data Peti...');
List<PetiAssetModel> petiApiData =
await SyncronizationDataAPI().fetchPetiFromApi();
await ControllerApi()
.deleteAllPetiDataAPI(); // Clear existing data in SQLite
await ControllerApi()
.addAllPetiDataAPI(petiApiData); // Add new data to SQLite
// Menentukan ukuran chunk, misalnya 100
int chunkSize = 100;
// Memasukkan data ke SQLite dengan menggunakan chunk
await ControllerApi().addAllPetiDataAPI(petiApiData, chunkSize);
EasyLoading.dismiss();
}

68
lib/pages/home/setting_page.dart

@ -43,23 +43,75 @@ class SettingPageState extends State<SettingPage> {
bool? confirm = await showDialog<bool>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Konfirmasi Logout'),
content: Text('Apakah Anda yakin ingin logout?'),
actions: <Widget>[
TextButton(
child: Text('Tidak'),
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.0),
),
elevation: 0,
backgroundColor: Colors.transparent,
child: Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Colors.white,
borderRadius: BorderRadius.circular(16.0),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Konfirmasi Keluar Akun',
style: TextStyle(
fontSize: 16, fontWeight: FontWeight.w600),
),
IconButton(
icon: Icon(Icons.close),
onPressed: () {
Navigator.of(context).pop(false);
},
),
TextButton(
child: Text('Ya'),
],
),
Divider(
height: 10,
thickness: 5,
),
SizedBox(
height: 15,
),
Text(
'Apakah Anda yakin ingin keluar akun?',
style: TextStyle(fontSize: 14),
textAlign: TextAlign.center,
),
SizedBox(
height: 22,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(width: 16),
TextButton.icon(
onPressed: () {
Navigator.of(context).pop(true);
},
icon: Icon(
Icons.exit_to_app,
color: Colors.red,
),
label: Text(
'Keluar',
style: TextStyle(color: Colors.red),
),
),
],
),
],
),
),
);
},
);

101
lib/pages/peminjaman_barang/conn/syncronize.dart

@ -83,9 +83,69 @@ class SyncronizationPeminjamanData {
await dbClient!.delete(SqfliteDatabaseHelper.peminjamanTable);
}
Future saveToPeminjamanWith(
// Future saveToPeminjamanWith(
// List<AssetStatusModel> assetStatusesLocalList) async {
// for (var i = 0; i < assetStatusesLocalList.length; i++) {
// 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;
// }
// }
// // Format tanggal sesuai kebutuhan
// String formattedCreatedAt = assetStatusesLocalList[i].created_at != null
// ? DateFormat('yyyy-MM-dd HH:mm:ss.SSS')
// .format(assetStatusesLocalList[i].created_at!)
// : DateFormat('yyyy-MM-dd HH:mm:ss.SSS').format(DateTime.now());
// Map<String, dynamic> data = {
// "mobile_id": assetStatusesLocalList[i].mobile_id.toString(),
// "peti_id": assetStatusesLocalList[i].peti_id.toString(),
// "customer_id": assetStatusesLocalList[i].customer_id.toString(),
// "warehouse_id": assetStatusesLocalList[i].warehouse_id.toString(),
// "exit_at": assetStatusesLocalList[i].exit_at.toString(),
// "est_pengembalian":
// assetStatusesLocalList[i].est_pengembalian.toString(),
// "exit_pic": assetStatusesLocalList[i].exit_pic.toString(),
// "exit_warehouse": assetStatusesLocalList[i].exit_warehouse.toString(),
// "created_by": assetStatusesLocalList[i].created_by.toString(),
// "created_at": formattedCreatedAt,
// };
// final response = await http.post(
// Uri.parse(await getBaseUrl() + '/asset-status/store'),
// body: data,
// );
// if (response.statusCode == 200) {
// // print("Data uploaded successfully for index $i:");
// // print("Response body: ${response.body}");
// print("Saving Data saveToMysqlWith");
// } else {
// print(
// "Failed to upload data for index $i. Status code: ${response.statusCode}");
// print("Response body: ${response.body}");
// }
// }
// return true; // Pengunggahan berhasil
// }
Future<bool> saveToPeminjamanWith(
List<AssetStatusModel> assetStatusesLocalList) async {
for (var i = 0; i < assetStatusesLocalList.length; i++) {
const maxRequestsBeforeDelay = 25;
const delayDuration = Duration(seconds: 3);
int requestCounter = 0;
await Future.forEach(assetStatusesLocalList, (assetStatus) async {
DateTime? parseDateTime(String? dateTimeString) {
if (dateTimeString == null || dateTimeString.isEmpty) {
return null;
@ -100,22 +160,21 @@ class SyncronizationPeminjamanData {
}
// Format tanggal sesuai kebutuhan
String formattedCreatedAt = assetStatusesLocalList[i].created_at != null
String formattedCreatedAt = assetStatus.created_at != null
? DateFormat('yyyy-MM-dd HH:mm:ss.SSS')
.format(assetStatusesLocalList[i].created_at!)
.format(assetStatus.created_at!)
: DateFormat('yyyy-MM-dd HH:mm:ss.SSS').format(DateTime.now());
Map<String, dynamic> data = {
"mobile_id": assetStatusesLocalList[i].mobile_id.toString(),
"peti_id": assetStatusesLocalList[i].peti_id.toString(),
"customer_id": assetStatusesLocalList[i].customer_id.toString(),
"warehouse_id": assetStatusesLocalList[i].warehouse_id.toString(),
"exit_at": assetStatusesLocalList[i].exit_at.toString(),
"est_pengembalian":
assetStatusesLocalList[i].est_pengembalian.toString(),
"exit_pic": assetStatusesLocalList[i].exit_pic.toString(),
"exit_warehouse": assetStatusesLocalList[i].exit_warehouse.toString(),
"created_by": assetStatusesLocalList[i].created_by.toString(),
"mobile_id": assetStatus.mobile_id.toString(),
"peti_id": assetStatus.peti_id.toString(),
"customer_id": assetStatus.customer_id.toString(),
"warehouse_id": assetStatus.warehouse_id.toString(),
"exit_at": assetStatus.exit_at.toString(),
"est_pengembalian": assetStatus.est_pengembalian.toString(),
"exit_pic": assetStatus.exit_pic.toString(),
"exit_warehouse": assetStatus.exit_warehouse.toString(),
"created_by": assetStatus.created_by.toString(),
"created_at": formattedCreatedAt,
};
@ -125,15 +184,21 @@ class SyncronizationPeminjamanData {
);
if (response.statusCode == 200) {
// print("Data uploaded successfully for index $i:");
// print("Response body: ${response.body}");
print("Saving Data saveToMysqlWith");
} else {
print(
"Failed to upload data for index $i. Status code: ${response.statusCode}");
print("Failed to upload data. Status code: ${response.statusCode}");
print("Response body: ${response.body}");
}
// Increment counter
requestCounter++;
// Jeda 2 detik setiap 30 permintaan
if (requestCounter % maxRequestsBeforeDelay == 0 &&
requestCounter != assetStatusesLocalList.length) {
await Future.delayed(delayDuration);
}
});
return true; // Pengunggahan berhasil
}

14
lib/pages/peminjaman_barang/controller/peminjaman_controller.dart

@ -108,6 +108,20 @@ class Controller {
return peminjamanList;
}
Future<void> deletePeminjamanById(String id) async {
var dbclient = await conn.db;
try {
await dbclient!.delete(
SqfliteDatabaseHelper.peminjamanTable,
where: 'id = ?',
whereArgs: [id],
);
} catch (e) {
print('Gagal menghapus peminjaman dari database: $e');
throw Exception('Gagal menghapus peminjaman');
}
}
Future<void> deleteAllData() async {
var dbClient = await conn.db;
await dbClient!.delete(SqfliteDatabaseHelper.peminjamanTable);

429
lib/pages/peminjaman_barang/create.dart

@ -19,6 +19,7 @@ import 'package:siopas/models/warehouse_mode.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:intl/date_symbol_data_local.dart'; // Import package intl
import 'package:uuid/uuid.dart';
import 'package:dropdown_search/dropdown_search.dart';
import '../../connection/connection.dart';
import 'package:http/http.dart' as http;
@ -58,7 +59,10 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
List<PetiAssetModel> _filteredPetiList = [];
bool isQRCodeScanned = false;
bool loading = true;
String searchText = '';
PetiAssetModel? selectedPeti;
TextEditingController searchBoxController = TextEditingController();
TextEditingController _exit_atController = TextEditingController();
TextEditingController _est_pengembalianController = TextEditingController();
TextEditingController _penanggungJawabController = TextEditingController();
@ -68,6 +72,8 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
Barcode? result;
QRViewController? controller;
bool loading = true;
@override
void initState() {
super.initState();
@ -76,8 +82,11 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
petiListAPI();
disposalListAPI();
customerListAPI();
initializeDateFormatting('id_ID', null);
setState(() {
loading = false; // Mengatur loading ke false setelah tugas selesai
});
}
void _getUserToken() async {
@ -537,7 +546,7 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
automaticallyImplyLeading: false,
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text('Buat Peminjaman Barang',
title: Text('Buat Peminjaman Peti',
style: TextStyle(
fontSize: 16,
)),
@ -558,73 +567,98 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
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: petiSqfliteApi,
// items: (_valpeti ?? [])
// .where((peti) =>
// peti.deleted_at != true &&
// (peti.warehouse_id ==
// user.warehouse_id) &&
// (peti.status == 'AKTIF'))
// .map((PetiAssetModel peti) {
// return DropdownMenuItem<PetiAssetModel>(
// child: Text(
// '${peti.fix_lot}', // Menampilkan warehouse_id
// style: TextStyle(
// fontSize: 12,
// ),
// ),
// value: peti,
// );
// }).toList(),
// 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,
// );
// }
// },
// );
// },
// ),
DropdownButtonFormField<PetiAssetModel>(
validator: (value) {
if (value == null) {
return 'Harus diisi';
child: DropdownSearch<PetiAssetModel>(
popupProps: PopupProps.bottomSheet(
showSearchBox: true,
itemBuilder: (context, PetiAssetModel? peti,
bool? isSelected) {
if (peti == null) {
return SizedBox.shrink();
}
return null;
// 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,
);
},
decoration: InputDecoration(
labelText: 'Peti',
border: OutlineInputBorder(),
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);
},
),
],
),
hint: Text("Pilih Peti"),
value: petiSqfliteApi,
Divider(),
],
),
),
),
dropdownDecoratorProps:
DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
labelText: 'Pilih Peti',
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(5.0),
),
),
),
),
items: (isQRCodeScanned
? _filteredPetiList
: (_valpeti ?? []).where((peti) =>
@ -632,32 +666,31 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
(peti.warehouse_id ==
user.warehouse_id) &&
(peti.status == 'AKTIF')))
.map((PetiAssetModel peti) {
return DropdownMenuItem<PetiAssetModel>(
child: Text(
'${peti.fix_lot}',
style: TextStyle(
fontSize: 12,
),
),
value: peti,
);
}).toList(),
.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) =>
warehouseSqfliteApi = _valwarehouse
?.firstWhere((warehouse) =>
warehouse.id ==
value.warehouse_id,
);
customerSqfliteApi =
_valcustomer?.firstWhereOrNull(
(customer) =>
customer.id == value.customer_id,
);
value.warehouse_id);
customerSqfliteApi = _valcustomer
?.firstWhereOrNull((customer) =>
customer.id ==
value.customer_id);
// Perbarui _unrestrictedPetiList sesuai pemilihan manual
_unrestrictedPetiList = [
@ -667,6 +700,12 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
}
});
},
validator: (PetiAssetModel? value) {
if (value == null) {
return 'Harus diisi';
}
return null;
},
),
),
),
@ -751,39 +790,112 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
elevation: 2,
child: Padding(
padding: const EdgeInsets.all(8),
child: DropdownButtonFormField<CustomerModel>(
validator: (value) {
if (value == null) {
return 'Harus diisi';
}
return null;
},
decoration: InputDecoration(
labelText: 'Customer',
border: OutlineInputBorder(),
child: DropdownSearch<CustomerModel>(
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
labelText: 'Pilih Customer',
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(5.0),
),
hint: Text("Pilih Customer"),
value: customerSqfliteApi,
items: (_valcustomer ?? [])
.where(
(customer) => customer.deleted_at != true)
.map((CustomerModel customer) {
return DropdownMenuItem<CustomerModel>(
child: Text(
'${customer.name}', // Menampilkan warehouse_id
),
),
),
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: 12,
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)
),
value: customer,
],
),
color: customer.id == customerSqfliteApi?.id
? Colors.grey.withOpacity(0.7)
: Colors.white,
);
}).toList(),
},
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(
() {
setState(() {
customerSqfliteApi = value;
});
},
);
validator: (CustomerModel? value) {
if (value == null) {
return 'Harus diisi';
}
return null;
},
),
),
@ -794,6 +906,28 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
child: Padding(
padding: const EdgeInsets.all(8),
child: FormBuilderDateTimePicker(
validator: (value) {
if (_exit_atController.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent[700],
content: Row(
children: [
Icon(
Icons.error_outline,
color: Colors.white,
),
SizedBox(width: 5),
Text('Tanggal Peminjaman harus diisi'),
],
),
duration: Duration(seconds: 2),
),
);
return null; // Return null jika ada kesalahan
}
return null; // Return null jika tidak ada kesalahan
},
controller: _exit_atController,
name: 'tanggal_peminjaman',
inputType: InputType.date,
@ -840,6 +974,30 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
Padding(
padding: const EdgeInsets.all(8),
child: FormBuilderDateTimePicker(
validator: (value) {
if (_est_pengembalianController
.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent[700],
content: Row(
children: [
Icon(
Icons.error_outline,
color: Colors.white,
),
SizedBox(width: 5),
Text(
'Tanggal Estimasi Pengembalian harus diisi'),
],
),
duration: Duration(seconds: 2),
),
);
return null; // Return null jika ada kesalahan
}
return null; // Return null jika tidak ada kesalahan
},
controller: _est_pengembalianController,
name: 'estimasi_pengembalian',
inputType: InputType.date,
@ -899,7 +1057,27 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
// _valwarehouse?.map((WarehouseModel warehouse)
{
return DropdownMenuItem<WarehouseModel>(
child: Text('${warehouse.name}'),
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() ??
@ -936,7 +1114,27 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
// _valwarehouse?.map((WarehouseModel warehouse)
{
return DropdownMenuItem<WarehouseModel>(
child: Text('${warehouseTujuan.name}'),
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() ??
@ -974,7 +1172,6 @@ class _CreatePeminjamanBarangState extends State<CreatePeminjamanBarang> {
),
child: IconButton(
onPressed: () {
// Navigator.pop(context);
Navigator.pushNamed(context, '/peminjaman-barang');
},
icon: Icon(Icons.close, color: Colors.white),

78
lib/pages/peminjaman_barang/peminjaman_stock_page.dart

@ -19,6 +19,7 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:siopas/models/asset_status_model.dart';
import 'package:siopas/providers/asset_status_provider.dart';
import 'package:collection/collection.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../models/condition_peti_model.dart';
import 'show.dart';
@ -54,26 +55,38 @@ class AssetStatusPageState extends State<AssetStatusPage> {
List<CustomerModel>? _customerData;
List<WarehouseModel>? _warehouseData;
bool _isLoading = false;
Timer? _timer;
bool _isLoading = false;
@override
void initState() {
super.initState();
_getUserToken();
warehouseListAPI();
typePetiListAPI();
customerListAPI();
petiListAPI();
// disposalListAPI();
// Mengatur _isLoading ke true sebelum tugas dimulai
setState(() {
_isLoading = true;
});
// Tampil data Datatables
datatablesAssetStatusList();
datatablesPetiList();
datatablesTipePetiList();
datatablesCustomerList();
datatablesWarehouseList();
Future.wait([
warehouseListAPI(),
typePetiListAPI(),
customerListAPI(),
petiListAPI(),
datatablesAssetStatusList(),
datatablesPetiList(),
datatablesTipePetiList(),
datatablesCustomerList(),
datatablesWarehouseList(),
]).then((_) {
// Mengatur _isLoading ke false setelah semua tugas selesai
setState(() {
_isLoading = false;
});
});
// Inisialisasi _data di sini jika diperlukan
_data = <AssetStatusModel>[];
}
@ -152,16 +165,16 @@ class AssetStatusPageState extends State<AssetStatusPage> {
}
}
Future<void> reinitAssetStatusApi() async {
EasyLoading.show(status: 'Mengambil data Asset Status...');
List<AssetStatusModel> assetStatusApiData =
await SyncronizationDataAPI().fetchAssetStatusFromApi();
await ControllerApi()
.deleteAllAssetStatusDataAPI(); // Clear existing data in SQLite
await ControllerApi()
.addAllAssetStatusDataAPI(assetStatusApiData); // Add new data to SQLite
EasyLoading.dismiss();
}
// Future<void> reinitAssetStatusApi() async {
// EasyLoading.show(status: 'Mengambil data Asset Status...');
// List<AssetStatusModel> assetStatusApiData =
// await SyncronizationDataAPI().fetchAssetStatusFromApi();
// await ControllerApi()
// .deleteAllAssetStatusDataAPI(); // Clear existing data in SQLite
// await ControllerApi()
// .addAllAssetStatusDataAPI(assetStatusApiData); // Add new data to SQLite
// EasyLoading.dismiss();
// }
Future<void> reinitWarehouseApi() async {
EasyLoading.show(status: 'Mengambil data Warehouse...');
@ -178,10 +191,16 @@ class AssetStatusPageState extends State<AssetStatusPage> {
EasyLoading.show(status: 'Mengambil data Peti...');
List<PetiAssetModel> petiApiData =
await SyncronizationDataAPI().fetchPetiFromApi();
await ControllerApi()
.deleteAllPetiDataAPI(); // Clear existing data in SQLite
await ControllerApi()
.addAllPetiDataAPI(petiApiData); // Add new data to SQLite
// Menentukan ukuran chunk, misalnya 100
int chunkSize = 100;
// Memasukkan data ke SQLite dengan menggunakan chunk
await ControllerApi().addAllPetiDataAPI(petiApiData, chunkSize);
EasyLoading.dismiss();
}
@ -257,7 +276,7 @@ class AssetStatusPageState extends State<AssetStatusPage> {
.then((peminjamanList) async {
EasyLoading.show(
status: 'Jangan tutup aplikasi. Kami sedang menyinkronkan...');
await Future.delayed(Duration(seconds: 3));
await Future.delayed(Duration(seconds: 2));
// Tambahkan penanganan pengunggahan
bool uploadSuccess = await SyncronizationPeminjamanData()
@ -475,7 +494,7 @@ class AssetStatusPageState extends State<AssetStatusPage> {
appBar: AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text('Data Peminjaman Barang',
title: Text('Data Peminjaman Peti',
style: TextStyle(
fontSize: 16,
)),
@ -508,7 +527,12 @@ class AssetStatusPageState extends State<AssetStatusPage> {
),
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
? Center(
child: LoadingAnimationWidget.staggeredDotsWave(
color: Colors.indigo,
size: 40,
),
)
: TabBarView(
children: [
SingleChildScrollView(

117
lib/pages/peminjaman_barang/show.dart

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:siopas/models/asset_status_model.dart';
import 'package:siopas/models/customer_model.dart';
import 'package:siopas/models/m_asset_status_model.dart';
@ -40,6 +41,9 @@ class _DetailPeminjamanBarangPageState
petiListAPI();
warehouseListAPI();
initializeDateFormatting('id_ID', null);
setState(() {
loading = false;
});
}
Future customerListAPI() async {
@ -102,6 +106,18 @@ class _DetailPeminjamanBarangPageState
}
}
Future<void> _deletePeminjaman() async {
try {
// Panggil fungsi untuk menghapus peminjaman berdasarkan ID
await Controller().deletePeminjamanById(widget.peminjamanId);
// Navigasi kembali ke halaman sebelumnya atau halaman yang sesuai
Navigator.pushNamed(context, '/peminjaman-barang');
} catch (e) {
// Tangani kesalahan jika terjadi
print('Gagal menghapus peminjaman: $e');
}
}
@override
Widget build(BuildContext context) {
PetiAssetModel? petiSqfliteApi;
@ -116,20 +132,92 @@ class _DetailPeminjamanBarangPageState
WarehouseModel? warehouseSqfliteApi;
warehouseSqfliteApi = warehouseData?.firstWhereOrNull(
(warehouse) => warehouse.id == peminjamanInfo!.exit_warehouse,
(warehouse) => warehouse.id == peminjamanInfo!.warehouse_id,
);
WarehouseModel? warehouseTujuanSqfliteApi;
warehouseTujuanSqfliteApi = warehouseData?.firstWhereOrNull(
(warehouse) => warehouse.id == peminjamanInfo!.exit_warehouse,
);
Future<void> _showDeleteConfirmationDialog() async {
return showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.0),
),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Icon(
Icons.info,
color: Colors.blue,
),
SizedBox(width: 8),
Text(
'Konfirmasi Hapus',
style: TextStyle(
fontSize: 18,
),
),
],
),
IconButton(
icon: Icon(
Icons.close,
color: Colors.black54,
),
onPressed: () {
Navigator.of(context).pop();
},
),
],
),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text(
'Anda yakin ingin menghapus pengembalian ini? ${petiSqfliteApi!.fix_lot.toString()}',
style: TextStyle(
fontSize: 16,
),
),
],
),
),
actions: <Widget>[
Container(
margin: EdgeInsets.only(right: 3.0),
child: ElevatedButton(
child: Text('Hapus'),
onPressed: () {
// Panggil fungsi untuk menghapus peminjaman berdasarkan ID
_deletePeminjaman();
Navigator.pushNamed(context, '/peminjaman-barang');
EasyLoading.showSuccess(
'Berhasil menghapus data peminjaman');
},
style: ElevatedButton.styleFrom(
primary: Colors.red,
),
),
),
],
);
},
);
}
return Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text(
'Detail Peminjaman Barang',
'Detail Peminjaman Peti',
style: TextStyle(
color: Colors.white,
fontSize: 16,
@ -141,6 +229,14 @@ class _DetailPeminjamanBarangPageState
Navigator.pushNamed(context, '/peminjaman-barang');
},
),
actions: [
IconButton(
icon: Icon(Icons.delete, color: Colors.redAccent),
onPressed: () {
_showDeleteConfirmationDialog();
},
),
],
),
body: Padding(
padding: EdgeInsets.all(16.0),
@ -225,7 +321,7 @@ class _DetailPeminjamanBarangPageState
'PJ Peminjaman', peminjamanInfo!.exit_pic.toString()),
Divider(thickness: 1),
_buildDetailItem(
'Asal Warehouse',
'Asal Gudang',
// peminjamanInfo!.exit_warehouse.toString()),
warehouseSqfliteApi != null &&
warehouseSqfliteApi.name != null
@ -233,11 +329,11 @@ class _DetailPeminjamanBarangPageState
: '-'),
Divider(thickness: 1),
_buildDetailItem(
'Exit Warehouse',
'Tujuan Gudang',
// peminjamanInfo!.exit_warehouse.toString()),
warehouseSqfliteApi != null &&
warehouseSqfliteApi.name != null
? warehouseSqfliteApi!.name.toString()
warehouseTujuanSqfliteApi != null &&
warehouseTujuanSqfliteApi.name != null
? warehouseTujuanSqfliteApi!.name.toString()
: '-'),
Divider(thickness: 1),
// ... tambahkan data lainnya sesuai kebutuhan
@ -257,9 +353,12 @@ class _DetailPeminjamanBarangPageState
children: [
Text(
label,
style: TextStyle(fontSize: 12.5, fontWeight: FontWeight.bold),
style: TextStyle(fontSize: 12, fontWeight: FontWeight.bold),
),
Text(
value,
style: TextStyle(fontSize: 12),
),
Text(value),
],
),
);

90
lib/pages/pengembalian_barang/conn/syncronize.dart

@ -84,9 +84,65 @@ class SyncronizationPengembalianData {
await dbClient!.delete(SqfliteDatabaseHelper.pengembalianTable);
}
Future savePengembalianToServerWith(
// Future savePengembalianToServerWith(
// List<AssetStatusModel> assetStatusesLocalList) async {
// for (var i = 0; i < assetStatusesLocalList.length; i++) {
// 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;
// }
// }
// // Format tanggal sesuai kebutuhan
// String formattedCreatedAt = assetStatusesLocalList[i].created_at != null
// ? DateFormat('yyyy-MM-dd HH:mm:ss.SSS')
// .format(assetStatusesLocalList[i].created_at!)
// : DateFormat('yyyy-MM-dd HH:mm:ss.SSS').format(DateTime.now());
// Map<String, dynamic> data = {
// "peti_id": assetStatusesLocalList[i].peti_id.toString(),
// "enter_at": assetStatusesLocalList[i].enter_at.toString(),
// "enter_pic": assetStatusesLocalList[i].enter_pic.toString(),
// "enter_warehouse": assetStatusesLocalList[i].enter_warehouse.toString(),
// "kondisi_peti_id": assetStatusesLocalList[i].kondisi_peti_id.toString(),
// "updated_by": assetStatusesLocalList[i].updated_by.toString(),
// "updated_at": formattedCreatedAt,
// };
// final response = await http.post(
// Uri.parse(await getBaseUrl() + '/asset-status/update'),
// body: data,
// );
// if (response.statusCode == 200) {
// // print("Data uploaded successfully for index $i:");
// // print("Response body: ${response.body}");
// print("Saving Data saveToPengembalianWith");
// } else {
// print(
// "Failed to upload data for index $i. Status code: ${response.statusCode}");
// print("Response body: ${response.body}");
// }
// }
// return true; // Pengunggahan berhasil
// }
Future<bool> savePengembalianToServerWith(
List<AssetStatusModel> assetStatusesLocalList) async {
for (var i = 0; i < assetStatusesLocalList.length; i++) {
const maxRequestsBeforeDelay = 25;
const delayDuration = Duration(seconds: 3);
int requestCounter = 0;
await Future.forEach(assetStatusesLocalList, (assetStatus) async {
DateTime? parseDateTime(String? dateTimeString) {
if (dateTimeString == null || dateTimeString.isEmpty) {
return null;
@ -101,18 +157,18 @@ class SyncronizationPengembalianData {
}
// Format tanggal sesuai kebutuhan
String formattedCreatedAt = assetStatusesLocalList[i].created_at != null
String formattedCreatedAt = assetStatus.created_at != null
? DateFormat('yyyy-MM-dd HH:mm:ss.SSS')
.format(assetStatusesLocalList[i].created_at!)
.format(assetStatus.created_at!)
: DateFormat('yyyy-MM-dd HH:mm:ss.SSS').format(DateTime.now());
Map<String, dynamic> data = {
"peti_id": assetStatusesLocalList[i].peti_id.toString(),
"enter_at": assetStatusesLocalList[i].enter_at.toString(),
"enter_pic": assetStatusesLocalList[i].enter_pic.toString(),
"enter_warehouse": assetStatusesLocalList[i].enter_warehouse.toString(),
"kondisi_peti_id": assetStatusesLocalList[i].kondisi_peti_id.toString(),
"updated_by": assetStatusesLocalList[i].updated_by.toString(),
"peti_id": assetStatus.peti_id.toString(),
"enter_at": assetStatus.enter_at.toString(),
"enter_pic": assetStatus.enter_pic.toString(),
"enter_warehouse": assetStatus.enter_warehouse.toString(),
"kondisi_peti_id": assetStatus.kondisi_peti_id.toString(),
"updated_by": assetStatus.updated_by.toString(),
"updated_at": formattedCreatedAt,
};
@ -122,15 +178,21 @@ class SyncronizationPengembalianData {
);
if (response.statusCode == 200) {
// print("Data uploaded successfully for index $i:");
// print("Response body: ${response.body}");
print("Saving Data saveToPengembalianWith");
} else {
print(
"Failed to upload data for index $i. Status code: ${response.statusCode}");
print("Failed to upload data. Status code: ${response.statusCode}");
print("Response body: ${response.body}");
}
// Increment counter
requestCounter++;
// Jeda 3 detik setiap 25 permintaan
if (requestCounter % maxRequestsBeforeDelay == 0 &&
requestCounter != assetStatusesLocalList.length) {
await Future.delayed(delayDuration);
}
});
return true; // Pengunggahan berhasil
}

14
lib/pages/pengembalian_barang/controller/pengembalian_controller.dart

@ -110,6 +110,20 @@ class ControllerPengembalian {
return pengembalianList;
}
Future<void> deletePengembalianById(String id) async {
var dbclient = await conn.db;
try {
await dbclient!.delete(
SqfliteDatabaseHelper.pengembalianTable,
where: 'id = ?',
whereArgs: [id],
);
} catch (e) {
print('Gagal menghapus pengembalian dari database: $e');
throw Exception('Gagal menghapus pengembalian');
}
}
Future<void> deleteAllData() async {
var dbClient = await conn.db;
await dbClient!.delete(SqfliteDatabaseHelper.pengembalianTable);

207
lib/pages/pengembalian_barang/edit.dart

@ -20,6 +20,7 @@ import 'package:siopas/models/warehouse_mode.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:intl/date_symbol_data_local.dart'; // Import package intl
import 'package:uuid/uuid.dart';
import 'package:dropdown_search/dropdown_search.dart';
import '../../connection/connection.dart';
import 'package:http/http.dart' as http;
@ -63,7 +64,8 @@ class _CreatePengembalianBarangPageState
List<PetiAssetModel> _filteredPetiList = [];
bool isQRCodeScanned = false;
bool loading = true;
TextEditingController searchBoxController = TextEditingController();
TextEditingController _enterAtController = TextEditingController();
// TextEditingController _enterPicController = TextEditingController();
// TextEditingController _kondisiPetiController = TextEditingController();
@ -74,19 +76,23 @@ class _CreatePengembalianBarangPageState
Barcode? result;
QRViewController? controller;
bool loading = true;
@override
void initState() {
super.initState();
_getUserToken();
warehouseListAPI();
datatablesAssetStatusList();
// typePetiListAPI();
// customerListAPI();
petiListAPI();
kondisiPetiListAPI();
initializeDateFormatting('id_ID', null);
setState(() {
loading = false; // Mengatur loading ke false setelah tugas selesai
});
}
void _getUserToken() async {
@ -389,7 +395,7 @@ class _CreatePengembalianBarangPageState
automaticallyImplyLeading: false,
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text('Buat Pengembalian barang',
title: Text('Buat Pengembalian Peti',
style: TextStyle(
fontSize: 16,
)),
@ -410,19 +416,98 @@ class _CreatePengembalianBarangPageState
elevation: 2,
child: Container(
margin: EdgeInsets.all(8),
child: DropdownButtonFormField<PetiAssetModel>(
validator: (value) {
if (value == null) {
return 'Harus diisi';
}
return null;
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,
);
},
decoration: InputDecoration(
labelText: 'Peti',
border: OutlineInputBorder(),
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(),
],
),
hint: Text("Pilih Peti"),
value: petiSqfliteApi,
),
),
dropdownDecoratorProps:
DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
labelText: 'Pilih Peti',
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(5.0),
),
),
),
),
items: (isQRCodeScanned
? _filteredPetiList
: (_valpeti ?? []).where((peti) =>
@ -430,28 +515,23 @@ class _CreatePengembalianBarangPageState
(peti.warehouse_id ==
user.warehouse_id) &&
(peti.status == 'AKTIF')))
.map((PetiAssetModel peti) {
return DropdownMenuItem<PetiAssetModel>(
child: Text(
'${peti.fix_lot}',
style: TextStyle(
fontSize: 12,
),
),
value: peti,
);
}).toList(),
.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,
);
// Perbarui _unrestrictedPetiList sesuai pemilihan manual
_unrestrictedPetiList = [
_valpeti!.firstWhere(
@ -460,6 +540,12 @@ class _CreatePengembalianBarangPageState
}
});
},
validator: (PetiAssetModel? value) {
if (value == null) {
return 'Harus diisi';
}
return null;
},
),
),
),
@ -595,17 +681,39 @@ class _CreatePengembalianBarangPageState
return null;
},
decoration: InputDecoration(
labelText: 'Pilih Gudang',
labelText: 'Gudang Pengembalian',
border: OutlineInputBorder(),
),
hint: Text("Pilih Gudang"),
hint: Text("Gudang Pengembalian"),
value: warehouseSqfliteApi,
items: (_valwarehouse ?? [])
.where((warehouse) =>
warehouse.deleted_at != true)
.map((WarehouseModel warehouse) {
.map((WarehouseModel warehouse)
// _valwarehouse?.map((WarehouseModel warehouse)
{
return DropdownMenuItem<WarehouseModel>(
child: Text('${warehouse.name}'),
child: Row(
children: [
Icon(
Icons.edit_location_alt,
color: warehouse.id ==
warehouseSqfliteApi?.id
? Colors.indigo[700]
: Colors.grey,
),
SizedBox(
width:
8), // Jarak antara ikon dan teks
Text(
'${warehouse.name}',
style: TextStyle(
fontSize: 16,
fontFamily: 'OpenSansCondensed',
),
),
],
),
value: warehouse,
);
}).toList() ??
@ -640,7 +748,30 @@ class _CreatePengembalianBarangPageState
(kondisi) => kondisi.deleted_at != true)
.map((ConditionPetiModel kondisi) {
return DropdownMenuItem<ConditionPetiModel>(
child: Text('${kondisi.nama_kondisi}'),
child: Row(
children: [
Icon(
kondisi.id ==
conditionPetiSqfliteApi?.id
? Icons.check_box
: Icons.check_box_outline_blank,
color: kondisi.id ==
conditionPetiSqfliteApi?.id
? Colors.teal[700]
: Colors.grey,
),
SizedBox(
width: 8,
),
Text(
'${kondisi.nama_kondisi}',
style: TextStyle(
fontSize: 16,
fontFamily: 'OpenSansCondensed',
),
),
],
),
value: kondisi,
);
}).toList() ??

61
lib/pages/pengembalian_barang/index.dart

@ -5,6 +5,7 @@ import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:data_table_2/data_table_2.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import 'package:siopas/models/condition_peti_model.dart';
import 'package:siopas/models/customer_model.dart';
import 'package:siopas/models/disposal_model.dart';
@ -58,28 +59,41 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
List<CustomerModel>? _customerData;
List<WarehouseModel>? _warehouseData;
List<ConditionPetiModel>? _conditionData;
bool _isLoading = false;
Timer? _timer;
bool _isLoading = false;
@override
void initState() {
super.initState();
_getUserToken();
warehouseListAPI();
conditionPetiListAPI();
typePetiListAPI();
customerListAPI();
petiListAPI();
// disposalListAPI();
// Set _isLoading ke true sebelum memulai tugas
setState(() {
_isLoading = true;
});
// Tampil data Datatables
datatablesPengembalianList();
datatablesPetiList();
datatablesTipePetiList();
datatablesCustomerList();
datatablesWarehouseList();
datatablesConditionList();
Future.wait([
warehouseListAPI(),
conditionPetiListAPI(),
typePetiListAPI(),
customerListAPI(),
petiListAPI(),
// disposalListAPI(),
datatablesPengembalianList(),
datatablesPetiList(),
datatablesTipePetiList(),
datatablesCustomerList(),
datatablesWarehouseList(),
datatablesConditionList(),
]).then((_) {
// Set _isLoading ke false setelah semua tugas selesai
setState(() {
_isLoading = false;
});
});
// Inisialisasi _data di sini jika diperlukan
_data = <AssetStatusModel>[];
}
@ -195,10 +209,16 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
EasyLoading.show(status: 'Mengambil data Peti...');
List<PetiAssetModel> petiApiData =
await SyncronizationDataAPI().fetchPetiFromApi();
await ControllerApi()
.deleteAllPetiDataAPI(); // Clear existing data in SQLite
await ControllerApi()
.addAllPetiDataAPI(petiApiData); // Add new data to SQLite
// Menentukan ukuran chunk, misalnya 100
int chunkSize = 100;
// Memasukkan data ke SQLite dengan menggunakan chunk
await ControllerApi().addAllPetiDataAPI(petiApiData, chunkSize);
EasyLoading.dismiss();
}
@ -491,7 +511,7 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
appBar: AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text('Data Pengembalian Barang',
title: Text('Data Pengembalian Peti',
style: TextStyle(
fontSize: 16,
)),
@ -524,7 +544,12 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
),
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
? Center(
child: LoadingAnimationWidget.staggeredDotsWave(
color: Colors.indigo,
size: 40,
),
)
: TabBarView(
children: [
SingleChildScrollView(

106
lib/pages/pengembalian_barang/show.dart

@ -1,4 +1,5 @@
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';
@ -37,12 +38,22 @@ class _DetailPengembalianBarangPageState
@override
void initState() {
super.initState();
// Pemanggilan fungsi-fungsi yang diperlukan
getPengembalianIdData();
customerListAPI();
petiListAPI();
warehouseListAPI();
kondisiPetiListAPI();
initializeDateFormatting('id_ID', null);
// Delay sejenak sebelum memanggil EasyLoading.dismiss()
Future.delayed(Duration(seconds: 1), () {
setState(() {
loading = false; // Mengatur loading ke false setelah tugas selesai
});
EasyLoading.dismiss();
});
}
Future customerListAPI() async {
@ -118,6 +129,19 @@ class _DetailPengembalianBarangPageState
}
}
Future<void> _deletePengembalian() async {
try {
// Panggil fungsi untuk menghapus peminjaman berdasarkan ID
await ControllerPengembalian()
.deletePengembalianById(widget.pengembalianId);
// Navigasi kembali ke halaman sebelumnya atau halaman yang sesuai
Navigator.pushNamed(context, '/pengembalian-barang');
} catch (e) {
// Tangani kesalahan jika terjadi
print('Gagal menghapus pengembalian: $e');
}
}
@override
Widget build(BuildContext context) {
PetiAssetModel? petiSqfliteApi;
@ -140,13 +164,85 @@ class _DetailPengembalianBarangPageState
(conditionPeti) => conditionPeti.id == pengembalianInfo!.kondisi_peti_id,
);
Future<void> _showDeleteConfirmationDialog() async {
return showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.0),
),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Icon(
Icons.info,
color: Colors.blue,
),
SizedBox(width: 8),
Text(
'Konfirmasi Hapus',
style: TextStyle(
fontSize: 18,
),
),
],
),
IconButton(
icon: Icon(
Icons.close,
color: Colors.black54,
),
onPressed: () {
Navigator.of(context).pop();
},
),
],
),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text(
'Anda yakin ingin menghapus pengembalian ini? ${petiSqfliteApi!.fix_lot.toString()}',
style: TextStyle(
fontSize: 16,
),
),
],
),
),
actions: <Widget>[
Container(
margin: EdgeInsets.only(right: 3.0),
child: ElevatedButton(
child: Text('Hapus'),
onPressed: () {
// Panggil fungsi untuk menghapus peminjaman berdasarkan ID
_deletePengembalian();
Navigator.pushNamed(context, '/pengembalian-barang');
EasyLoading.showSuccess(
'Berhasil menghapus data pengembalian');
},
style: ElevatedButton.styleFrom(
primary: Colors.red,
),
),
),
],
);
},
);
}
return Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text(
'Detail Pengembalian Barang',
'Detail Pengembalian Peti',
style: TextStyle(
color: Colors.white,
fontSize: 16,
@ -158,6 +254,14 @@ class _DetailPengembalianBarangPageState
Navigator.pushNamed(context, '/pengembalian-barang');
},
),
actions: [
IconButton(
icon: Icon(Icons.delete, color: Colors.redAccent),
onPressed: () {
_showDeleteConfirmationDialog();
},
),
],
),
body: Padding(
padding: EdgeInsets.all(16.0),

55
lib/pages/sign_in_page.dart

@ -76,7 +76,7 @@ class _SignInPageState extends State<SignInPage> {
onPressed: () {
_showSettingsModal(context); // Show the modal
},
child: Text('Settings'),
child: Text('Pengaturan'),
),
],
),
@ -96,16 +96,18 @@ class _Logo extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
children: [
Container(
margin: EdgeInsets.only(top: 30),
// margin: EdgeInsets.only(top: 30),
child: Image.asset(
'assets/img/logo_siopas.png',
'assets/img/siopas_apps.png',
height: isSmallScreen ? 135 : 200,
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
"Welcome To Siopas!",
child: Column(
children: [
Text(
"Siopas ISTW",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: isSmallScreen ? 18 : 22,
@ -113,6 +115,19 @@ class _Logo extends StatelessWidget {
color: Colors.black,
),
),
SizedBox(
height:
8.0), // Berikan sedikit jarak antara teks "Siopas ISTW" dan versi
Text(
"Version 1.0.0", // Gantilah dengan versi aktual
textAlign: TextAlign.center,
style: TextStyle(
fontSize: isSmallScreen ? 14 : 16,
color: Colors.grey,
),
),
],
),
),
],
);
@ -261,13 +276,27 @@ class __FormContentState extends State<_FormContent> {
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4)),
borderRadius: BorderRadius.circular(4),
),
primary: Colors.indigo, // Ganti warna tombol menjadi indigo
alignment: Alignment.center, // Menyusun isi tombol ke tengah
),
child: const Padding(
padding: EdgeInsets.all(10.0),
child: Text(
'Login',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.center, // Tengahkan teks 'Login'
children: [
Icon(Icons.login),
SizedBox(
width:
8.0), // Berikan sedikit jarak antara ikon dan teks
Text(
'Masuk',
style: TextStyle(
fontSize: 16, fontWeight: FontWeight.bold),
),
],
),
),
onPressed: () {
@ -347,7 +376,7 @@ class _SettingsModalState extends State<SettingsModal> {
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Settings'),
Text('Pengaturan'),
GestureDetector(
onTap: () {
Navigator.of(context).pop(); // Close the modal
@ -379,7 +408,7 @@ class _SettingsModalState extends State<SettingsModal> {
saveSettings(ipAddressController.text, portController.text);
Navigator.of(context).pop(); // Close the modal
},
child: Text('Save'),
child: Text('Simpan'),
),
],
);

6
lib/pages/splash_page.dart

@ -1,5 +1,6 @@
import 'dart:async';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:siopas/models/user_model.dart';
@ -73,7 +74,10 @@ class _SplashPageState extends State<SplashPage> {
),
),
SizedBox(height: 16),
CircularProgressIndicator(),
LoadingAnimationWidget.staggeredDotsWave(
color: Colors.indigo,
size: 40,
),
SizedBox(height: 16),
Text(
'Memuat...',

97
lib/pages/transfer_peti/conn/syncronize.dart

@ -85,9 +85,68 @@ class SyncronizationTransferPetiData {
await dbClient!.delete(SqfliteDatabaseHelper.transferPetiTable);
}
Future saveTransferPetiServerWith(
// Future saveTransferPetiServerWith(
// List<TransferPetiModel> transferPetiLocalList) async {
// for (var i = 0; i < transferPetiLocalList.length; i++) {
// 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;
// }
// }
// // Format tanggal sesuai kebutuhan
// String formattedCreatedAt = transferPetiLocalList[i].created_at != null
// ? DateFormat('yyyy-MM-dd HH:mm:ss.SSS')
// .format(transferPetiLocalList[i].created_at!)
// : DateFormat('yyyy-MM-dd HH:mm:ss.SSS').format(DateTime.now());
// Map<String, dynamic> data = {
// "mobile_id": transferPetiLocalList[i].mobile_id.toString(), // "id": "1
// "peti_id": transferPetiLocalList[i].peti_id.toString(),
// "name_customer": transferPetiLocalList[i].name_customer.toString(),
// "source_warehouse":
// transferPetiLocalList[i].source_warehouse.toString(),
// "destination_warehouse":
// transferPetiLocalList[i].destination_warehouse.toString(),
// "date": transferPetiLocalList[i].date.toString(),
// "created_by": transferPetiLocalList[i].created_by.toString(),
// "created_at": formattedCreatedAt,
// };
// final response = await http.post(
// Uri.parse(await getBaseUrl() + '/m-transfer-peti/store'),
// body: data,
// );
// if (response.statusCode == 200) {
// // print("Data uploaded successfully for index $i:");
// // print("Response body: ${response.body}");
// print("Saving Data saveToTransferPetiWith");
// } else {
// print(
// "Failed to upload data for index $i. Status code: ${response.statusCode}");
// print("Response body: ${response.body}");
// }
// }
// return true; // Pengunggahan berhasil
// }
Future<bool> saveTransferPetiServerWith(
List<TransferPetiModel> transferPetiLocalList) async {
for (var i = 0; i < transferPetiLocalList.length; i++) {
const maxRequestsBeforeDelay = 25;
const delayDuration = Duration(seconds: 3);
int requestCounter = 0;
await Future.forEach(transferPetiLocalList, (transferPeti) async {
DateTime? parseDateTime(String? dateTimeString) {
if (dateTimeString == null || dateTimeString.isEmpty) {
return null;
@ -102,21 +161,19 @@ class SyncronizationTransferPetiData {
}
// Format tanggal sesuai kebutuhan
String formattedCreatedAt = transferPetiLocalList[i].created_at != null
String formattedCreatedAt = transferPeti.created_at != null
? DateFormat('yyyy-MM-dd HH:mm:ss.SSS')
.format(transferPetiLocalList[i].created_at!)
.format(transferPeti.created_at!)
: DateFormat('yyyy-MM-dd HH:mm:ss.SSS').format(DateTime.now());
Map<String, dynamic> data = {
"mobile_id": transferPetiLocalList[i].mobile_id.toString(), // "id": "1
"peti_id": transferPetiLocalList[i].peti_id.toString(),
"name_customer": transferPetiLocalList[i].name_customer.toString(),
"source_warehouse":
transferPetiLocalList[i].source_warehouse.toString(),
"destination_warehouse":
transferPetiLocalList[i].destination_warehouse.toString(),
"date": transferPetiLocalList[i].date.toString(),
"created_by": transferPetiLocalList[i].created_by.toString(),
"mobile_id": transferPeti.mobile_id.toString(),
"peti_id": transferPeti.peti_id.toString(),
"name_customer": transferPeti.name_customer.toString(),
"source_warehouse": transferPeti.source_warehouse.toString(),
"destination_warehouse": transferPeti.destination_warehouse.toString(),
"date": transferPeti.date.toString(),
"created_by": transferPeti.created_by.toString(),
"created_at": formattedCreatedAt,
};
@ -126,15 +183,21 @@ class SyncronizationTransferPetiData {
);
if (response.statusCode == 200) {
// print("Data uploaded successfully for index $i:");
// print("Response body: ${response.body}");
print("Saving Data saveToTransferPetiWith");
} else {
print(
"Failed to upload data for index $i. Status code: ${response.statusCode}");
print("Failed to upload data. Status code: ${response.statusCode}");
print("Response body: ${response.body}");
}
// Increment counter
requestCounter++;
// Jeda 3 detik setiap 25 permintaan
if (requestCounter % maxRequestsBeforeDelay == 0 &&
requestCounter != transferPetiLocalList.length) {
await Future.delayed(delayDuration);
}
});
return true; // Pengunggahan berhasil
}

16
lib/pages/transfer_peti/controller/transfer_peti_controller.dart

@ -95,7 +95,7 @@ class ControllerTransferPeti {
return transferPetiList;
}
Future<List<TransferPetiModel>> fetchDataId() async {
Future<List<TransferPetiModel>> fetchTransferPetiDataId() async {
var dbclient = await conn.db;
List<TransferPetiModel> transferPetiList = [];
try {
@ -110,6 +110,20 @@ class ControllerTransferPeti {
return transferPetiList;
}
Future<void> deleteTransferPetiById(String id) async {
var dbclient = await conn.db;
try {
await dbclient!.delete(
SqfliteDatabaseHelper.transferPetiTable,
where: 'id = ?',
whereArgs: [id],
);
} catch (e) {
print('Gagal menghapus transfer peti dari database: $e');
throw Exception('Gagal menghapus transfer peti');
}
}
Future<void> deleteAllData() async {
var dbClient = await conn.db;
await dbClient!.delete(SqfliteDatabaseHelper.transferPetiTable);

340
lib/pages/transfer_peti/edit.dart

@ -21,6 +21,7 @@ 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';
@ -54,15 +55,15 @@ class _EditTransferPetiPageState extends State<EditTransferPetiPage> {
List<WarehouseModel>? _valwarehouse;
List<WarehouseModel>? _valWarehouse_tujuan_gudang;
List<ConditionPetiModel>? _valconditionPeti;
List<CustomerModel>? _valcustomer;
CustomerModel? customerSqfliteApi;
List<CustomerModel>? _valcustomer;
List<PetiAssetModel> _unrestrictedPetiList = [];
List<PetiAssetModel> _filteredPetiList = [];
bool isQRCodeScanned = false;
bool loading = true;
TextEditingController searchBoxController = TextEditingController();
TextEditingController _dateController = TextEditingController();
// TextEditingController _enterPicController = TextEditingController();
// TextEditingController _kondisiPetiController = TextEditingController();
@ -73,12 +74,19 @@ class _EditTransferPetiPageState extends State<EditTransferPetiPage> {
Barcode? result;
QRViewController? controller;
bool loading = true;
@override
void initState() {
super.initState();
_getUserToken();
warehouseListAPI();
// Memulai loading
setState(() {
loading = true;
});
datatablesTransferPetiList();
// typePetiListAPI();
customerListAPI();
@ -86,6 +94,11 @@ class _EditTransferPetiPageState extends State<EditTransferPetiPage> {
kondisiPetiListAPI();
initializeDateFormatting('id_ID', null);
// Mengakhiri loading setelah tugas selesai
setState(() {
loading = false;
});
}
void _getUserToken() async {
@ -234,7 +247,7 @@ class _EditTransferPetiPageState extends State<EditTransferPetiPage> {
(warehouse) => warehouse.id == allowedPeti.warehouse_id,
);
customerItemSqfliteApi = _valcustomer?.firstWhereOrNull(
customerSqfliteApi = _valcustomer?.firstWhereOrNull(
(customer) => customer.id == allowedPeti.customer_id,
);
});
@ -373,7 +386,7 @@ class _EditTransferPetiPageState extends State<EditTransferPetiPage> {
id: null,
mobile_id: uuid.v4(),
peti_id: petiSqfliteApi!.id,
name_customer: customerItemSqfliteApi!.id,
name_customer: customerSqfliteApi!.id,
source_warehouse: warehouseSqfliteApi!.id,
destination_warehouse: warehouseTujuanSqfliteApi!.id,
date: parseDateTime(_dateController.text),
@ -426,19 +439,98 @@ class _EditTransferPetiPageState extends State<EditTransferPetiPage> {
elevation: 2,
child: Container(
margin: EdgeInsets.all(8),
child: DropdownButtonFormField<PetiAssetModel>(
validator: (value) {
if (value == null) {
return 'Harus diisi';
child: DropdownSearch<PetiAssetModel>(
popupProps: PopupProps.bottomSheet(
showSearchBox: true,
itemBuilder: (context, PetiAssetModel? peti,
bool? isSelected) {
if (peti == null) {
return SizedBox.shrink();
}
return null;
// 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,
);
},
decoration: InputDecoration(
labelText: 'Peti',
border: OutlineInputBorder(),
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),
),
),
),
hint: Text("Pilih Peti"),
value: petiSqfliteApi,
),
items: (isQRCodeScanned
? _filteredPetiList
: (_valpeti ?? []).where((peti) =>
@ -446,32 +538,31 @@ class _EditTransferPetiPageState extends State<EditTransferPetiPage> {
(peti.warehouse_id ==
user.warehouse_id) &&
(peti.status == 'AKTIF')))
.map((PetiAssetModel peti) {
return DropdownMenuItem<PetiAssetModel>(
child: Text(
'${peti.fix_lot}',
style: TextStyle(
fontSize: 12,
),
),
value: peti,
);
}).toList(),
.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) =>
warehouseSqfliteApi = _valwarehouse
?.firstWhere((warehouse) =>
warehouse.id ==
value.warehouse_id,
);
customerItemSqfliteApi =
_valcustomer?.firstWhereOrNull(
(customer) =>
customer.id == value.customer_id,
);
value.warehouse_id);
customerSqfliteApi = _valcustomer
?.firstWhereOrNull((customer) =>
customer.id ==
value.customer_id);
// Perbarui _unrestrictedPetiList sesuai pemilihan manual
_unrestrictedPetiList = [
@ -481,6 +572,12 @@ class _EditTransferPetiPageState extends State<EditTransferPetiPage> {
}
});
},
validator: (PetiAssetModel? value) {
if (value == null) {
return 'Harus diisi';
}
return null;
},
),
),
),
@ -608,34 +705,113 @@ class _EditTransferPetiPageState extends State<EditTransferPetiPage> {
Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: DropdownButtonFormField<CustomerModel>(
validator: (value) {
if (value == null) {
return 'Harus diisi';
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 null;
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);
},
decoration: InputDecoration(
labelText: 'Pilih Customer',
border: OutlineInputBorder(),
),
hint: Text("Pilih Customer"),
value: customerItemSqfliteApi,
],
),
Divider(),
],
),
),
),
items: (_valcustomer ?? [])
.where((customer) =>
customer.deleted_at != true)
.map((CustomerModel customer) {
return DropdownMenuItem<CustomerModel>(
child: Text('${customer.name}'),
value: customer,
);
}).toList() ??
.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(() {
customerItemSqfliteApi = value;
customerSqfliteApi = value;
});
},
validator: (CustomerModel? value) {
if (value == null) {
return 'Harus diisi';
}
return null;
},
),
),
),
@ -651,17 +827,39 @@ class _EditTransferPetiPageState extends State<EditTransferPetiPage> {
return null;
},
decoration: InputDecoration(
labelText: 'Pilih Asal Gudang',
labelText: 'Asal Gudang',
border: OutlineInputBorder(),
),
hint: Text("Pilih Asal Gudang"),
hint: Text("Asal Gudang"),
value: warehouseSqfliteApi,
items: (_valwarehouse ?? [])
.where((warehouse) =>
warehouse.deleted_at != true)
.map((WarehouseModel warehouse) {
.map((WarehouseModel warehouse)
// _valwarehouse?.map((WarehouseModel warehouse)
{
return DropdownMenuItem<WarehouseModel>(
child: Text('${warehouse.name}'),
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() ??
@ -687,17 +885,39 @@ class _EditTransferPetiPageState extends State<EditTransferPetiPage> {
return null;
},
decoration: InputDecoration(
labelText: 'Pilih Tujuan Gudang',
labelText: 'Tujuan Transfer Gudang',
border: OutlineInputBorder(),
),
hint: Text("Pilih Tujuan Gudang"),
hint: Text("Tujuan Transfer Gudang"),
value: warehouseTujuanSqfliteApi,
items: (_valwarehouse ?? [])
.where((warehouseTujuan) =>
warehouseTujuan.deleted_at != true)
.map((WarehouseModel warehouseTujuan) {
.map((WarehouseModel warehouseTujuan)
// _valwarehouse?.map((WarehouseModel warehouse)
{
return DropdownMenuItem<WarehouseModel>(
child: Text('${warehouseTujuan.name}'),
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() ??

78
lib/pages/transfer_peti/index.dart

@ -5,6 +5,7 @@ import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:data_table_2/data_table_2.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import 'package:siopas/models/customer_model.dart';
import 'package:siopas/models/disposal_model.dart';
import 'package:siopas/models/m_asset_status_model.dart';
@ -26,6 +27,7 @@ import 'package:http/http.dart' as http;
import '../../connection/connection.dart';
import '../../models/condition_peti_model.dart';
import 'show.dart';
class TransferPetiPage extends StatefulWidget {
const TransferPetiPage({super.key});
@ -57,27 +59,38 @@ class TransferPetiPageState extends State<TransferPetiPage> {
List<TypePetiModel>? _tipePetiData;
List<CustomerModel>? _customerData;
List<WarehouseModel>? _warehouseData;
bool _isLoading = false;
Timer? _timer;
bool _isLoading = false;
@override
void initState() {
super.initState();
_getUserToken();
warehouseListAPI();
typePetiListAPI();
customerListAPI();
petiListAPI();
// disposalListAPI();
// Memulai loading
setState(() {
_isLoading = true;
});
// Tampil data Datatables
// datatablesAssetStatusList();
datatablesTransferPetiList();
datatablesPetiList();
datatablesTipePetiList();
datatablesCustomerList();
datatablesWarehouseList();
Future.wait([
warehouseListAPI(),
typePetiListAPI(),
customerListAPI(),
petiListAPI(),
// disposalListAPI(),
datatablesTransferPetiList(),
datatablesPetiList(),
datatablesTipePetiList(),
datatablesCustomerList(),
datatablesWarehouseList(),
]).then((_) {
// Mengakhiri loading setelah semua tugas selesai
setState(() {
_isLoading = false;
});
});
// Inisialisasi _data di sini jika diperlukan
_data = <TransferPetiModel>[];
}
@ -180,10 +193,16 @@ class TransferPetiPageState extends State<TransferPetiPage> {
EasyLoading.show(status: 'Mengambil data Peti...');
List<PetiAssetModel> petiApiData =
await SyncronizationDataAPI().fetchPetiFromApi();
await ControllerApi()
.deleteAllPetiDataAPI(); // Clear existing data in SQLite
await ControllerApi()
.addAllPetiDataAPI(petiApiData); // Add new data to SQLite
// Menentukan ukuran chunk, misalnya 100
int chunkSize = 100;
// Memasukkan data ke SQLite dengan menggunakan chunk
await ControllerApi().addAllPetiDataAPI(petiApiData, chunkSize);
EasyLoading.dismiss();
}
@ -501,7 +520,12 @@ class TransferPetiPageState extends State<TransferPetiPage> {
),
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
? Center(
child: LoadingAnimationWidget.staggeredDotsWave(
color: Colors.indigo,
size: 40,
),
)
: TabBarView(
children: [
SingleChildScrollView(
@ -520,6 +544,7 @@ class TransferPetiPageState extends State<TransferPetiPage> {
},
columns: [
DataColumn(label: Text('No')),
DataColumn(label: Text('')),
DataColumn(label: Text('Kode Peti')),
DataColumn(label: Text('Customer')),
DataColumn(label: Text('Tgl Transfer')),
@ -702,6 +727,27 @@ class _DataSourceLokal extends DataTableSource {
(index + 1).toString(),
),
),
DataCell(
GestureDetector(
onTap: () {
if (item.id != null) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailTransferPetiPage(
transferPetiId: int.parse(item.id.toString()),
),
),
);
// print('asset id: ${item.id}');
}
},
child: Icon(Icons.article,
size: 40,
color: Colors.indigo[700]), // Ganti ikon sesuai kebutuhan
),
),
DataCell(
Text(
petiSqfliteApi != null && petiSqfliteApi.fix_lot != null

367
lib/pages/transfer_peti/show.dart

@ -0,0 +1,367 @@
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:siopas/models/asset_status_model.dart';
import 'package:siopas/models/customer_model.dart';
import 'package:siopas/models/m_asset_status_model.dart';
import 'package:siopas/models/transfer_peti_model.dart';
import 'package:siopas/pages/peminjaman_barang/controller/peminjaman_controller.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:intl/intl.dart';
import 'package:collection/collection.dart';
import 'package:siopas/pages/transfer_peti/controller/transfer_peti_controller.dart';
import '../../models/warehouse_mode.dart';
import '../../services/controllerApi.dart';
class DetailTransferPetiPage extends StatefulWidget {
final int transferPetiId;
const DetailTransferPetiPage({Key? key, required this.transferPetiId})
: super(key: key);
@override
_DetailTransferPetiPageState createState() => _DetailTransferPetiPageState();
}
class _DetailTransferPetiPageState extends State<DetailTransferPetiPage> {
TransferPetiModel? transferInfo;
WarehouseModel? warehouseInfo;
List<PetiAssetModel>? petiData;
List<CustomerModel>? customerData;
List<WarehouseModel>? warehouseData;
bool loading = true;
@override
void initState() {
super.initState();
// Pemanggilan fungsi-fungsi yang diperlukan
getTransferIdData();
customerListAPI();
petiListAPI();
warehouseListAPI();
initializeDateFormatting('id_ID', null);
// Mengatur loading ke false setelah tugas selesai
setState(() {
loading = false;
});
}
Future customerListAPI() async {
if (mounted) {
await ControllerApi().fetchCustomerDataAPI().then((value) {
setState(() {
customerData = (value as List<dynamic>)
.map((item) => CustomerModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
Future petiListAPI() async {
if (mounted) {
await ControllerApi().fetchPetiDataAPI().then((value) {
setState(() {
petiData = (value as List<dynamic>)
.map((item) => PetiAssetModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
Future warehouseListAPI() async {
if (mounted) {
await ControllerApi().fetchWarehouseDataAPI().then((value) {
setState(() {
warehouseData = (value as List<dynamic>)
.map((item) => WarehouseModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
Future<void> getTransferIdData() async {
List<TransferPetiModel> transfers =
await ControllerTransferPeti().fetchTransferPetiDataId();
transferInfo = transfers.firstWhereOrNull(
(transfer) => transfer.id.toString() == widget.transferPetiId.toString(),
);
if (mounted) {
setState(() {});
}
}
String _formatDate(String? date) {
if (date != null) {
DateTime parsedDate = DateTime.parse(date);
String formattedDate =
DateFormat('EEEE, dd MMMM yyyy', 'id_ID').format(parsedDate);
return formattedDate;
} else {
return '';
}
}
Future<void> _deleteTransferPeti() async {
try {
// Panggil fungsi untuk menghapus peminjaman berdasarkan ID
await ControllerTransferPeti()
.deleteTransferPetiById(widget.transferPetiId.toString());
// Navigasi kembali ke halaman sebelumnya atau halaman yang sesuai
Navigator.pushNamed(context, '/transfer-peti');
} catch (e) {
// Tangani kesalahan jika terjadi
print('Gagal menghapus transfer peti: $e');
}
}
@override
Widget build(BuildContext context) {
PetiAssetModel? petiSqfliteApi;
petiSqfliteApi = petiData?.firstWhereOrNull(
(peti) => peti.id == transferInfo?.peti_id,
);
CustomerModel? customerSqfliteApi;
customerSqfliteApi = customerData?.firstWhereOrNull(
(customer) => customer.id == transferInfo?.name_customer,
);
WarehouseModel? warehouseSqfliteApi;
warehouseSqfliteApi = warehouseData?.firstWhereOrNull(
(warehouse) => warehouse.id == transferInfo?.source_warehouse,
);
WarehouseModel? warehouseTujuanSqfliteApi;
warehouseTujuanSqfliteApi = warehouseData?.firstWhereOrNull(
(warehouse) => warehouse.id == transferInfo?.destination_warehouse,
);
Future<void> _showDeleteConfirmationDialog() async {
return showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.0),
),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Icon(
Icons.info,
color: Colors.blue,
),
SizedBox(width: 8),
Text(
'Konfirmasi Hapus',
style: TextStyle(
fontSize: 18,
),
),
],
),
IconButton(
icon: Icon(
Icons.close,
color: Colors.black54,
),
onPressed: () {
Navigator.of(context).pop();
},
),
],
),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text(
'Anda yakin ingin menghapus pengembalian ini? ${petiSqfliteApi!.fix_lot.toString()}',
style: TextStyle(
fontSize: 16,
),
),
],
),
),
actions: <Widget>[
Container(
margin: EdgeInsets.only(right: 3.0),
child: ElevatedButton(
child: Text('Hapus'),
onPressed: () {
// Panggil fungsi untuk menghapus peminjaman berdasarkan ID
_deleteTransferPeti();
Navigator.pushNamed(context, '/transfer-peti');
EasyLoading.showSuccess(
'Berhasil menghapus data transfer peti');
},
style: ElevatedButton.styleFrom(
primary: Colors.red,
),
),
),
],
);
},
);
}
return Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text(
'Detail Transfer Peti',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
Navigator.pushNamed(context, '/transfer-peti');
},
),
actions: [
IconButton(
icon: Icon(Icons.delete, color: Colors.redAccent),
onPressed: () {
_showDeleteConfirmationDialog();
},
),
],
),
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: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.article, size: 30, color: Colors.white),
SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'ID:',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
SizedBox(height: 5),
Text(
petiSqfliteApi != null &&
petiSqfliteApi.fix_lot != null
? petiSqfliteApi!.fix_lot.toString()
: '-',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
],
),
],
),
],
),
),
),
SizedBox(height: 10),
if (transferInfo != null) ...[
_buildDetailItem(
'Kode Peti',
petiSqfliteApi != null && petiSqfliteApi.fix_lot != null
? petiSqfliteApi!.fix_lot.toString()
: '-',
),
Divider(thickness: 1),
_buildDetailItem(
'Nama Customer',
customerSqfliteApi != null && customerSqfliteApi.name != null
? customerSqfliteApi!.name.toString()
: '-',
),
Divider(thickness: 1),
_buildDetailItem(
'Tgl Transfer', _formatDate(transferInfo!.date.toString())),
Divider(thickness: 1),
_buildDetailItem(
'Asal Gudang',
// peminjamanInfo!.exit_warehouse.toString()),
warehouseSqfliteApi != null &&
warehouseSqfliteApi.name != null
? warehouseSqfliteApi!.name.toString()
: '-'),
Divider(thickness: 1),
_buildDetailItem(
'Tujuan Gudang',
// peminjamanInfo!.exit_warehouse.toString()),
warehouseTujuanSqfliteApi != null &&
warehouseTujuanSqfliteApi.name != null
? warehouseTujuanSqfliteApi!.name.toString()
: '-'),
Divider(thickness: 1),
// ... tambahkan data lainnya sesuai kebutuhan
],
],
),
),
),
);
}
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, fontWeight: FontWeight.bold),
),
Text(
value,
style: TextStyle(fontSize: 12),
),
],
),
);
}
}

114
lib/services/controllerApi.dart

@ -104,20 +104,122 @@ class ControllerApi {
await dbClient!.delete(SqfliteDatabaseHelper.petiTable);
}
Future<void> addAllPetiDataAPI(List<PetiAssetModel> petiListApi) async {
var dbclient = await conn.db;
Batch batch = dbclient!.batch();
// Future<void> addAllPetiDataAPI(List<PetiAssetModel> petiListApi) async {
// var dbclient = await conn.db;
// Batch batch = dbclient!.batch();
// for (var peti in petiListApi) {
// // Ensure that toJson() correctly converts the model to a map
// batch.insert(
// SqfliteDatabaseHelper.petiTable,
// peti.toJson(),
// );
// }
// await batch.commit();
// }
// ini sudah benar
// Future<void> addAllPetiDataAPI(
// List<PetiAssetModel> petiListApi, int chunkSize) async {
// var dbclient = await conn.db;
// // Mulai batch
// Batch batch = dbclient!.batch();
// // Iterasi melalui data dalam chunk
// for (int i = 0; i < petiListApi.length; i += chunkSize) {
// // Ambil chunk dari data
// List<PetiAssetModel> chunk = petiListApi.skip(i).take(chunkSize).toList();
// // Insert setiap item dalam chunk ke dalam batch
// for (var peti in chunk) {
// batch.insert(
// SqfliteDatabaseHelper.petiTable,
// peti.toJson(),
// );
// }
// }
// // Commit batch
// await batch.commit();
// }
// Future<void> addAllPetiDataAPI(List<PetiAssetModel> petiListApi) async {
// var dbclient = await conn.db;
// Batch batch = dbclient!.batch();
// // Tentukan ukuran chunk yang diinginkan
// int chunkSize = 100;
// // Iterasi melalui data dalam chunk
// for (int i = 0; i < petiListApi.length; i += chunkSize) {
// // Ambil chunk dari data
// List<PetiAssetModel> chunk = petiListApi.skip(i).take(chunkSize).toList();
// // Insert setiap item dalam chunk ke dalam batch
// for (var peti in chunk) {
// batch.insert(
// SqfliteDatabaseHelper.petiTable,
// peti.toJson(),
// );
// }
// // Commit batch setelah menambahkan semua item dalam chunk
// await batch.commit();
// }
// }
Future<void> addAllPetiDataAPI(
List<PetiAssetModel> petiListApi, int chunkSize) async {
try {
String? formatDateTime(DateTime? dateTime) {
return dateTime
?.toIso8601String(); // Ubah DateTime ke dalam format ISO 8601
}
var dbclient = await conn?.db;
if (dbclient == null) {
print("Error: Database connection is null");
return;
}
await dbclient.transaction((txn) async {
Batch batch = txn.batch();
// Iterasi melalui data dalam chunk
for (int i = 0; i < petiListApi.length; i += chunkSize) {
List<PetiAssetModel> chunk =
petiListApi.skip(i).take(chunkSize).toList();
for (var peti in chunk) {
// Hanya ambil kolom yang diinginkan
var petiData = {
'id': peti.id,
'fix_lot': peti.fix_lot,
'status': peti.status,
'customer_id': peti.customer_id,
'warehouse_id': peti.warehouse_id,
'kondisipeti_id': peti.kondisipeti_id,
'deleted_at': formatDateTime(peti.deleted_at),
};
for (var peti in petiListApi) {
// Ensure that toJson() correctly converts the model to a map
batch.insert(
SqfliteDatabaseHelper.petiTable,
peti.toJson(),
petiData,
);
}
}
await batch.commit();
});
} catch (e) {
print("Error during addAllPetiDataAPI: $e");
// Handle error sesuai kebutuhan Anda
}
}
// End Peti ------------------------------------------------------------------------------------------------------------------
// Warehouse ------------------------------------------------------------------------------------------------------------------

51
lib/services/syncronizeAPI.dart

@ -54,57 +54,6 @@ class SyncronizationDataAPI {
}
}
// Future<List<PetiAssetModel>> fetchPetiFromApi() async {
// final apiURL = 'http://192.168.0.18:8000/api/v1/peti-asset';
// final response = await http.get(Uri.parse(apiURL));
// if (response.statusCode == 200) {
// List<dynamic> data = json.decode(response.body)['data']['petis'];
// print('Success Fetch Data Peti');
// List<PetiAssetModel> petiList = data.map((item) {
// // Extracting and transforming data from JSON
// String id = item['id'].toString();
// String tipePetiId = item['tipe_peti_id'].toString();
// String warna = item['warna'].toString();
// int? packingNo = item['packing_no'] != null
// ? int.parse(item['packing_no'].toString())
// : null;
// String customerID = item['customer_id'].toString();
// String warehouseID = item['warehouse_id'].toString();
// String kondisiPetiID = item['kondisipeti_id'].toString();
// int? jumlah = item['jumlah'] != null
// ? int.parse(item['jumlah'].toString())
// : null;
// DateTime datePembuatan = DateTime.parse(item['date_pembuatan']);
// // Creating an instance of PetiAssetModel
// PetiAssetModel peti = PetiAssetModel(
// id: id,
// tipe_peti_id: tipePetiId,
// warna: warna,
// packing_no: packingNo,
// customer_id: customerID,
// warehouse_id: warehouseID,
// kondisipeti_id: kondisiPetiID,
// jumlah: jumlah,
// date_pembuatan: datePembuatan,
// created_by:
// item['created_by'] != null ? item['created_by'].toString() : null,
// updated_by:
// item['updated_by'] != null ? item['updated_by'].toString() : null,
// );
// return peti;
// }).toList();
// return petiList;
// } else {
// throw Exception('Failed to fetch data from API Peti');
// }
// }
Future<List<WarehouseModel>> fetchWarehouseFromApi() async {
final apiURL = '${await getBaseUrl()}/m-warehouse';

24
pubspec.lock

@ -153,6 +153,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.10"
dropdown_search:
dependency: "direct main"
description:
name: dropdown_search
sha256: "55106e8290acaa97ed15bea1fdad82c3cf0c248dd410e651f5a8ac6870f783ab"
url: "https://pub.dev"
source: hosted
version: "5.0.6"
fake_async:
dependency: transitive
description:
@ -296,6 +304,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.8.1"
loading_animation_widget:
dependency: "direct main"
description:
name: loading_animation_widget
sha256: "1901682600273a966c34cf44a85fc5355da92a8d08a8a43c11adc4e471993e3a"
url: "https://pub.dev"
source: hosted
version: "1.2.0+4"
matcher:
dependency: transitive
description:
@ -528,6 +544,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.3.2"
shimmer:
dependency: "direct main"
description:
name: shimmer
sha256: "5f88c883a22e9f9f299e5ba0e4f7e6054857224976a5d9f839d4ebdc94a14ac9"
url: "https://pub.dev"
source: hosted
version: "3.0.0"
sky_engine:
dependency: transitive
description: flutter

14
pubspec.yaml

@ -52,6 +52,11 @@ dependencies:
flutter_easyloading: ^3.0.5
sqflite: ^2.3.0
flutter_launcher_icons: ^0.13.1
dropdown_search: ^5.0.6
shimmer: ^3.0.0
loading_animation_widget: ^1.2.0+4
dev_dependencies:
@ -61,10 +66,13 @@ dev_dependencies:
flutter_launcher_icons:
android: true
ios: true
image_path: "assets/img/siopas_apps.png"
adaptive_icon_background: "#ffffff"
image_path_ios: "assets/img/logo_siopas_apps.png"
image_path_android: "assets/img/logo_siopas_apps.png"
# image_path: "assets/img/siopas_apps.png"
adaptive_icon_background: "assets/img/putih.png"
adaptive_icon_foreground: "assets/img/siopas_apps.png"
adaptive_icon_mask: "assets/img/siopas_apps.png"
# adaptive_icon_foreground: "assets/img/logo_siopas_apps.jpg"
# adaptive_icon_mask: "assets/img/logo_siopas_apps.jpg"
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is

Loading…
Cancel
Save