Browse Source

Update peminjaman, pengembalian, transfer mode offline, perbaikan icon dan nama apps

master
unknown 1 year ago
parent
commit
65fee98f79
  1. 4
      android/app/src/main/AndroidManifest.xml
  2. BIN
      android/app/src/main/res/drawable-hdpi/ic_launcher_foreground.png
  3. BIN
      android/app/src/main/res/drawable-mdpi/ic_launcher_foreground.png
  4. BIN
      android/app/src/main/res/drawable-xhdpi/ic_launcher_foreground.png
  5. BIN
      android/app/src/main/res/drawable-xxhdpi/ic_launcher_foreground.png
  6. BIN
      android/app/src/main/res/drawable-xxxhdpi/ic_launcher_foreground.png
  7. 5
      android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
  8. BIN
      android/app/src/main/res/mipmap-hdpi/ic_launcher.png
  9. BIN
      android/app/src/main/res/mipmap-mdpi/ic_launcher.png
  10. BIN
      android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  11. BIN
      android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  12. BIN
      android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  13. 4
      android/app/src/main/res/values/colors.xml
  14. BIN
      assets/img/siopas_apps.png
  15. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
  16. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
  17. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
  18. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
  19. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
  20. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
  21. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
  22. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
  23. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
  24. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
  25. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png
  26. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png
  27. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png
  28. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png
  29. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
  30. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
  31. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png
  32. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png
  33. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
  34. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
  35. BIN
      ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
  36. 2
      ios/Runner/Info.plist
  37. 27
      lib/connection/connection.dart
  38. 45
      lib/main.dart
  39. 265
      lib/migrations/databasehelper.dart
  40. 117
      lib/models/asset_status_model.dart
  41. 56
      lib/models/condition_peti_model.dart
  42. 62
      lib/models/customer_model.dart
  43. 84
      lib/models/disposal_model.dart
  44. 89
      lib/models/m_asset_status_model.dart
  45. 84
      lib/models/transfer_peti_model.dart
  46. 2
      lib/models/type_peti_model.dart
  47. 34
      lib/models/user_model.dart
  48. 26
      lib/models/warehouse_mode.dart
  49. 259
      lib/pages/home/conn_home_page.dart/syncronize.dart
  50. 62
      lib/pages/home/controller/home_controller.dart
  51. 734
      lib/pages/home/home_page.dart
  52. 2
      lib/pages/home/main_page.dart
  53. 4
      lib/pages/home/setting_page.dart
  54. 222
      lib/pages/peminjaman_barang/conn/syncronize.dart
  55. 204
      lib/pages/peminjaman_barang/controller/peminjaman_controller.dart
  56. 1143
      lib/pages/peminjaman_barang/create.dart
  57. 760
      lib/pages/peminjaman_barang/peminjaman_stock_page.dart
  58. 226
      lib/pages/peminjaman_barang/show.dart
  59. 218
      lib/pages/pengembalian_barang/conn/syncronize.dart
  60. 221
      lib/pages/pengembalian_barang/controller/pengembalian_controller.dart
  61. 764
      lib/pages/pengembalian_barang/edit.dart
  62. 801
      lib/pages/pengembalian_barang/index.dart
  63. 296
      lib/pages/pengembalian_barang/pengembalian_index.dart
  64. 274
      lib/pages/pengembalian_barang/show.dart
  65. 174
      lib/pages/sign_in_page.dart
  66. 224
      lib/pages/transfer_peti/conn/syncronize.dart
  67. 191
      lib/pages/transfer_peti/controller/transfer_peti_controller.dart
  68. 812
      lib/pages/transfer_peti/edit.dart
  69. 751
      lib/pages/transfer_peti/index.dart
  70. 175
      lib/pages/transfer_peti/show.dart
  71. 287
      lib/pages/transfer_peti/transfer_peti_index.dart
  72. 4
      lib/services/asset_status_service.dart
  73. 13
      lib/services/auth_service.dart
  74. 372
      lib/services/controllerApi.dart
  75. 2
      lib/services/m_status_service.dart
  76. 224
      lib/services/syncronizeAPI.dart
  77. 2
      macos/Flutter/GeneratedPluginRegistrant.swift
  78. 164
      pubspec.lock
  79. 18
      pubspec.yaml
  80. 3
      windows/flutter/generated_plugin_registrant.cc
  81. 1
      windows/flutter/generated_plugins.cmake

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

@ -1,6 +1,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:label="siopas"
android:label="SIOPAS ISTW"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

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

@ -0,0 +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"/>
<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: 544 B

After

Width:  |  Height:  |  Size: 4.7 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 B

After

Width:  |  Height:  |  Size: 2.6 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 721 B

After

Width:  |  Height:  |  Size: 6.9 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 12 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 17 KiB

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

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

BIN
assets/img/siopas_apps.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 212 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 B

After

Width:  |  Height:  |  Size: 869 B

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 2.1 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 450 B

After

Width:  |  Height:  |  Size: 3.7 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 B

After

Width:  |  Height:  |  Size: 1.4 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 462 B

After

Width:  |  Height:  |  Size: 3.5 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 704 B

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: 406 B

After

Width:  |  Height:  |  Size: 2.1 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 586 B

After

Width:  |  Height:  |  Size: 5.4 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 B

After

Width:  |  Height:  |  Size: 9.1 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 B

After

Width:  |  Height:  |  Size: 9.1 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 16 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 762 B

After

Width:  |  Height:  |  Size: 5.1 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 13 KiB

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 14 KiB

2
ios/Runner/Info.plist

@ -17,7 +17,7 @@
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>siopas</string>
<string>SIOPAS ISTW</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>

27
lib/connection/connection.dart

@ -1,4 +1,25 @@
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:shared_preferences/shared_preferences.dart';
String baseUrl = 'http://192.168.0.20:8000/api/v1';
import 'package:shared_preferences/shared_preferences.dart';
Future<String> getBaseUrl() async {
try {
SharedPreferences prefs = await SharedPreferences.getInstance();
String ipAddress =
prefs.getString('ipAddress') ?? '192.168.0.18'; // Default value
String port = prefs.getString('port') ?? '8000'; // Default value
String baseUrl = 'http://$ipAddress:$port/api/v1';
return baseUrl;
} catch (e) {
// Penanganan kesalahan
print('Error reading SharedPreferences: $e');
return ''; // Atau nilai default lainnya jika terjadi kesalahan
}
}
// return 'http://$ipAddress:$port/api/v1';
// String baseUrl = 'http://192.168.0.18:8000/api/v1';
// Gunakan fungsi ini saat diperlukan, misalnya di tempat-tempat yang membutuhkan baseUrl
// Contoh penggunaan: String url = await getBaseUrl();

45
lib/main.dart

@ -1,36 +1,54 @@
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:siopas/migrations/databasehelper.dart';
import 'package:siopas/pages/transfer_peti/edit.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:siopas/pages/pengembalian_barang/edit.dart';
import 'package:siopas/pages/pengembalian_barang/pengembalian_index.dart';
import 'package:siopas/pages/transfer_peti/edit.dart';
import 'package:siopas/pages/transfer_peti/transfer_peti_index.dart';
import 'pages/home/main_page.dart';
import 'pages/peminjaman_barang/peminjaman_stock_page.dart';
import 'pages/peminjaman_barang/create.dart';
import 'pages/peminjaman_barang/show.dart';
import 'pages/pengembalian_barang/edit.dart';
import 'pages/pengembalian_barang/index.dart';
import 'pages/sign_in_page.dart';
import 'pages/splash_page.dart';
import 'pages/transfer_peti/show.dart';
import 'pages/transfer_peti/index.dart';
import 'providers/asset_status_provider.dart';
import 'providers/auth_provider.dart';
import 'providers/m_status_provider.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// SharedPreferences prefs = await SharedPreferences.getInstance();
// var email = prefs.getString("email");
// var password = prefs.getString("password");
// var token = prefs.getString("token");
// await Firebase.initializeApp();
runApp(MyApp());
await SqfliteDatabaseHelper.instance.db;
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp, // Atur orientasi ke potrait
]);
runApp(MyApp());
configLoading(); // Pindahkan baris ini ke sini setelah runApp
}
void configLoading() {
EasyLoading.instance
..displayDuration = const Duration(milliseconds: 2000)
..indicatorType = EasyLoadingIndicatorType.fadingCircle
..loadingStyle = EasyLoadingStyle.dark
..indicatorSize = 45.0
..radius = 10.0
..progressColor = Colors.yellow
..backgroundColor = Colors.green
..indicatorColor = Colors.yellow
..textColor = Colors.yellow
..maskColor = Colors.blue.withOpacity(0.5)
..userInteractions = true
..dismissOnTap = false;
}
class MyApp extends StatelessWidget {
MyApp() {
EasyLoading.init(); // Inisialisasi EasyLoading
}
@override
Widget build(BuildContext context) {
return MultiProvider(
@ -51,18 +69,19 @@ class MyApp extends StatelessWidget {
visualDensity: VisualDensity.adaptivePlatformDensity,
),
debugShowCheckedModeBanner: false,
home: SplashPage(),
routes: {
'/': (context) => SplashPage(),
'/sign-in': (context) => SignInPage(),
'/home': (context) => MainPage(),
'/peminjaman-barang': (context) => AssetStatusPage(),
'/peminjaman-barang/create': (context) => CreatePeminjamanBarang(),
'/pengembalian-barang': (context) => PengembalianBarangPage(),
'/pengembalian-barang/create': (context) =>
'/pengembalian-barang/edit': (context) =>
CreatePengembalianBarangPage(),
'/transfer-peti': (context) => TransferPetiPage(),
'/transfer-peti/edit': (context) => EditTransferPetiPage(),
},
builder: EasyLoading.init(),
),
);
}

265
lib/migrations/databasehelper.dart

@ -0,0 +1,265 @@
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
import '../models/warehouse_mode.dart';
class SqfliteDatabaseHelper {
SqfliteDatabaseHelper.internal();
static final SqfliteDatabaseHelper instance =
SqfliteDatabaseHelper.internal();
factory SqfliteDatabaseHelper() => instance;
static final warehouseTable = 'm_warehouses';
static final typePetiTable = 'type_petis';
static final conditionPetiTable = 'kondisi_petis';
static final customerTable = 'customers';
static final petiTable = 'petis';
static final transferPetiTable = 'transfers';
static final disposalTable = 'disposals';
static final asset_statusesTable = 'asset_statuses';
// static final assetLocalTable = 'asset_statuses_local';
static final peminjamanTable = 'peminjamans';
static final pengembalianTable = 'pengembalians';
static final _version = 1; // Versi database ditingkatkan
Database? _db;
Future<Database?> get db async {
if (_db != null) {
return _db;
}
_db = await initDb();
return _db;
}
Future<void> saveWarehouseList(List<WarehouseModel> warehouseList) async {
final dbClient = await db;
try {
await dbClient!.transaction((txn) async {
var batch = txn.batch();
for (var warehouse in warehouseList) {
batch.insert(
warehouseTable,
warehouse.toJson(),
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
await batch.commit();
});
} catch (e) {
print('Error saving warehouse list to SQLite: $e');
}
}
Future<Database> initDb() async {
final Directory directory = await getApplicationDocumentsDirectory();
String dbPath = join(directory.path, 'siopas.db');
print(dbPath);
var openDb = await openDatabase(dbPath, version: _version,
onCreate: (Database db, int version) async {
await db.execute("""
CREATE TABLE $peminjamanTable (
id INTEGER PRIMARY KEY AUTOINCREMENT,
mobile_id INTEGER NULL,
peti_id INTEGER NULL,
customer_id INTEGER NULL,
warehouse_id INTEGER NULL,
exit_at DATETIME NULL,
est_pengembalian DATETIME NULL,
exit_pic TEXT NULL,
exit_warehouse INTEGER NULL,
enter_at DATETIME NULL,
enter_pic TEXT NULL,
enter_warehouse INTEGER NULL,
kondisi_peti_id INTEGER NULL,
status INTEGER NULL,
created_at TIMESTAMP NULL,
updated_at TIMESTAMP NULL,
deleted_at TIMESTAMP NULL,
created_by TEXT NULL,
updated_by TEXT NULL
);
""");
await db.execute("""
CREATE TABLE $pengembalianTable (
id INTEGER PRIMARY KEY AUTOINCREMENT,
mobile_id INTEGER NULL,
peti_id INTEGER NULL,
customer_id INTEGER NULL,
warehouse_id INTEGER NULL,
exit_at DATETIME NULL,
est_pengembalian DATETIME NULL,
exit_pic TEXT NULL,
exit_warehouse INTEGER NULL,
enter_at DATETIME NULL,
enter_pic TEXT NULL,
enter_warehouse INTEGER NULL,
kondisi_peti_id INTEGER NULL,
status INTEGER NULL,
created_at TIMESTAMP NULL,
updated_at TIMESTAMP NULL,
deleted_at TIMESTAMP NULL,
created_by TEXT NULL,
updated_by TEXT NULL
);
""");
await db.execute("""
CREATE TABLE $asset_statusesTable (
id INTEGER PRIMARY KEY AUTOINCREMENT,
mobile_id INTEGER NOT NULL,
peti_id INTEGER NULL,
customer_id INTEGER NULL,
warehouse_id INTEGER NULL,
exit_at DATETIME NULL,
est_pengembalian DATETIME NULL,
exit_pic TEXT NULL,
exit_warehouse INTEGER NULL,
enter_at DATETIME NULL,
enter_pic TEXT NULL,
enter_warehouse INTEGER NULL,
kondisi_peti_id INTEGER NULL,
status INTEGER NULL,
created_at TIMESTAMP NULL,
updated_at TIMESTAMP NULL,
deleted_at TIMESTAMP NULL,
created_by TEXT NULL,
updated_by TEXT NULL
);
""");
await db.execute("""
CREATE TABLE $warehouseTable (
id INTEGER PRIMARY KEY AUTOINCREMENT,
mobile_id TEXT NULL,
name TEXT NULL,
description TEXT NULL,
address TEXT NULL,
created_at TIMESTAMP NULL,
updated_at TIMESTAMP NULL,
deleted_at TIMESTAMP NULL,
created_by TEXT NULL,
updated_by TEXT NULL
);
""");
await db.execute("""
CREATE TABLE $typePetiTable (
id INTEGER PRIMARY KEY AUTOINCREMENT,
type TEXT NULL,
size_peti TEXT NULL,
description TEXT NULL,
created_at TIMESTAMP NULL,
updated_at TIMESTAMP NULL,
deleted_at TIMESTAMP NULL,
created_by TEXT NULL,
updated_by TEXT NULL
);
""");
await db.execute("""
CREATE TABLE $conditionPetiTable (
id INTEGER PRIMARY KEY AUTOINCREMENT,
nama_kondisi TEXT NULL,
deskripsi_kondisi TEXT NULL,
created_at TIMESTAMP NULL,
updated_at TIMESTAMP NULL,
deleted_at TIMESTAMP NULL,
created_by TEXT NULL,
updated_by TEXT NULL
);
""");
await db.execute("""
CREATE TABLE $customerTable (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NULL,
code_customer TEXT NULL,
lot_no TEXT NULL,
no_tlp TEXT NULL,
address TEXT NULL,
created_at TIMESTAMP NULL,
updated_at TIMESTAMP NULL,
deleted_at TIMESTAMP NULL,
created_by TEXT NULL,
updated_by TEXT NULL
);
""");
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)
);
""");
await db.execute("""
CREATE TABLE $transferPetiTable (
id INTEGER PRIMARY KEY AUTOINCREMENT,
mobile_id TEXT NULL,
peti_id INTEGER NULL,
name_customer INTEGER NULL,
source_warehouse INTEGER NULL,
destination_warehouse INTEGER NULL,
date DATETIME NULL,
created_at TIMESTAMP NULL,
updated_at TIMESTAMP NULL,
deleted_at TIMESTAMP NULL,
created_by TEXT NULL,
updated_by TEXT NULL
);
""");
await db.execute("""
CREATE TABLE $disposalTable (
id INTEGER PRIMARY KEY AUTOINCREMENT,
mobile_id TEXT NULL,
peti_id INTEGER NULL,
customer_id INTEGER NULL,
warehouse_id INTEGER NULL,
date_disposal DATETIME NULL,
description LONGTEXT NULL,
status_disposal TEXT NULL,
created_at TIMESTAMP NULL,
updated_at TIMESTAMP NULL,
deleted_at TIMESTAMP NULL,
created_by TEXT NULL,
updated_by TEXT NULL
);
""");
// Tambahkan CREATE TABLE untuk tabel-tabel lainnya di sini
}, onUpgrade: (Database db, int oldversion, int newversion) async {
if (oldversion < newversion) {
print("Version Upgrade");
// Tambahkan pernyataan ALTER TABLE jika diperlukan
}
});
print('db initialize');
return openDb;
}
}

117
lib/models/asset_status_model.dart

@ -3,7 +3,10 @@ import 'warehouse_mode.dart';
class AssetStatusModel {
int? id;
String? mobile_id;
int? peti_id;
int? customer_id;
int? warehouse_id;
DateTime? exit_at;
String? exit_pic;
int? exit_warehouse;
@ -11,16 +14,23 @@ class AssetStatusModel {
String? enter_pic;
int? enter_warehouse;
DateTime? est_pengembalian;
String? kondisi_peti;
int? kondisi_peti_id;
// int? status;
String? created_by;
String? updated_by;
PetiAssetModel? peti;
WarehouseModel? warehouse;
WarehouseEnterModel? warehouse_enter;
DateTime? created_at;
DateTime? updated_at;
DateTime? deleted_at;
// PetiAssetModel? peti;
// WarehouseModel? warehouse;
// WarehouseEnterModel? warehouse_enter;
AssetStatusModel({
this.id,
required this.id,
this.mobile_id,
this.peti_id,
this.customer_id,
this.warehouse_id,
this.exit_at,
this.exit_pic,
this.exit_warehouse,
@ -28,64 +38,85 @@ class AssetStatusModel {
this.enter_pic,
this.enter_warehouse,
this.est_pengembalian,
this.kondisi_peti,
this.kondisi_peti_id,
// this.status,
this.created_by,
this.updated_by,
this.peti,
this.warehouse,
this.warehouse_enter,
this.created_at,
this.updated_at,
this.deleted_at,
// this.peti,
// this.warehouse,
// this.warehouse_enter,
});
factory AssetStatusModel.fromJson(Map<String, dynamic> json) {
return AssetStatusModel(
id: json['id'],
peti_id: json['peti_id'] != null
? int.parse(json['peti_id'].toString())
: null,
exit_at: json['exit_at'] != null ? DateTime.parse(json['exit_at']) : null,
id: json['id'] != null ? int.parse(json['id'].toString()) : 0,
mobile_id: json['mobile_id'].toString(),
peti_id:
json['peti_id'] != null ? int.parse(json['peti_id'].toString()) : 0,
customer_id: json['customer_id'] != null
? int.parse(json['customer_id'].toString())
: 0,
warehouse_id: json['warehouse_id'] != null
? int.parse(json['warehouse_id'].toString())
: 0,
exit_at: parseDateTime(json['exit_at']),
exit_pic: json['exit_pic'],
exit_warehouse: json['exit_warehouse'] != null
? int.parse(json['exit_warehouse'].toString())
: null,
enter_at:
json['enter_at'] != null ? DateTime.parse(json['enter_at']) : null,
enter_pic: json['enter_pic'] != null ? json['enter_pic'] : null,
: 0,
enter_at: parseDateTime(json['enter_at']),
enter_pic: json['enter_pic'],
enter_warehouse: json['enter_warehouse'] != null
? int.parse(json['enter_warehouse'].toString())
: null,
est_pengembalian: json['est_pengembalian'] != null
? DateTime.parse(json['est_pengembalian'])
: null,
kondisi_peti:
json['kondisi_peti'] != null ? json['kondisi_peti'] : 'null',
created_by: json['created_by'] != null ? json['created_by'] : 'null',
updated_by: json['updated_by'] != null ? json['updated_by'] : 'null',
peti: PetiAssetModel.fromJson(json['peti'] != null ? json['peti'] : null),
warehouse: WarehouseModel.fromJson(json['warehouse'] != null
? json['warehouse']
: {'id': 0, 'name': 'null'}),
warehouse_enter: WarehouseEnterModel.fromJson(
json['warehouse_enter'] != null
? json['warehouse_enter']
: {'id': 0, 'name': 'null'}),
: 0,
est_pengembalian: parseDateTime(json['est_pengembalian']),
kondisi_peti_id: json['kondisi_peti_id'] != null
? int.parse(json['kondisi_peti_id'].toString())
: 0,
created_by: json['created_by'] ?? 'null',
updated_by: json['updated_by'] ?? 'null',
created_at: parseDateTime(json['created_at']),
updated_at: parseDateTime(json['updated_at']),
deleted_at: parseDateTime(json['deleted_at']),
);
}
Map<String, dynamic> toJson() => {
'id': id,
'mobile_id': mobile_id.toString(),
'peti_id': peti_id,
'exit_at': exit_at,
'exit_pic': exit_pic,
'customer_id': customer_id,
'warehouse_id': warehouse_id,
'exit_at': exit_at?.toIso8601String(),
'exit_pic': exit_pic.toString(),
'exit_warehouse': exit_warehouse,
'enter_at': enter_at,
'enter_at': enter_at?.toIso8601String(),
'enter_pic': enter_pic,
'enter_warehouse': enter_warehouse,
'est_pengembalian': est_pengembalian,
'kondisi_peti': kondisi_peti,
'enter_warehouse': enter_warehouse?.toString(),
'est_pengembalian': est_pengembalian?.toIso8601String(),
'kondisi_peti_id': kondisi_peti_id,
// 'status': status.toString(),
'created_by': created_by,
'updated_by': updated_by,
'peti': peti!.toJson(),
'warehouse': warehouse!.toJson(),
'warehouse_enter': warehouse_enter!.toJson(),
'created_at': created_at?.toIso8601String(),
'updated_at': updated_at?.toIso8601String(),
'deleted_at': deleted_at?.toIso8601String(),
// 'peti': peti!.toJson(),
// 'warehouse': warehouse!.toJson(),
// 'warehouse_enter': warehouse_enter!.toJson(),
};
static DateTime? parseDateTime(String? dateTimeString) {
if (dateTimeString != null && dateTimeString.isNotEmpty) {
try {
return DateTime.parse(dateTimeString);
} catch (e) {
print('Error parsing DateTime: $e');
}
}
return null;
}
}

56
lib/models/condition_peti_model.dart

@ -0,0 +1,56 @@
class ConditionPetiModel {
int? id;
String? nama_kondisi;
String? deskripsi_kondisi;
DateTime? created_at;
DateTime? updated_at;
DateTime? deleted_at;
String? created_by;
String? updated_by;
ConditionPetiModel({
this.id,
this.nama_kondisi,
this.deskripsi_kondisi,
this.created_at,
this.updated_at,
this.deleted_at,
this.created_by,
this.updated_by,
});
factory ConditionPetiModel.fromJson(Map<String, dynamic> json) {
return ConditionPetiModel(
id: json['id'],
nama_kondisi: json['nama_kondisi'],
deskripsi_kondisi: json['deskripsi_kondisi'],
created_at: parseDateTime(json['created_at']),
updated_at: parseDateTime(json['updated_at']),
deleted_at: parseDateTime(json['deleted_at']),
created_by: json['created_by'].toString(),
updated_by: json['updated_by'].toString(),
);
}
Map<String, dynamic> toJson() => {
'id': id,
'nama_kondisi': nama_kondisi,
'deskripsi_kondisi': deskripsi_kondisi,
'created_by': created_by.toString(),
'updated_by': updated_by.toString(),
'created_at': created_at?.toIso8601String(),
'updated_at': updated_at?.toIso8601String(),
'deleted_at': deleted_at?.toIso8601String(),
};
static DateTime? parseDateTime(String? dateTimeString) {
if (dateTimeString != null && dateTimeString.isNotEmpty) {
try {
return DateTime.parse(dateTimeString);
} catch (e) {
print('Error parsing DateTime: $e');
}
}
return null;
}
}

62
lib/models/customer_model.dart

@ -3,26 +3,32 @@ class CustomerModel {
String? name;
String? code_customer;
String? lot_no;
String? nip;
String? no_hp;
DateTime? tgl_lahir;
String? jenis_kelamin;
String? agama;
// String? nip;
// String? no_hp;
// DateTime? tgl_lahir;
// String? jenis_kelamin;
// String? agama;
String? created_by;
String? updated_by;
DateTime? created_at;
DateTime? updated_at;
DateTime? deleted_at;
CustomerModel({
this.id,
this.name,
this.code_customer,
this.lot_no,
this.nip,
this.no_hp,
this.tgl_lahir,
this.jenis_kelamin,
this.agama,
// this.nip,
// this.no_hp,
// this.tgl_lahir,
// this.jenis_kelamin,
// this.agama,
this.created_by,
this.updated_by,
this.created_at,
this.updated_at,
this.deleted_at,
});
factory CustomerModel.fromJson(Map<String, dynamic> json) {
@ -32,15 +38,24 @@ class CustomerModel {
code_customer:
json['code_customer'] != null ? json['code_customer'] : null,
lot_no: json['lot_no'] != null ? json['lot_no'] : null,
nip: json['nip'] != null ? json['nip'] : null,
no_hp: json['no_hp'] != null ? json['no_hp'] : null,
tgl_lahir:
json['tgl_lahir'] != null ? DateTime.parse(json['tgl_lahir']) : null,
jenis_kelamin:
json['jenis_kelamin'] != null ? json['jenis_kelamin'] : null,
agama: json['agama'] != null ? json['agama'] : null,
// nip: json['nip'] != null ? json['nip'] : null,
// no_hp: json['no_hp'] != null ? json['no_hp'] : null,
// tgl_lahir:
// json['tgl_lahir'] != null ? DateTime.parse(json['tgl_lahir']) : null,
// jenis_kelamin:
// json['jenis_kelamin'] != null ? json['jenis_kelamin'] : null,
// agama: json['agama'] != null ? json['agama'] : null,
created_by: json['created_by'] != null ? json['created_by'] : null,
updated_by: json['updated_by'] != null ? json['updated_by'] : null,
created_at: json['created_at'] != null
? DateTime.parse(json['created_at'])
: null,
updated_at: json['updated_at'] != null
? DateTime.parse(json['updated_at'])
: null,
deleted_at: json['deleted_at'] != null
? DateTime.parse(json['deleted_at'])
: null,
);
}
@ -49,12 +64,15 @@ class CustomerModel {
'name': name,
'code_customer': code_customer,
'lot_no': lot_no,
'nip': nip,
'no_hp': no_hp,
'tgl_lahir': tgl_lahir,
'jenis_kelamin': jenis_kelamin,
'agama': agama,
// 'nip': nip,
// 'no_hp': no_hp,
// 'tgl_lahir': tgl_lahir,
// 'jenis_kelamin': jenis_kelamin,
// 'agama': agama,
'created_by': created_by,
'updated_by': updated_by,
'created_at': created_at,
'updated_at': updated_at,
'deleted_at': deleted_at,
};
}

84
lib/models/disposal_model.dart

@ -0,0 +1,84 @@
class DisposalPetiModel {
int? id;
String? mobile_id;
int? peti_id;
int? customer_id;
int? warehouse_id;
DateTime? date_disposal;
String? description;
String? status_disposal;
DateTime? created_at;
DateTime? updated_at;
DateTime? deleted_at;
String? created_by;
String? updated_by;
DisposalPetiModel({
this.id,
this.mobile_id,
this.peti_id,
this.customer_id,
this.warehouse_id,
this.date_disposal,
this.description,
this.status_disposal,
this.created_at,
this.updated_at,
this.deleted_at,
this.created_by,
this.updated_by,
});
factory DisposalPetiModel.fromJson(Map<String, dynamic> json) =>
DisposalPetiModel(
id: json['id'],
mobile_id:
json['mobile_id'] != null ? json['mobile_id'].toString() : null,
peti_id: json['peti_id'] != null
? int.parse(json['peti_id'].toString())
: null,
customer_id: json['customer_id'] != null
? int.parse(json['customer_id'].toString())
: null,
warehouse_id: json['warehouse_id'] != null
? int.parse(json['warehouse_id'].toString())
: null,
date_disposal: json['date_disposal'] != null
? DateTime.parse(json['date_disposal'])
: null,
description:
json['description'] != null ? json['description'].toString() : null,
status_disposal: json['status_disposal'] != null
? json['status_disposal'].toString()
: null,
created_at: json['created_at'] != null
? DateTime.parse(json['created_at'])
: null,
updated_at: json['updated_at'] != null
? DateTime.parse(json['updated_at'])
: null,
deleted_at: json['deleted_at'] != null
? DateTime.parse(json['deleted_at'])
: null,
created_by:
json['created_by'] != null ? json['created_by'].toString() : null,
updated_by:
json['updated_by'] != null ? json['updated_by'].toString() : null,
);
Map<String, dynamic> toJson() => {
"id": id,
"mobile_id": mobile_id,
"peti_id": peti_id,
"customer_id": customer_id,
"warehouse_id": warehouse_id,
"date_disposal": date_disposal,
"description": description,
"status_disposal": status_disposal,
"created_at": created_at,
"updated_at": updated_at,
"deleted_at": deleted_at,
"created_by": created_by,
"updated_by": updated_by,
};
}

89
lib/models/m_asset_status_model.dart

@ -4,47 +4,56 @@ import 'package:siopas/models/warehouse_mode.dart';
class PetiAssetModel {
int? id;
String? tipe_peti_id;
int? tipe_peti_id;
String? warna;
String? fix_lot;
final String fix_lot;
int? packing_no;
int? customer_id;
int? warehouse_id;
int? jumlah;
DateTime? date_pembuatan;
WarehouseModel? warehouse;
TypePetiModel? tipe_peti;
CustomerModel? customer;
int? warehouse_id;
int? kondisipeti_id;
String? status;
// WarehouseModel? warehouse;
// TypePetiModel? tipe_peti;
// CustomerModel? customer;
String? status_disposal;
String? created_by;
String? updated_by;
// late WarehouseModel warehouse;
DateTime? created_at;
DateTime? updated_at;
DateTime? deleted_at;
PetiAssetModel({
this.id,
this.tipe_peti_id,
this.warna,
this.fix_lot,
required this.fix_lot,
this.packing_no,
this.customer_id,
this.warehouse_id,
this.jumlah,
this.date_pembuatan,
this.warehouse,
this.tipe_peti,
this.customer,
this.status_disposal,
// this.warehouse,
// this.tipe_peti,
// this.customer,
this.warehouse_id,
this.kondisipeti_id,
this.status,
this.created_by,
this.updated_by,
this.created_at,
this.updated_at,
this.deleted_at,
// required this.warehouse,
});
factory PetiAssetModel.fromJson(Map<String, dynamic> json) {
return PetiAssetModel(
id: json['id'],
tipe_peti_id: json['tipe_peti_id'],
warna: json['warna'],
tipe_peti_id: json['tipe_peti_id'] != null
? int.parse(json['tipe_peti_id'].toString())
: null,
warna: json['warna'] != null ? json['warna'].toString() : null,
fix_lot: json['fix_lot'],
packing_no: json['packing_no'] != null
? int.parse(json['packing_no'].toString())
@ -55,25 +64,39 @@ class PetiAssetModel {
warehouse_id: json['warehouse_id'] != null
? int.parse(json['warehouse_id'].toString())
: null,
kondisipeti_id: json['kondisipeti_id'] != null
? int.parse(json['kondisipeti_id'].toString())
: null,
status: json['status'] != null ? json['status'].toString() : null,
jumlah:
json['jumlah'] != null ? int.parse(json['jumlah'].toString()) : null,
date_pembuatan: DateTime.parse(json['date_pembuatan']),
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'])
date_pembuatan: json['date_pembuatan'] != null
? DateTime.parse(json['date_pembuatan'].toString())
: null,
status_disposal: json['status_disposal'],
// 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'],
updated_by: json['updated_by'] != null
? json['updated_by'].toString()
: json['updated_by'],
created_at: json['created_at'] != null
? DateTime.parse(json['created_at'].toString())
: DateTime.now(),
updated_at: json['updated_at'] != null
? DateTime.parse(json['updated_at'].toString())
: DateTime.now(),
deleted_at: json['deleted_at'] != null
? DateTime.parse(json['deleted_at'].toString())
: DateTime.now(),
);
}
@ -81,17 +104,21 @@ class PetiAssetModel {
'id': id,
'tipe_peti_id': tipe_peti_id,
'warna': warna,
'fix_lot': fix_lot,
'fix_lot': fix_lot.toString(),
'packing_no': packing_no,
'customer_id': customer_id,
'warehouse_id': warehouse_id,
'kondisipeti_id': kondisipeti_id,
'status': status,
'jumlah': jumlah,
'date_pembuatan': date_pembuatan!.toIso8601String(),
'warehouse': warehouse!.toJson(),
'tipe_peti': tipe_peti!.toJson(),
'customer': customer!.toJson(),
'status_disposal': status_disposal,
// '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(),
'updated_at': updated_at!.toIso8601String(),
'deleted_at': deleted_at!.toIso8601String(),
};
}

84
lib/models/transfer_peti_model.dart

@ -0,0 +1,84 @@
class TransferPetiModel {
int? id;
String? mobile_id;
int? peti_id;
int? name_customer;
int? source_warehouse;
int? destination_warehouse;
DateTime? date;
String? created_by;
String? updated_by;
DateTime? created_at;
DateTime? updated_at;
DateTime? deleted_at;
TransferPetiModel({
this.id,
this.mobile_id,
this.peti_id,
this.name_customer,
this.source_warehouse,
this.destination_warehouse,
this.date,
this.created_by,
this.updated_by,
this.created_at,
this.updated_at,
this.deleted_at,
});
factory TransferPetiModel.fromJson(Map<String, dynamic> json) {
return TransferPetiModel(
id: json['id'],
mobile_id: json['mobile_id'] != null ? json['mobile_id'] : null,
peti_id: json['peti_id'] != null
? int.parse(json['peti_id'].toString())
: null,
name_customer: json['name_customer'] != null
? int.parse(json['name_customer'].toString())
: null,
source_warehouse: json['source_warehouse'] != null
? int.parse(json['source_warehouse'].toString())
: null,
destination_warehouse: json['destination_warehouse'] != null
? int.parse(json['destination_warehouse'].toString())
: null,
date: parseDateTime(json['date']),
created_by: json['created_by'] != null ? json['created_by'] : null,
updated_by: json['updated_by'] != null ? json['updated_by'] : null,
created_at: parseDateTime(json['created_at']),
updated_at: parseDateTime(json['updated_at']),
deleted_at: parseDateTime(json['deleted_at']),
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'mobile_id': mobile_id,
'peti_id': peti_id,
'name_customer': name_customer,
'source_warehouse': source_warehouse,
'destination_warehouse': destination_warehouse,
'date': date?.toIso8601String(),
'created_by': created_by,
'updated_by': updated_by,
'created_at': created_at?.toIso8601String(),
'updated_at': updated_at?.toIso8601String(),
'deleted_at': deleted_at?.toIso8601String(),
};
}
static DateTime? parseDateTime(String? dateTimeString) {
if (dateTimeString != null && dateTimeString.isNotEmpty) {
try {
return DateTime.parse(dateTimeString);
} catch (e) {
print('Error parsing DateTime: $e');
}
}
return null;
}
}

2
lib/models/type_peti_model.dart

@ -29,7 +29,7 @@ class TypePetiModel {
}
Map<String, dynamic> toJson() => {
'id': id,
'id': id.toString(),
'type': type,
'size_peti': size_peti,
'description': description,

34
lib/models/user_model.dart

@ -1,12 +1,17 @@
import 'package:flutter/cupertino.dart';
class UserModel {
int? id;
String? id;
String? username;
String? fullname;
String? email;
String? nip;
String? no_hp;
String? jenis_kelamin;
String? address;
String? password;
int? role_id;
int? warehouse_id;
String? token;
UserModel({
@ -14,28 +19,47 @@ class UserModel {
this.username,
this.fullname,
this.email,
this.nip,
this.no_hp,
this.jenis_kelamin,
this.address,
this.password,
this.role_id,
this.warehouse_id,
this.token,
});
UserModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
id = json['id'].toString();
username = json['username'];
fullname = json['fullname'];
email = json['email'];
nip = json['nip'];
no_hp = json['no_hp'];
jenis_kelamin = json['jenis_kelamin'];
address = json['address'];
password = json['password'];
role_id = int.parse(json['role_id'].toString());
role_id =
json['role_id'] != null ? int.parse(json['role_id'].toString()) : null;
warehouse_id = json['warehouse_id'] != null
? int.parse(json['warehouse_id'].toString())
: null;
token = json['token'].toString();
}
Map<String, dynamic> toJson() {
return {
'id': id,
'id': id.toString(),
'username': username,
'email': email,
'fullname': fullname,
'nip': nip,
'no_hp': no_hp,
'jenis_kelamin': jenis_kelamin,
'address': address,
'password': password,
'role_id': role_id,
'role_id': role_id.toString(),
'warehouse_id': warehouse_id.toString(),
'token': token.toString(),
};
}

26
lib/models/warehouse_mode.dart

@ -8,6 +8,10 @@ class WarehouseModel {
String? created_by;
String? updated_by;
DateTime? created_at;
DateTime? updated_at;
DateTime? deleted_at;
WarehouseModel({
this.id,
this.name,
@ -15,19 +19,31 @@ class WarehouseModel {
this.address,
this.created_by,
this.updated_by,
this.created_at,
this.updated_at,
this.deleted_at,
});
WarehouseModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
id = json['id'] != null ? int.parse(json['id'].toString()) : 0;
name = json['name'];
description = json['description'];
address = json['address'];
created_by = json['created_by'];
updated_by = json['updated_by'];
created_at = DateTime.parse(json['created_at'] != null
? json['created_at'].toString()
: DateTime.now().toString());
updated_at = DateTime.parse(json['updated_at'] != null
? json['updated_at'].toString()
: DateTime.now().toString());
deleted_at = DateTime.parse(json['deleted_at'] != null
? json['deleted_at'].toString()
: DateTime.now().toString());
}
Map<String, dynamic> toJson() => {
'id': id,
'id': id.toString(),
'name': name,
'description': description,
'address': address,
@ -37,7 +53,7 @@ class WarehouseModel {
}
class WarehouseEnterModel {
int? id;
String? id;
String? name;
String? description;
String? address;
@ -51,7 +67,7 @@ class WarehouseEnterModel {
factory WarehouseEnterModel.fromJson(Map<String, dynamic> json) {
return WarehouseEnterModel(
id: json['id'],
id: json['id'].toString(),
name: json['name'],
description: json['description'],
address: json['address'],
@ -59,7 +75,7 @@ class WarehouseEnterModel {
}
Map<String, dynamic> toJson() => {
'id': id,
'id': id.toString(),
'name': name,
'description': description,
'address': address,

259
lib/pages/home/conn_home_page.dart/syncronize.dart

@ -0,0 +1,259 @@
import 'dart:convert';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:siopas/models/transfer_peti_model.dart';
import 'package:internet_connection_checker/internet_connection_checker.dart';
import 'package:intl/intl.dart';
import '../../../connection/connection.dart';
import '../../../migrations/databasehelper.dart';
import '../../../models/asset_status_model.dart';
import 'package:http/http.dart' as http;
class SyncronizationGlobalData {
Future<int> addData(AssetStatusModel assetStatusModel) async {
final dbClient = await conn.db;
late int result;
try {
result = await dbClient!.insert(
SqfliteDatabaseHelper.peminjamanTable, assetStatusModel.toJson());
} catch (e) {
print('Error adding data to local SQLite: $e');
result = 0; // Handle the error appropriately
}
return result;
}
Future<List> fetchData() async {
var dbclient = await conn.db;
List assetStatusList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.peminjamanTable, orderBy: 'id DESC');
for (var item in maps) {
assetStatusList.add(item);
}
} catch (e) {
print(e.toString());
}
return assetStatusList;
}
static Future<bool> isInternet() async {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
if (await InternetConnectionChecker().hasConnection) {
print("Mobile data detected & internet connection confirmed.");
return true;
} else {
print('No internet :( Reason:');
return false;
}
} else if (connectivityResult == ConnectivityResult.wifi) {
if (await InternetConnectionChecker().hasConnection) {
print("wifi data detected & internet connection confirmed.");
return true;
} else {
print('No internet :( Reason:');
return false;
}
} else {
print(
"Neither mobile data or WIFI detected, not internet connection found.");
return false;
}
}
final conn = SqfliteDatabaseHelper.instance;
Future<List<AssetStatusModel>> fetchAllPeminjamanInfo() async {
final dbClient = await conn.db;
List<AssetStatusModel> peminjamanList = [];
try {
final maps = await dbClient!.query(SqfliteDatabaseHelper.peminjamanTable);
for (var item in maps) {
peminjamanList.add(AssetStatusModel.fromJson(item));
}
} catch (e) {
print(e.toString());
}
return peminjamanList;
}
Future<List<AssetStatusModel>> fetchAllPengembalianInfo() async {
final dbClient = await conn.db;
List<AssetStatusModel> pengembalianList = [];
try {
final maps =
await dbClient!.query(SqfliteDatabaseHelper.pengembalianTable);
for (var item in maps) {
pengembalianList.add(AssetStatusModel.fromJson(item));
}
} catch (e) {
print(e.toString());
}
return pengembalianList;
}
Future<List<TransferPetiModel>> fetchAllTransferInfo() async {
final dbClient = await conn.db;
List<TransferPetiModel> transferList = [];
try {
final maps =
await dbClient!.query(SqfliteDatabaseHelper.transferPetiTable);
for (var item in maps) {
transferList.add(TransferPetiModel.fromJson(item));
}
} catch (e) {
print(e.toString());
}
return transferList;
}
Future<void> deleteAllPeminjamanData() async {
var dbClient = await conn.db;
await dbClient!.delete(SqfliteDatabaseHelper.peminjamanTable);
}
Future<void> deleteAllPengembalianData() async {
var dbClient = await conn.db;
await dbClient!.delete(SqfliteDatabaseHelper.pengembalianTable);
}
Future<void> deleteAllTransferData() async {
var dbClient = await conn.db;
await dbClient!.delete(SqfliteDatabaseHelper.transferPetiTable);
}
Future saveToMysqlWith(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(),
"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(),
// "status": assetStatusesLocalList[i].status.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<List> fetchAllCustomerInfo() async {
final dbClient = await conn.db;
List contactList = [];
try {
final maps = await dbClient!.query(SqfliteDatabaseHelper.peminjamanTable);
for (var item in maps) {
contactList.add(item);
}
} catch (e) {
print(e.toString());
}
return contactList;
}
Future saveToMysql(List assetStatusesLocalList) async {
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;
}
}
for (var i = 0; i < assetStatusesLocalList.length; i++) {
// 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(),
"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(),
"status": assetStatusesLocalList[i]['status'].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(response.body);
print("Saving Data saveToMysql");
} else {
print(response.statusCode);
}
}
}
Future<List<AssetStatusModel>> fetchFromApi() async {
final response = await http.get(
Uri.parse(await getBaseUrl() + '/asset-status'),
);
if (response.statusCode == 200) {
List<dynamic> data = json.decode(response.body)['data']['asset_status'];
List<AssetStatusModel> contactDBList = data
.map(
(item) => AssetStatusModel.fromJson(item as Map<String, dynamic>))
.toList();
return contactDBList;
} else {
throw Exception('Failed to fetch data from API Asset Status');
}
}
}

62
lib/pages/home/controller/home_controller.dart

@ -0,0 +1,62 @@
import 'dart:async';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:siopas/models/asset_status_model.dart';
import 'package:http/http.dart' as http;
import 'package:internet_connection_checker/internet_connection_checker.dart';
import 'package:sqflite/sqflite.dart';
import '../../../migrations/databasehelper.dart';
class ControllerHome {
final conn = SqfliteDatabaseHelper.instance;
Future<int> getPeminjamanCount() async {
final dbClient = await conn.db;
final count = Sqflite.firstIntValue(await dbClient!
.query(SqfliteDatabaseHelper.peminjamanTable, columns: ['COUNT(*)']));
return count ?? 0;
}
Future<int> getPengembalianCount() async {
final dbClient = await conn.db;
final count = Sqflite.firstIntValue(
await dbClient!.query(SqfliteDatabaseHelper.pengembalianTable,
columns: ['COUNT(*)']),
);
return count ?? 0;
}
Future<int> getTransferCount() async {
final dbClient = await conn.db;
final count = Sqflite.firstIntValue(
await dbClient!.query(SqfliteDatabaseHelper.transferPetiTable,
columns: ['COUNT(*)']),
);
return count ?? 0;
}
static Future<bool> isInternet() async {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
if (await InternetConnectionChecker().hasConnection) {
print("Mobile data detected & internet connection confirmed.");
return true;
} else {
print('No internet :( Reason:');
return false;
}
} else if (connectivityResult == ConnectivityResult.wifi) {
if (await InternetConnectionChecker().hasConnection) {
print("wifi data detected & internet connection confirmed.");
return true;
} else {
print('No internet :( Reason:');
return false;
}
} else {
print(
"Neither mobile data nor WIFI detected, no internet connection found.");
return false;
}
}
}

734
lib/pages/home/home_page.dart

@ -1,14 +1,31 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:siopas/migrations/databasehelper.dart';
import 'package:siopas/models/transfer_peti_model.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../models/asset_status_model.dart';
import '../../models/condition_peti_model.dart';
import '../../models/customer_model.dart';
import '../../models/m_asset_status_model.dart';
import '../../models/type_peti_model.dart';
import '../../models/user_model.dart';
import '../../models/warehouse_mode.dart';
import '../../providers/auth_provider.dart';
import 'package:intl/intl.dart';
import 'package:intl/date_symbol_data_local.dart';
import '../../services/controllerApi.dart';
import '../../services/syncronizeAPI.dart';
import '../../theme.dart';
import '../peminjaman_barang/conn/syncronize.dart';
import '../peminjaman_barang/controller/peminjaman_controller.dart';
import '../pengembalian_barang/conn/syncronize.dart';
import '../transfer_peti/conn/syncronize.dart';
import 'conn_home_page.dart/syncronize.dart';
import 'controller/home_controller.dart';
class HomePage extends StatefulWidget {
@override
@ -17,20 +34,45 @@ class HomePage extends StatefulWidget {
class _HomePageState extends State<HomePage> {
String? token;
// final items = ["Android", "iOS", "Desktop", "Web"];
// final items = ['assets/gps_samara.jpeg'];
final items = [
'https://mypertamina.id/uploads/posts/Survey-Bright-Cafe-2021-1024x576.jpg',
'https://grhaproperti.com/wp-content/uploads/2022/05/banner-survey-on-520.jpg',
'https://grhaproperti.com/wp-content/uploads/2022/05/banner-properti-agent-1-1.jpg'
];
// bool isLoading = true;
bool loading = true;
// Reinit atau Upload Only
WarehouseModel? warehouseSqfliteApi;
List<TypePetiModel>? typePetiSqfliteApi;
List<CustomerModel>? customerSqfliteApi;
PetiAssetModel? petiSqfliteApi;
List<PetiAssetModel>? _valpeti; // Change this line
List<WarehouseModel>? _valwarehouse;
// Datatable
int _currentPage = 1;
int _pageSize = 10;
List<AssetStatusModel>? _data;
List<PetiAssetModel>? _petiData;
List<TypePetiModel>? _tipePetiData;
List<CustomerModel>? _customerData;
List<WarehouseModel>? _warehouseData;
bool _isLoading = false;
Timer? _timer;
@override
void initState() {
super.initState();
initializeDateFormatting("id_ID", null); // Inisialisasi pustaka intl
_getUserToken();
warehouseListAPI();
typePetiListAPI();
customerListAPI();
petiListAPI();
// Tampil data Datatables
datatablesAssetStatusList();
datatablesPetiList();
datatablesTipePetiList();
datatablesCustomerList();
datatablesWarehouseList();
_data = <AssetStatusModel>[];
}
void _getUserToken() async {
@ -38,11 +80,251 @@ class _HomePageState extends State<HomePage> {
if (mounted) {
setState(() {
token = prefs.getString('token');
// getInit(); // Panggil getInit jika token sudah didapatkan
});
}
}
// Reinit atau Upload Only ------------------------------------------------------------------------
Future warehouseListAPI() async {
if (mounted) {
await ControllerApi().fetchWarehouseDataAPI().then((value) {
setState(() {
_valwarehouse = (value as List<dynamic>)
.map((item) => WarehouseModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
Future typePetiListAPI() async {
if (mounted) {
await ControllerApi().fetchTipePetiDataAPI().then((value) {
setState(() {
typePetiSqfliteApi = (value as List<dynamic>)
.map((item) => TypePetiModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
Future customerListAPI() async {
if (mounted) {
await ControllerApi().fetchCustomerDataAPI().then((value) {
setState(() {
customerSqfliteApi = (value as List<dynamic>)
.map((item) => CustomerModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
Future petiListAPI() async {
if (mounted) {
await ControllerApi().fetchPetiDataAPI().then((value) {
setState(() {
_valpeti = (value as List<dynamic>)
.map((item) => PetiAssetModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
Future<void> reinitWarehouseApi() async {
EasyLoading.show(status: 'Mengambil data Warehouse...');
List<WarehouseModel> warehouseApiData =
await SyncronizationDataAPI().fetchWarehouseFromApi();
await ControllerApi()
.deleteAllWarehouseDataAPI(); // Clear existing data in SQLite
await ControllerApi()
.addAllWarehouseDataAPI(warehouseApiData); // Add new data to SQLite
EasyLoading.dismiss();
}
Future<void> reinitPetiApi() async {
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
EasyLoading.dismiss();
}
Future<void> reinitCustomerApi() async {
EasyLoading.show(status: 'Mengambil data Customer...');
List<CustomerModel> customerApiData =
await SyncronizationDataAPI().fetchCustomerFromApi();
await ControllerApi()
.deleteAllCustomerDataAPI(); // Clear existing data in SQLite
await ControllerApi()
.addAllCustomerDataAPI(customerApiData); // Add new data to SQLite
EasyLoading.dismiss();
}
Future<void> reinitConditionPetiApi() async {
EasyLoading.show(status: 'Mengambil data Condition Peti...');
List<ConditionPetiModel> conditionPetiApiData =
await SyncronizationDataAPI().fetchKondisiPetiFromApi();
await ControllerApi()
.deleteAllKondisiPetiDataAPI(); // Clear existing data in SQLite
await ControllerApi().addAllKondisiPetiDataAPI(
conditionPetiApiData); // Add new data to SQLite
EasyLoading.dismiss();
}
Future<void> fetchDataFromApiAndSync() async {
EasyLoading.show(status: 'Mengambil data dari Server...');
try {
// await syncToGlobal();
await syncToGlobal('Peminjaman');
await syncToGlobal('Pengembalian');
await syncToGlobal('Transfer');
// await reinitAssetStatusApi();
await reinitWarehouseApi();
await reinitPetiApi();
await reinitCustomerApi();
// await reinitTypePetiApi();
await reinitConditionPetiApi();
await datatablesAssetStatusList();
EasyLoading.showSuccess('Data berhasil diperbarui');
} catch (e) {
EasyLoading.showError('Gagal memperbarui data: $e');
} finally {
EasyLoading.dismiss();
}
}
Future syncToGlobal(String type) async {
try {
EasyLoading.show(
status: 'Jangan tutup aplikasi. Kami sedang menyinkronkan...');
await Future.delayed(Duration(seconds: 3));
// Tambahkan penanganan pengunggahan
bool uploadSuccess = false; // Berikan nilai awal false
if (type == 'Peminjaman') {
List<AssetStatusModel> peminjamanList =
await SyncronizationGlobalData().fetchAllPeminjamanInfo();
uploadSuccess = await SyncronizationPeminjamanData()
.saveToPeminjamanWith(peminjamanList);
// Jika pengunggahan berhasil, hapus data lokal Peminjaman
if (uploadSuccess) {
await SyncronizationGlobalData().deleteAllPeminjamanData();
}
} else if (type == 'Pengembalian') {
List<AssetStatusModel> pengembalianList =
await SyncronizationGlobalData().fetchAllPengembalianInfo();
uploadSuccess = await SyncronizationPengembalianData()
.savePengembalianToServerWith(pengembalianList);
// Jika pengunggahan berhasil, hapus data lokal Pengembalian
if (uploadSuccess) {
await SyncronizationGlobalData().deleteAllPengembalianData();
}
} else if (type == 'Transfer') {
List<TransferPetiModel> transferPetiList =
await SyncronizationGlobalData().fetchAllTransferInfo();
uploadSuccess = await SyncronizationTransferPetiData()
.saveTransferPetiServerWith(transferPetiList);
// Jika pengunggahan berhasil, hapus data lokal Pengembalian
if (uploadSuccess) {
await SyncronizationGlobalData().deleteAllTransferData();
}
}
// Setelah selesai, tampilkan pesan sukses atau gagal
if (uploadSuccess) {
EasyLoading.showSuccess('Berhasil disinkronkan dengan Server');
} else {
EasyLoading.showError('Gagal disinkronkan dengan Server');
}
} catch (error) {
// Handle error jika terjadi
EasyLoading.showError('Terjadi kesalahan: $error');
}
}
Future<void> isInteret() async {
await SyncronizationGlobalData.isInternet().then((connection) {
if (connection) {
print("Internet connection available");
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("No Internet")));
}
});
}
// Datatables ------------------------------------------------------------------------
Future datatablesAssetStatusList() async {
await Controller().fetchAssetStatusLocalController().then((value) {
setState(() {
_data = (value as List<dynamic>)
.map((e) => AssetStatusModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesPetiList() async {
await Controller().fetchPetiData().then((value) {
setState(() {
_petiData = (value as List<dynamic>)
.map((e) => PetiAssetModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesTipePetiList() async {
await Controller().fetchTipePetiData().then((value) {
setState(() {
_tipePetiData = (value as List<dynamic>)
.map((e) => TypePetiModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesCustomerList() async {
await Controller().fetchCustomerData().then((value) {
setState(() {
_customerData = (value as List<dynamic>)
.map((e) => CustomerModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesWarehouseList() async {
await Controller().fetchWarehouseData().then((value) {
setState(() {
_warehouseData = (value as List<dynamic>)
.map((e) => WarehouseModel.fromJson(e))
.toList();
loading = false;
});
});
}
@override
void dispose() {
// Memastikan untuk membatalkan timer saat widget di-dispose
@ -55,156 +337,6 @@ class _HomePageState extends State<HomePage> {
UserModel user = authProvider.user;
// String? token = authProvider.token;
Widget header() {
return Container(
margin: EdgeInsets.only(
top: defaultMargin,
left: 10,
right: 10,
bottom: 15.5,
),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Hallo, ${user.email}',
style: primaryTextStyle.copyWith(
fontSize: 16,
fontWeight: semiBold,
),
),
Text(
'${user.email}',
style: subtitleTextStyle.copyWith(
fontSize: 14,
),
),
],
),
),
Stack(
children: [
GestureDetector(
onTap: () {
// Tambahkan aksi yang ingin Anda lakukan ketika ikon notifikasi diklik di sini
},
child: Icon(
Icons
.notifications, // Ubah ikon notifikasi sesuai kebutuhan
size: 30,
color: Colors.blue[700], // Ubah warna sesuai kebutuhan
),
),
Positioned(
right: 0,
top: 0,
child: Container(
padding: EdgeInsets.all(4),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.red, // Warna latar belakang notifikasi
),
child: Text(
'1', // Jumlah notifikasi (Anda dapat mengubahnya sesuai kebutuhan)
style: TextStyle(
color: Colors.white, // Warna teks notifikasi
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
],
),
);
}
Widget subHeader() {
return Card(
margin: EdgeInsets.only(
top: 10,
left: 10,
right: 10,
),
child: Container(
padding: EdgeInsets.all(15),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Pengumuman',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
Text(
DateFormat('dd MMMM yyyy', 'id_ID').format(DateTime.now()),
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
],
),
SizedBox(height: 10),
Text(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec euismod, nisl eget aliquet ultricies, nunc nisl aliquam nisl, vitae aliquam nisl nisl eget nisl. Donec euismod, nisl eget aliquet ultricies, nunc nisl aliquam nisl, vitae aliquam nisl nisl eget nisl.',
style: TextStyle(
fontSize: 11.5,
),
),
],
),
),
);
}
Widget titleMenu() {
return Container(
margin: EdgeInsets.only(
top: 5,
left: 10,
right: 10,
bottom: 5,
),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Menu Apps',
style: primaryTextStyle.copyWith(
fontSize: 16,
fontWeight: semiBold,
),
),
Text(
'See All',
style: TextStyle(fontSize: 12, color: Colors.blue[700]),
),
],
),
],
),
),
],
),
);
}
Widget cardMenuPeminjaman() {
return Container(
margin: EdgeInsets.all(10),
@ -352,82 +484,161 @@ class _HomePageState extends State<HomePage> {
);
}
Widget cardRow() {
Widget _buildCountTile(IconData icon, int count, Color color, String text) {
return Column(
children: [
Row(
children: [
cardTotal('PENGADAAN', 0, Icons.shopping_cart),
cardTotal('PEMINJAMAN', 0, Icons.shopping_basket),
],
CircleAvatar(
backgroundColor: color,
radius: 12,
child: Icon(icon, size: 12, color: Colors.white),
),
SizedBox(height: 5),
Row(
children: [
cardTotal('PENGEMBALIAN', 0, Icons.reply),
cardTotal('REMINDER PENGEMBALIAN', 0, Icons.access_alarm),
],
SizedBox(height: 4),
Text(
text,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
Text(
'$count',
style: TextStyle(fontSize: 12),
),
],
);
}
Widget _buildDrawer() {
return SizedBox(
//membuat menu drawer
child: Drawer(
//membuat list,
//list digunakan untuk melakukan scrolling jika datanya terlalu panjang
child: ListView(
padding: EdgeInsets.zero,
//di dalam listview ini terdapat beberapa widget drawable
children: [
UserAccountsDrawerHeader(
//membuat gambar profil
currentAccountPicture: Image(
image: NetworkImage(
"https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png")),
//membuat nama akun
accountName: Text("Sahretech"),
//membuat nama email
accountEmail: Text("ig: @sahretech"),
//memberikan background
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
"https://cdn.pixabay.com/photo/2016/04/24/20/52/laundry-1350593_960_720.jpg"),
fit: BoxFit.cover)),
),
//membuat list menu
ListTile(
leading: Icon(Icons.home),
title: Text("Beranda"),
onTap: () {},
),
ListTile(
leading: Icon(Icons.people),
title: Text("Pegawai"),
onTap: () {},
),
ListTile(
leading: Icon(Icons.money),
title: Text("Transaksi"),
onTap: () {},
),
Divider(),
ListTile(
leading: Icon(Icons.emoji_emotions),
title: Text("Profil"),
onTap: () {},
),
ListTile(
leading: Icon(Icons.info),
title: Text("Tentang"),
onTap: () {},
),
],
),
),
Future<void> showSyncDialog(BuildContext context) async {
// Create an instance of ControllerHome
ControllerHome controllerHome = ControllerHome();
// Fetch counts from the ControllerHome
int peminjamanCount = await controllerHome.getPeminjamanCount();
int pengembalianCount = await controllerHome.getPengembalianCount();
int transferCount = await controllerHome.getTransferCount();
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
// Dialog shape and style
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
backgroundColor: Colors.grey[100],
elevation: 0,
// Dialog content
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Dialog title with close button
Container(
width: double.infinity,
color: Colors.indigo[700], // Indigo background
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
"Sync Server Global",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 20.0,
),
),
),
IconButton(
icon: Icon(
Icons.close,
color: Colors.white,
),
onPressed: () {
Navigator.pop(context); // Close dialog
},
),
],
),
),
Divider(
height: 1,
thickness: 1,
color: Colors.black, // Black divider
),
// Display counts for each table
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildCountTile(Icons.vertical_align_top, peminjamanCount,
Colors.green[700]!, 'Peminjaman'),
_buildCountTile(Icons.vertical_align_bottom,
pengembalianCount, Colors.blue[700]!, 'Pengembalian'),
_buildCountTile(Icons.input_outlined, transferCount,
Colors.yellow[700]!, 'Transfer'),
],
),
SizedBox(height: 10),
// Divider
Divider(
height: 1,
thickness: 1,
color: Colors.black, // Black divider
),
// Re-init Button
Container(
width: double.infinity,
child: TextButton(
onPressed: () {
Navigator.pop(context); // Close dialog
fetchDataFromApiAndSync();
},
child: Text(
"Upload + Download",
style: TextStyle(
color: Colors.black,
fontSize: 16.0,
fontFamily: 'Poppins',
),
),
),
),
// Divider
// Divider(
// height: 1,
// thickness: 1,
// color: Colors.black, // Black divider
// ),
// Upload Only Button
// Container(
// width: double.infinity,
// child: TextButton(
// onPressed: () {
// Navigator.pop(context); // Close dialog
// syncToGlobal('Peminjaman');
// syncToGlobal('Pengembalian');
// syncToGlobal('Transfer');
// },
// child: Text(
// "Upload Only",
// style: TextStyle(
// color: Colors.black,
// fontSize: 16.0,
// fontFamily: 'Poppins',
// ),
// ),
// ),
// ),
],
),
);
},
);
}
@ -437,6 +648,24 @@ class _HomePageState extends State<HomePage> {
elevation: 0,
automaticallyImplyLeading: false,
backgroundColor: Colors.indigo[700],
actions: [
IconButton(
icon: Icon(
Icons.cloud_sync,
size: 30,
),
onPressed: () async {
if (await SyncronizationGlobalData.isInternet()) {
// Display custom dialog when the IconButton is pressed
showSyncDialog(context);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("No internet connection")),
);
}
},
),
],
title: Row(
children: [
SizedBox(width: 10),
@ -445,7 +674,7 @@ class _HomePageState extends State<HomePage> {
child: Column(
children: [
Text(
'Beranda',
'SIOPAS-ISTW',
textAlign: TextAlign.center,
),
Text(
@ -460,54 +689,9 @@ class _HomePageState extends State<HomePage> {
),
],
),
// actions: [
// Align(
// alignment: Alignment.center,
// child: Stack(
// children: [
// GestureDetector(
// onTap: () {
// // Tambahkan aksi yang diinginkan saat ikon ditekan
// },
// child: Icon(
// Icons.notifications,
// color: Colors.white,
// size: 30,
// ),
// ),
// Positioned(
// right: 0,
// top: 0,
// child: Container(
// padding: EdgeInsets.all(4),
// decoration: BoxDecoration(
// shape: BoxShape.circle,
// color: Colors.red, // Warna latar belakang notifikasi
// ),
// child: Text(
// '5',
// style: TextStyle(
// color: Colors.white, // Warna teks notifikasi
// fontSize: 12,
// fontWeight: FontWeight.bold,
// ),
// ),
// ),
// ),
// ],
// ),
// ),
// SizedBox(width: 10),
// ],
),
// drawer: _buildDrawer(),
body: ListView(
children: [
// header(),
// subHeader(),
// SizedBox(height: 10),
// cardRow(),
// titleMenu(),
GridView.count(
crossAxisCount: 2,
shrinkWrap: true,

2
lib/pages/home/main_page.dart

@ -67,7 +67,7 @@ class _MainPageState extends State<MainPage> {
// label: 'Receive',
// ),
BottomNavigationBarItem(
icon: Icon(Icons.person),
icon: Icon(Icons.settings),
label: 'Pengaturan',
),
],

4
lib/pages/home/setting_page.dart

@ -163,7 +163,7 @@ class SettingPageState extends State<SettingPage> {
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.indigo[700],
title: const Text("Settings"),
title: const Text("Pengaturan"),
automaticallyImplyLeading: false,
),
body: Center(
@ -182,7 +182,7 @@ class SettingPageState extends State<SettingPage> {
_SingleSection(
children: [
_Logout(
title: "Sign out",
title: "Keluar",
icon: Icons.exit_to_app_rounded,
handleLogout: handleGetLogout,
),

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

@ -0,0 +1,222 @@
import 'dart:convert';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:internet_connection_checker/internet_connection_checker.dart';
import 'package:intl/intl.dart';
import '../../../connection/connection.dart';
import '../../../migrations/databasehelper.dart';
import '../../../models/asset_status_model.dart';
import 'package:http/http.dart' as http;
class SyncronizationPeminjamanData {
Future<int> addData(AssetStatusModel assetStatusModel) async {
final dbClient = await conn.db;
late int result;
try {
result = await dbClient!.insert(
SqfliteDatabaseHelper.peminjamanTable, assetStatusModel.toJson());
} catch (e) {
print('Error adding data to local SQLite: $e');
result = 0; // Handle the error appropriately
}
return result;
}
Future<List> fetchData() async {
var dbclient = await conn.db;
List assetStatusList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.peminjamanTable, orderBy: 'id DESC');
for (var item in maps) {
assetStatusList.add(item);
}
} catch (e) {
print(e.toString());
}
return assetStatusList;
}
static Future<bool> isInternet() async {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
if (await InternetConnectionChecker().hasConnection) {
print("Mobile data detected & internet connection confirmed.");
return true;
} else {
print('No internet :( Reason:');
return false;
}
} else if (connectivityResult == ConnectivityResult.wifi) {
if (await InternetConnectionChecker().hasConnection) {
print("wifi data detected & internet connection confirmed.");
return true;
} else {
print('No internet :( Reason:');
return false;
}
} else {
print(
"Neither mobile data or WIFI detected, not internet connection found.");
return false;
}
}
final conn = SqfliteDatabaseHelper.instance;
Future<List<AssetStatusModel>> fetchAllInfo() async {
final dbClient = await conn.db;
List<AssetStatusModel> assetStatusList = [];
try {
final maps = await dbClient!.query(SqfliteDatabaseHelper.peminjamanTable);
for (var item in maps) {
assetStatusList.add(AssetStatusModel.fromJson(item));
}
} catch (e) {
print(e.toString());
}
return assetStatusList;
}
Future<void> deleteAllAssetStatusData() async {
var dbClient = await conn.db;
await dbClient!.delete(SqfliteDatabaseHelper.peminjamanTable);
}
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<List> fetchAllCustomerInfo() async {
final dbClient = await conn.db;
List contactList = [];
try {
final maps = await dbClient!.query(SqfliteDatabaseHelper.peminjamanTable);
for (var item in maps) {
contactList.add(item);
}
} catch (e) {
print(e.toString());
}
return contactList;
}
Future saveToMysql(List assetStatusesLocalList) async {
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;
}
}
for (var i = 0; i < assetStatusesLocalList.length; i++) {
// 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(),
"status": assetStatusesLocalList[i]['status'].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(response.body);
print("Saving Data saveToMysql");
} else {
print(response.statusCode);
}
}
}
Future<List<AssetStatusModel>> fetchFromApi() async {
final response = await http.get(
Uri.parse(await getBaseUrl() + '/asset-status'),
);
if (response.statusCode == 200) {
List<dynamic> data = json.decode(response.body)['data']['asset_status'];
List<AssetStatusModel> contactDBList = data
.map(
(item) => AssetStatusModel.fromJson(item as Map<String, dynamic>))
.toList();
return contactDBList;
} else {
throw Exception('Failed to fetch data from API Asset Status');
}
}
}

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

@ -0,0 +1,204 @@
import 'dart:async';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:siopas/models/asset_status_model.dart';
import 'package:http/http.dart' as http;
import 'package:internet_connection_checker/internet_connection_checker.dart';
import 'package:sqflite/sqflite.dart';
import '../../../migrations/databasehelper.dart';
class Controller {
final conn = SqfliteDatabaseHelper.instance;
Future<List<AssetStatusModel>> fetchAllPeminjamanInfo() async {
final dbClient = await conn.db;
List<AssetStatusModel> assetStatusList = [];
try {
final maps = await dbClient!.query(SqfliteDatabaseHelper.peminjamanTable);
for (var item in maps) {
assetStatusList.add(AssetStatusModel.fromJson(item));
}
} catch (e) {
print(e.toString());
}
return assetStatusList;
}
static Future<bool> isInternet() async {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
if (await InternetConnectionChecker().hasConnection) {
print("Mobile data detected & internet connection confirmed.");
return true;
} else {
print('No internet :( Reason:');
return false;
}
} else if (connectivityResult == ConnectivityResult.wifi) {
if (await InternetConnectionChecker().hasConnection) {
print("wifi data detected & internet connection confirmed.");
return true;
} else {
print('No internet :( Reason:');
return false;
}
} else {
print(
"Neither mobile data or WIFI detected, not internet connection found.");
return false;
}
}
Future<int> addPeminjamanData(AssetStatusModel peminjamanAddModel) async {
var dbclient = await conn.db;
int result = 0; // Provide an initial value
try {
result = await dbclient!.insert(
SqfliteDatabaseHelper.peminjamanTable, peminjamanAddModel.toJson());
} catch (e) {
print(e.toString());
}
return result;
}
Future<int> updatePeminjamanData(AssetStatusModel peminjamanAddModel) async {
var dbclient = await conn.db;
late int result;
try {
result = await dbclient!.update(
SqfliteDatabaseHelper.peminjamanTable,
peminjamanAddModel.toJson(),
where: 'id=?',
whereArgs: [peminjamanAddModel.id],
);
} catch (e) {
print(e.toString());
}
return result;
}
Future<List> fetchAssetStatusLocalController() async {
var dbclient = await conn.db;
List peminjamanStatusList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.peminjamanTable, orderBy: 'id DESC');
for (var item in maps) {
peminjamanStatusList.add(item);
}
} catch (e) {
print(e.toString());
}
return peminjamanStatusList;
}
Future<List<AssetStatusModel>> fetchPeminjamanDataId() async {
var dbclient = await conn.db;
List<AssetStatusModel> peminjamanList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.peminjamanTable, orderBy: 'id DESC');
for (var item in maps) {
peminjamanList.add(AssetStatusModel.fromJson(item));
}
} catch (e) {
print(e.toString());
}
return peminjamanList;
}
Future<void> deleteAllData() async {
var dbClient = await conn.db;
await dbClient!.delete(SqfliteDatabaseHelper.peminjamanTable);
}
Future<void> addAllData(List<AssetStatusModel> contactList) async {
var dbclient = await conn.db;
Batch batch = dbclient!.batch();
for (var contact in contactList) {
batch.insert(
SqfliteDatabaseHelper.peminjamanTable,
contact.toJson(),
);
}
await batch.commit();
}
Future<List> fetchPetiData() async {
var dbclient = await conn.db;
List petiList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.petiTable, orderBy: 'id DESC');
for (var item in maps) {
petiList.add(item);
}
} catch (e) {
print(e.toString());
}
return petiList;
}
Future<List> fetchTipePetiData() async {
var dbclient = await conn.db;
List tipePetiList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.typePetiTable, orderBy: 'id DESC');
for (var item in maps) {
tipePetiList.add(item);
}
} catch (e) {
print(e.toString());
}
return tipePetiList;
}
Future<List> fetchCustomerData() async {
var dbclient = await conn.db;
List customerList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.customerTable, orderBy: 'id DESC');
for (var item in maps) {
customerList.add(item);
}
} catch (e) {
print(e.toString());
}
return customerList;
}
Future<List> fetchWarehouseData() async {
var dbclient = await conn.db;
List warehouseList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.warehouseTable, orderBy: 'id DESC');
for (var item in maps) {
warehouseList.add(item);
}
} catch (e) {
print(e.toString());
}
return warehouseList;
}
Future<List> fetchDisposalData() async {
var dbclient = await conn.db;
List disposalList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.disposalTable, orderBy: 'id DESC');
for (var item in maps) {
disposalList.add(item);
}
} catch (e) {
print(e.toString());
}
return disposalList;
}
}

1143
lib/pages/peminjaman_barang/create.dart

File diff suppressed because it is too large Load Diff

760
lib/pages/peminjaman_barang/peminjaman_stock_page.dart

@ -1,16 +1,26 @@
import 'dart:async';
import 'dart:convert';
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:siopas/models/customer_model.dart';
import 'package:siopas/models/disposal_model.dart';
import 'package:siopas/models/m_asset_status_model.dart';
import 'package:siopas/models/type_peti_model.dart';
import 'package:siopas/models/warehouse_mode.dart';
import 'package:siopas/pages/peminjaman_barang/conn/syncronize.dart';
import 'package:siopas/services/syncronizeAPI.dart';
import 'package:siopas/services/controllerApi.dart';
import 'package:siopas/pages/peminjaman_barang/controller/peminjaman_controller.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:siopas/models/asset_status_model.dart';
import 'package:siopas/providers/asset_status_provider.dart';
import 'package:http/http.dart' as http;
import 'package:collection/collection.dart';
import '../../connection/connection.dart';
import '../../models/condition_peti_model.dart';
import 'show.dart';
class AssetStatusPage extends StatefulWidget {
@ -22,16 +32,49 @@ class AssetStatusPage extends StatefulWidget {
class AssetStatusPageState extends State<AssetStatusPage> {
String? token;
bool loading = true;
// Reinit atau Upload Only
WarehouseModel? warehouseSqfliteApi;
List<TypePetiModel>? typePetiSqfliteApi;
List<CustomerModel>? customerSqfliteApi;
PetiAssetModel? petiSqfliteApi;
DisposalPetiModel? disposalSqfliteApi;
List<PetiAssetModel>? _valpeti; // Change this line
List<WarehouseModel>? _valwarehouse;
List<DisposalPetiModel>? _valdisposal;
// Datatable
int _currentPage = 1;
int _pageSize = 10;
List<AssetStatusModel> _data = [];
List<AssetStatusModel>? _data;
List<PetiAssetModel>? _petiData;
List<TypePetiModel>? _tipePetiData;
List<CustomerModel>? _customerData;
List<WarehouseModel>? _warehouseData;
bool _isLoading = false;
Timer? _timer;
@override
void initState() {
super.initState();
_getUserToken();
fetchData();
warehouseListAPI();
typePetiListAPI();
customerListAPI();
petiListAPI();
// disposalListAPI();
// Tampil data Datatables
datatablesAssetStatusList();
datatablesPetiList();
datatablesTipePetiList();
datatablesCustomerList();
datatablesWarehouseList();
_data = <AssetStatusModel>[];
}
void _getUserToken() async {
@ -43,149 +86,617 @@ class AssetStatusPageState extends State<AssetStatusPage> {
}
}
Future<void> fetchData() async {
// Reinit atau Upload Only ------------------------------------------------------------------------
Future warehouseListAPI() async {
if (mounted) {
setState(() {
_isLoading = true;
await ControllerApi().fetchWarehouseDataAPI().then((value) {
setState(() {
_valwarehouse = (value as List<dynamic>)
.map((item) => WarehouseModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
try {
final response = await http.get(Uri.parse('$baseUrl/asset-status'));
// Future disposalListAPI() async {
// if (mounted) {
// await ControllerApi().fetchDisposalDataAPI().then((value) {
// setState(() {
// _valdisposal = (value as List<dynamic>)
// .map((item) => DisposalPetiModel.fromJson(item))
// .toList();
// loading = false;
// });
// });
// }
// }
if (response.statusCode == 200) {
final jsonData = json.decode(response.body)['data']['asset_status'];
Future typePetiListAPI() async {
if (mounted) {
await ControllerApi().fetchTipePetiDataAPI().then((value) {
setState(() {
typePetiSqfliteApi = (value as List<dynamic>)
.map((item) => TypePetiModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
final List<AssetStatusModel> newData = (jsonData as List)
.map((item) => AssetStatusModel.fromJson(item))
Future customerListAPI() async {
if (mounted) {
await ControllerApi().fetchCustomerDataAPI().then((value) {
setState(() {
customerSqfliteApi = (value as List<dynamic>)
.map((item) => CustomerModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
if (mounted) {
setState(() {
_data.addAll(newData);
_isLoading = false;
});
}
} else {
if (mounted) {
setState(() {
_isLoading = false;
});
}
throw Exception('Failed to fetch data');
}
} catch (e) {
if (mounted) {
setState(() {
_isLoading = false;
});
}
print('Error fetching data: $e');
}
Future petiListAPI() async {
if (mounted) {
await ControllerApi().fetchPetiDataAPI().then((value) {
setState(() {
_valpeti = (value as List<dynamic>)
.map((item) => PetiAssetModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
Future<void> 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...');
List<WarehouseModel> warehouseApiData =
await SyncronizationDataAPI().fetchWarehouseFromApi();
await ControllerApi()
.deleteAllWarehouseDataAPI(); // Clear existing data in SQLite
await ControllerApi()
.addAllWarehouseDataAPI(warehouseApiData); // Add new data to SQLite
EasyLoading.dismiss();
}
Future<void> reinitPetiApi() async {
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
EasyLoading.dismiss();
}
Future<void> reinitCustomerApi() async {
EasyLoading.show(status: 'Mengambil data Customer...');
List<CustomerModel> customerApiData =
await SyncronizationDataAPI().fetchCustomerFromApi();
await ControllerApi()
.deleteAllCustomerDataAPI(); // Clear existing data in SQLite
await ControllerApi()
.addAllCustomerDataAPI(customerApiData); // Add new data to SQLite
EasyLoading.dismiss();
}
Future<void> reinitTypePetiApi() async {
EasyLoading.show(status: 'Mengambil data Type Peti...');
List<TypePetiModel> typePetiApiData =
await SyncronizationDataAPI().fetchTipePetiFromApi();
await ControllerApi()
.deleteAllTipePetiDataAPI(); // Clear existing data in SQLite
await ControllerApi()
.addAllTipePetiDataAPI(typePetiApiData); // Add new data to SQLite
EasyLoading.dismiss();
}
Future<void> reinitConditionPetiApi() async {
EasyLoading.show(status: 'Mengambil data Condition Peti...');
List<ConditionPetiModel> conditionPetiApiData =
await SyncronizationDataAPI().fetchKondisiPetiFromApi();
await ControllerApi()
.deleteAllKondisiPetiDataAPI(); // Clear existing data in SQLite
await ControllerApi().addAllKondisiPetiDataAPI(
conditionPetiApiData); // Add new data to SQLite
EasyLoading.dismiss();
}
// Future<void> reinitDisposalApi() async {
// List<DisposalPetiModel> disposalApiData =
// await SyncronizationDataAPI().fetchDisposalFromApi();
// await ControllerApi()
// .deleteAllDisposalDataAPI(); // Clear existing data in SQLite
// await ControllerApi()
// .addAllDisposalDataAPI(disposalApiData); // Add new data to SQLite
// }
Future<void> fetchDataFromApiAndSync() async {
EasyLoading.show(status: 'Mengambil data dari Server...');
await Future.delayed(Duration(seconds: 3));
try {
await syncToMysql();
// await reinitAssetStatusApi();
await reinitWarehouseApi();
await reinitPetiApi();
await reinitCustomerApi();
// await reinitTypePetiApi();
await reinitConditionPetiApi();
// await reinitDisposalApi();
await datatablesAssetStatusList();
EasyLoading.showSuccess('Data berhasil diperbarui');
} catch (e) {
EasyLoading.showError('Gagal memperbarui data: $e');
} finally {
EasyLoading.dismiss();
}
}
Future syncToMysql() async {
await SyncronizationPeminjamanData()
.fetchAllInfo()
.then((peminjamanList) async {
EasyLoading.show(
status: 'Jangan tutup aplikasi. Kami sedang menyinkronkan...');
await Future.delayed(Duration(seconds: 3));
// Tambahkan penanganan pengunggahan
bool uploadSuccess = await SyncronizationPeminjamanData()
.saveToPeminjamanWith(peminjamanList);
// Jika pengunggahan berhasil, hapus data lokal
if (uploadSuccess) {
await SyncronizationPeminjamanData().deleteAllAssetStatusData();
// Setelah selesai, tampilkan pesan sukses
EasyLoading.showSuccess('Berhasil disinkronkan dengan Server');
await datatablesAssetStatusList();
} else {
// Tampilkan pesan gagal jika pengunggahan tidak berhasil
EasyLoading.showError('Gagal disinkronkan dengan Server');
}
});
}
// Future syncToMysql() async {
// await SyncronizationData().fetchAllInfo().then((assetList) async {
// EasyLoading.show(status: 'Don\'t close app. We are syncing...');
// await SyncronizationData().saveToMysqlWith(assetList);
// await SyncronizationData().deleteAllAssetStatusData();
// // EasyLoading.showSuccess('Successfully saved to MySQL');
// });
// }
Future<void> isInteret() async {
await SyncronizationPeminjamanData.isInternet().then((connection) {
if (connection) {
print("Internet connection available");
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("No Internet")));
}
});
}
// Datatables ------------------------------------------------------------------------
Future datatablesAssetStatusList() async {
await Controller().fetchAssetStatusLocalController().then((value) {
setState(() {
_data = (value as List<dynamic>)
.map((e) => AssetStatusModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesPetiList() async {
await Controller().fetchPetiData().then((value) {
setState(() {
_petiData = (value as List<dynamic>)
.map((e) => PetiAssetModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesTipePetiList() async {
await Controller().fetchTipePetiData().then((value) {
setState(() {
_tipePetiData = (value as List<dynamic>)
.map((e) => TypePetiModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesCustomerList() async {
await Controller().fetchCustomerData().then((value) {
setState(() {
_customerData = (value as List<dynamic>)
.map((e) => CustomerModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesWarehouseList() async {
await Controller().fetchWarehouseData().then((value) {
setState(() {
_warehouseData = (value as List<dynamic>)
.map((e) => WarehouseModel.fromJson(e))
.toList();
loading = false;
});
});
}
void _loadMoreData() {
if (mounted && !_isLoading) {
setState(() {
_currentPage++;
});
fetchData();
datatablesAssetStatusList();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text('Data Peminjaman Barang',
style: TextStyle(
fontSize: 16,
)),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
Navigator.pushNamed(context, '/home');
},
),
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: SingleChildScrollView(
child: SizedBox(
width: double.infinity,
child: PaginatedDataTable(
header: const Text('Peminjaman Barang'),
rowsPerPage: _pageSize,
availableRowsPerPage: const [10, 25, 50],
onRowsPerPageChanged: (value) {
setState(() {
_pageSize = value!;
});
},
columns: const [
DataColumn(label: Text('No')),
DataColumn(label: Text('')),
DataColumn(label: Text('Kode Peti')),
DataColumn(label: Text('Nama Customer')),
DataColumn(label: Text('Tgl Peminjaman')),
DataColumn(label: Text('PJ Peminjaman')),
DataColumn(label: Text('Asal Gudang')),
],
source: _DataSource(data: _data, context: context),
),
),
// Add this function outside the build method
void showSyncDialog(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
// Dialog shape and style
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
bottomNavigationBar: BottomAppBar(
color: Color.fromARGB(255, 5, 28, 158), // Warna latar belakang
child: Container(
height: 65.0,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
InkWell(
customBorder: CircleBorder(),
onTap: () {
// Aksi ketika ikon diklik
Navigator.pushNamed(context, '/peminjaman-barang/create');
},
child: Container(
width: 45,
height: 45,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.greenAccent[700],
backgroundColor: Colors.grey[100],
elevation: 0,
// Dialog content
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Dialog title with close button
Container(
width: double.infinity,
color: Colors.indigo[700], // Indigo background
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
"Sync Server Peminjaman",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 16.0,
),
),
),
IconButton(
icon: Icon(
Icons.close,
color: Colors.white,
),
onPressed: () {
Navigator.pop(context); // Close dialog
},
),
],
),
child: Icon(
Icons.add,
size: 30,
color: Colors.white,
),
// Divider
Divider(
height: 1,
thickness: 1,
color: Colors.black, // Black divider
),
// Re-init Button
Container(
width: double.infinity,
child: TextButton(
onPressed: () {
Navigator.pop(context); // Close dialog
fetchDataFromApiAndSync();
},
child: Text(
"Upload + Download",
style: TextStyle(
color: Colors.black,
fontSize: 16.0,
fontFamily: 'Poppins',
),
),
),
),
),
// Divider
// Divider(
// height: 1,
// thickness: 1,
// color: Colors.black, // Black divider
// ),
// Upload Only Button
// Container(
// width: double.infinity,
// child: TextButton(
// onPressed: () {
// Navigator.pop(context); // Close dialog
// syncToMysql();
// },
// child: Text(
// "Upload Only",
// style: TextStyle(
// color: Colors.black,
// fontSize: 16.0,
// fontFamily: 'Poppins',
// ),
// ),
// ),
// ),
],
),
);
},
);
}
return DefaultTabController(
length: 1,
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text('Data Peminjaman Barang',
style: TextStyle(
fontSize: 16,
)),
actions: [
IconButton(
icon: Icon(Icons.backup),
onPressed: () async {
if (await SyncronizationPeminjamanData.isInternet()) {
// Display custom dialog when the IconButton is pressed
showSyncDialog(context);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("No internet connection")),
);
}
},
),
],
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
Navigator.pushNamed(context, '/home');
},
),
bottom: TabBar(
indicator: BoxDecoration(color: Color.fromARGB(255, 50, 39, 122)),
tabs: [
Tab(text: 'Peminjaman Hari ini'),
],
),
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: TabBarView(
children: [
SingleChildScrollView(
child: Column(
children: [
SizedBox(
width: double.infinity,
child: PaginatedDataTable(
// header: Text('Searching'), // Removed const
rowsPerPage: _pageSize,
availableRowsPerPage: [10, 25, 50], // Removed const
onRowsPerPageChanged: (value) {
setState(() {
_pageSize = value!;
});
},
columns: [
DataColumn(label: Text('No')),
DataColumn(label: Text('')),
DataColumn(label: Text('Kode Peti')),
DataColumn(label: Text('Nama Customer')),
DataColumn(label: Text('Tgl Peminjaman')),
DataColumn(label: Text('Est Peminjaman')),
DataColumn(label: Text('PJ Peminjaman')),
DataColumn(label: Text('Asal Gudang')),
DataColumn(label: Text('Tujuan Gudang')),
],
source: _DataSourceLokal(
data: _data!,
context: context,
petiData: _petiData != null ? _petiData : [],
tipePetiData:
_tipePetiData != null ? _tipePetiData : [],
customerData:
_customerData != null ? _customerData : [],
warehouseData:
_warehouseData != null ? _warehouseData : [],
),
),
),
],
),
),
],
),
bottomNavigationBar: BottomAppBar(
color: Color.fromARGB(255, 5, 28, 158), // Warna latar belakang
child: Container(
height: 65.0,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
InkWell(
customBorder: CircleBorder(),
onTap: () {
// Aksi ketika ikon diklik
Navigator.pushNamed(context, '/peminjaman-barang/create');
},
child: Container(
width: 45,
height: 45,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.greenAccent[700],
),
child: Icon(
Icons.add,
size: 30,
color: Colors.white,
),
),
),
],
),
),
),
),
);
}
}
class _DataSource extends DataTableSource {
class _DataSourceLokal extends DataTableSource {
final List<AssetStatusModel> data;
List<PetiAssetModel>? petiData;
List<TypePetiModel>? tipePetiData;
List<CustomerModel>? customerData;
List<WarehouseModel>? warehouseData;
final BuildContext context;
_DataSource({required this.data, required this.context});
_DataSourceLokal({
required this.data,
required this.petiData,
required this.tipePetiData,
required this.customerData,
required this.warehouseData,
required this.context,
});
@override
DataRow? getRow(int index) {
if (index >= data.length) {
return null;
}
data.sort((a, b) {
if (a.created_at == null && b.created_at == null) {
return 0; // Both dates are null, consider them equal
} else if (a.created_at == null) {
return 1; // Null is considered greater than non-null
} else if (b.created_at == null) {
return -1; // Non-null is considered smaller than null
} else {
return b.created_at!.compareTo(a.created_at!); // Compare non-null dates
}
});
final item = data[index];
// Menemukan data peti yang sesuai dengan asset
PetiAssetModel? petiSqfliteApi;
if (item.peti_id != null) {
petiSqfliteApi = petiData!.firstWhere(
(peti) => peti.id == item.peti_id,
orElse: () => PetiAssetModel(
id: null,
tipe_peti_id: null,
warna: 'null',
packing_no: null,
customer_id: null,
warehouse_id: null,
kondisipeti_id: null,
jumlah: null,
date_pembuatan: DateTime.now(),
created_by: 'null',
updated_by: 'null',
fix_lot: '',
),
);
}
TypePetiModel? tipePetiSqfliteApi;
if (petiSqfliteApi != null && petiSqfliteApi.tipe_peti_id != null) {
tipePetiSqfliteApi = tipePetiData?.firstWhere(
(tipePeti) => tipePeti.id == petiSqfliteApi?.tipe_peti_id,
orElse: () => TypePetiModel(
id: null,
type: 'null',
size_peti: 'null',
description: 'null',
created_by: 'null',
updated_by: 'null',
),
);
}
CustomerModel? customerSqfliteApi;
if (petiSqfliteApi != null && petiSqfliteApi.customer_id != null) {
customerSqfliteApi = customerData?.firstWhere(
(customer) => customer.id == item.customer_id,
orElse: () => CustomerModel(
id: null,
name: 'null',
code_customer: 'null',
lot_no: 'null',
created_by: 'null',
updated_by: 'null',
),
);
}
WarehouseModel? warehouseSqfliteApi;
if (item.warehouse_id != null) {
warehouseSqfliteApi = warehouseData?.firstWhere(
(warehouse) => warehouse.id == item.warehouse_id,
orElse: () => WarehouseModel(
id: null,
name: 'null',
created_by: 'null',
updated_by: 'null',
),
);
}
WarehouseModel? warehouseTujuanSqfliteApi;
warehouseTujuanSqfliteApi = warehouseData?.firstWhereOrNull(
(warehouse) => warehouse.id == item.exit_warehouse,
);
return DataRow(cells: [
DataCell(
Text(
@ -200,7 +711,7 @@ class _DataSource extends DataTableSource {
context,
MaterialPageRoute(
builder: (context) => DetailPeminjamanBarangPage(
assetId: item.id!,
peminjamanId: item.id.toString(),
),
),
);
@ -215,22 +726,27 @@ class _DataSource extends DataTableSource {
),
DataCell(
Text(
// item.asset.exit_at.toString(),
item.peti!.customer!.code_customer.toString() +
'-' +
item.peti!.tipe_peti!.type.toString(),
petiSqfliteApi != null && petiSqfliteApi.fix_lot != null
? petiSqfliteApi!.fix_lot.toString()
: '-',
),
),
DataCell(
Text(
customerSqfliteApi != null && customerSqfliteApi.name != null
? customerSqfliteApi!.name.toString()
: '-',
),
),
DataCell(
Text(
item.peti!.customer!.name.toString(),
item.exit_at != null
? DateFormat('dd-MM-yyyy').format(item.exit_at!)
: '-',
),
),
DataCell(
Text(
// item.asset.exit_at.toString(),
// item.exit_at.toString(),
// DateFormat('dd-MM-yyyy').format(item.est_pengembalian!)
item.est_pengembalian != null
? DateFormat('dd-MM-yyyy').format(item.est_pengembalian!)
: '-',
@ -238,11 +754,23 @@ class _DataSource extends DataTableSource {
),
DataCell(
Text(
item.exit_pic.toString(),
item.exit_pic != null ? item.exit_pic.toString() : '-',
),
),
DataCell(
Text(item.warehouse!.name.toString()),
Text(
warehouseSqfliteApi != null && warehouseSqfliteApi.name != null
? warehouseSqfliteApi.name.toString()
: '-',
),
),
DataCell(
Text(
warehouseTujuanSqfliteApi != null &&
warehouseTujuanSqfliteApi.name != null
? warehouseTujuanSqfliteApi.name.toString()
: '-',
),
),
]);
}

226
lib/pages/peminjaman_barang/show.dart

@ -1,13 +1,19 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
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/pages/peminjaman_barang/controller/peminjaman_controller.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:intl/intl.dart';
import 'package:siopas/connection/connection.dart';
import 'package:collection/collection.dart';
import '../../models/warehouse_mode.dart';
import '../../services/controllerApi.dart';
class DetailPeminjamanBarangPage extends StatefulWidget {
final int assetId;
const DetailPeminjamanBarangPage({Key? key, required this.assetId})
final String peminjamanId;
const DetailPeminjamanBarangPage({Key? key, required this.peminjamanId})
: super(key: key);
@override
@ -17,54 +23,118 @@ class DetailPeminjamanBarangPage extends StatefulWidget {
class _DetailPeminjamanBarangPageState
extends State<DetailPeminjamanBarangPage> {
Map<String, dynamic>? assetStatusData;
AssetStatusModel? peminjamanInfo;
WarehouseModel? warehouseInfo;
String _formatDate(String date) {
DateTime parsedDate = DateTime.parse(date);
String formattedDate =
DateFormat('EEEE, dd MMMM yyyy', 'id_ID').format(parsedDate);
return formattedDate;
}
List<PetiAssetModel>? petiData;
List<CustomerModel>? customerData;
List<WarehouseModel>? warehouseData;
bool loading = true;
@override
void initState() {
super.initState();
_fetchAssetStatusData();
getPeminjamanIdData();
customerListAPI();
petiListAPI();
warehouseListAPI();
initializeDateFormatting('id_ID', null);
}
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<void> _fetchAssetStatusData() async {
try {
final response = await http.get(
Uri.parse('$baseUrl/asset-status/peminjaman/show/${widget.assetId}'),
headers: {
'Content-Type': 'application/json',
},
);
Future petiListAPI() async {
if (mounted) {
await ControllerApi().fetchPetiDataAPI().then((value) {
setState(() {
petiData = (value as List<dynamic>)
.map((item) => PetiAssetModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
if (response.statusCode == 200) {
Future warehouseListAPI() async {
if (mounted) {
await ControllerApi().fetchWarehouseDataAPI().then((value) {
setState(() {
assetStatusData = json.decode(response.body)['data']['asset_status'];
warehouseData = (value as List<dynamic>)
.map((item) => WarehouseModel.fromJson(item))
.toList();
loading = false;
});
} else {
throw Exception('Failed to load data');
}
} catch (e) {
print('Error fetching data: $e');
});
}
}
Future<void> getPeminjamanIdData() async {
List<AssetStatusModel> peminjamans =
await Controller().fetchPeminjamanDataId();
peminjamanInfo = peminjamans.firstWhereOrNull(
(peminjaman) => peminjaman.id.toString() == widget.peminjamanId,
);
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 '';
}
}
@override
Widget build(BuildContext context) {
PetiAssetModel? petiSqfliteApi;
petiSqfliteApi = petiData?.firstWhereOrNull(
(peti) => peti.id == peminjamanInfo!.peti_id,
);
CustomerModel? customerSqfliteApi;
customerSqfliteApi = customerData?.firstWhereOrNull(
(customer) => customer.id == peminjamanInfo?.customer_id,
);
WarehouseModel? warehouseSqfliteApi;
warehouseSqfliteApi = warehouseData?.firstWhereOrNull(
(warehouse) => warehouse.id == peminjamanInfo!.exit_warehouse,
);
WarehouseModel? warehouseTujuanSqfliteApi;
warehouseTujuanSqfliteApi = warehouseData?.firstWhereOrNull(
(warehouse) => warehouse.id == peminjamanInfo!.exit_warehouse,
);
return Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text('Detail Peminjaman Barang',
style: TextStyle(
color: Colors.white,
fontSize: 16,
)),
title: Text(
'Detail Peminjaman Barang',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
@ -91,45 +161,85 @@ class _DetailPeminjamanBarangPageState
color: Colors.indigo[700],
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(Icons.article,
size: 40,
color: Colors.white), // Ganti ikon sesuai kebutuhan
SizedBox(width: 10),
Text(
'ID: ${widget.assetId}',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
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 (assetStatusData != null) ...[
if (peminjamanInfo != null) ...[
_buildDetailItem(
'Kode Peti',
assetStatusData!['peti']['customer']['code_customer'] +
' - ' +
assetStatusData!['peti']['tipe_peti']['type'],
petiSqfliteApi != null && petiSqfliteApi.fix_lot != null
? petiSqfliteApi!.fix_lot.toString()
: '-',
),
// _buildDetailItem(
// 'Peti Nama', assetStatusData!['peti']['fix_lot']),
Divider(thickness: 1),
_buildDetailItem('Nama Customer',
assetStatusData!['peti']['customer']['name']),
_buildDetailItem(
'Nama Customer',
customerSqfliteApi != null && customerSqfliteApi.name != null
? customerSqfliteApi!.name.toString()
: '-',
),
Divider(thickness: 1),
_buildDetailItem('Tgl Peminjaman',
_formatDate(peminjamanInfo!.exit_at.toString())),
Divider(thickness: 1),
_buildDetailItem('Est Peminjaman',
_formatDate(peminjamanInfo!.est_pengembalian.toString())),
Divider(thickness: 1),
_buildDetailItem(
'Tgl Peminjaman', _formatDate(assetStatusData!['exit_at'])),
'PJ Peminjaman', peminjamanInfo!.exit_pic.toString()),
Divider(thickness: 1),
_buildDetailItem('PJ Peminjaman', assetStatusData!['exit_pic']),
_buildDetailItem(
'Asal Warehouse',
// peminjamanInfo!.exit_warehouse.toString()),
warehouseSqfliteApi != null &&
warehouseSqfliteApi.name != null
? warehouseSqfliteApi!.name.toString()
: '-'),
Divider(thickness: 1),
_buildDetailItem(
'Exit Warehouse', assetStatusData!['warehouse']['name']),
'Exit Warehouse',
// peminjamanInfo!.exit_warehouse.toString()),
warehouseSqfliteApi != null &&
warehouseSqfliteApi.name != null
? warehouseSqfliteApi!.name.toString()
: '-'),
Divider(thickness: 1),
// ... tambahkan data lainnya sesuai kebutuhan
],
],
@ -147,7 +257,7 @@ class _DetailPeminjamanBarangPageState
children: [
Text(
label,
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
style: TextStyle(fontSize: 12.5, fontWeight: FontWeight.bold),
),
Text(value),
],

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

@ -0,0 +1,218 @@
import 'dart:convert';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:internet_connection_checker/internet_connection_checker.dart';
import 'package:intl/intl.dart';
import '../../../connection/connection.dart';
import '../../../migrations/databasehelper.dart';
import '../../../models/asset_status_model.dart';
import 'package:http/http.dart' as http;
class SyncronizationPengembalianData {
Future<int> addData(AssetStatusModel assetStatusModel) async {
final dbClient = await conn.db;
late int result;
try {
result = await dbClient!.insert(
SqfliteDatabaseHelper.pengembalianTable, assetStatusModel.toJson());
} catch (e) {
print('Error adding data to local SQLite: $e');
result = 0; // Handle the error appropriately
}
return result;
}
Future<List> fetchData() async {
var dbclient = await conn.db;
List assetStatusList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.pengembalianTable, orderBy: 'id DESC');
for (var item in maps) {
assetStatusList.add(item);
}
} catch (e) {
print(e.toString());
}
return assetStatusList;
}
static Future<bool> isInternet() async {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
if (await InternetConnectionChecker().hasConnection) {
print("Mobile data detected & internet connection confirmed.");
return true;
} else {
print('No internet :( Reason:');
return false;
}
} else if (connectivityResult == ConnectivityResult.wifi) {
if (await InternetConnectionChecker().hasConnection) {
print("wifi data detected & internet connection confirmed.");
return true;
} else {
print('No internet :( Reason:');
return false;
}
} else {
print(
"Neither mobile data or WIFI detected, not internet connection found.");
return false;
}
}
final conn = SqfliteDatabaseHelper.instance;
Future<List<AssetStatusModel>> fetchAllInfo() async {
final dbClient = await conn.db;
List<AssetStatusModel> assetStatusList = [];
try {
final maps =
await dbClient!.query(SqfliteDatabaseHelper.pengembalianTable);
for (var item in maps) {
assetStatusList.add(AssetStatusModel.fromJson(item));
}
} catch (e) {
print(e.toString());
}
return assetStatusList;
}
Future<void> deleteAllAssetStatusData() async {
var dbClient = await conn.db;
await dbClient!.delete(SqfliteDatabaseHelper.pengembalianTable);
}
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<List> fetchAllCustomerInfo() async {
final dbClient = await conn.db;
List contactList = [];
try {
final maps =
await dbClient!.query(SqfliteDatabaseHelper.pengembalianTable);
for (var item in maps) {
contactList.add(item);
}
} catch (e) {
print(e.toString());
}
return contactList;
}
Future saveToMysql(List assetStatusesLocalList) async {
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;
}
}
for (var i = 0; i < assetStatusesLocalList.length; i++) {
// 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(response.body);
print("Saving Data saveToMysql");
} else {
print(response.statusCode);
print(
"Failed to upload data for index $i. Status code: ${response.statusCode}");
}
}
}
Future<List<AssetStatusModel>> fetchFromApi() async {
final response = await http.get(
Uri.parse(await getBaseUrl() + '/asset-status'),
);
if (response.statusCode == 200) {
List<dynamic> data = json.decode(response.body)['data']['asset_status'];
List<AssetStatusModel> contactDBList = data
.map(
(item) => AssetStatusModel.fromJson(item as Map<String, dynamic>))
.toList();
return contactDBList;
} else {
throw Exception('Failed to fetch data from API Asset Status');
}
}
}

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

@ -0,0 +1,221 @@
import 'dart:async';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:siopas/models/asset_status_model.dart';
import 'package:http/http.dart' as http;
import 'package:internet_connection_checker/internet_connection_checker.dart';
import 'package:sqflite/sqflite.dart';
import '../../../migrations/databasehelper.dart';
class ControllerPengembalian {
final conn = SqfliteDatabaseHelper.instance;
Future<List<AssetStatusModel>> fetchAllPengembalianInfo() async {
final dbClient = await conn.db;
List<AssetStatusModel> pengembalianList = [];
try {
final maps =
await dbClient!.query(SqfliteDatabaseHelper.pengembalianTable);
for (var item in maps) {
pengembalianList.add(AssetStatusModel.fromJson(item));
}
} catch (e) {
print(e.toString());
}
return pengembalianList;
}
static Future<bool> isInternet() async {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
if (await InternetConnectionChecker().hasConnection) {
print("Mobile data detected & internet connection confirmed.");
return true;
} else {
print('No internet :( Reason:');
return false;
}
} else if (connectivityResult == ConnectivityResult.wifi) {
if (await InternetConnectionChecker().hasConnection) {
print("wifi data detected & internet connection confirmed.");
return true;
} else {
print('No internet :( Reason:');
return false;
}
} else {
print(
"Neither mobile data or WIFI detected, not internet connection found.");
return false;
}
}
Future<int> addPengembalianData(AssetStatusModel pengembalianAddModel) async {
var dbclient = await conn.db;
int result = 0; // Provide an initial value
try {
result = await dbclient!.insert(SqfliteDatabaseHelper.pengembalianTable,
pengembalianAddModel.toJson());
} catch (e) {
print(e.toString());
}
return result;
}
Future<int> updatePengembalianData(
AssetStatusModel pengembalianAddModel) async {
var dbclient = await conn.db;
late int result;
try {
result = await dbclient!.update(
SqfliteDatabaseHelper.pengembalianTable,
pengembalianAddModel.toJson(),
where: 'id=?',
whereArgs: [pengembalianAddModel.id],
);
} catch (e) {
print(e.toString());
}
return result;
}
Future<List> fetchPengembalianLocalController() async {
var dbclient = await conn.db;
List pengembalianStatusList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.pengembalianTable, orderBy: 'id DESC');
for (var item in maps) {
pengembalianStatusList.add(item);
}
} catch (e) {
print(e.toString());
}
return pengembalianStatusList;
}
Future<List<AssetStatusModel>> fetchPengembalianDataId() async {
var dbclient = await conn.db;
List<AssetStatusModel> pengembalianList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.pengembalianTable, orderBy: 'id DESC');
for (var item in maps) {
pengembalianList.add(AssetStatusModel.fromJson(item));
}
} catch (e) {
print(e.toString());
}
return pengembalianList;
}
Future<void> deleteAllData() async {
var dbClient = await conn.db;
await dbClient!.delete(SqfliteDatabaseHelper.pengembalianTable);
}
Future<void> addAllData(List<AssetStatusModel> pengembalianList) async {
var dbclient = await conn.db;
Batch batch = dbclient!.batch();
for (var pengembalian in pengembalianList) {
batch.insert(
SqfliteDatabaseHelper.pengembalianTable,
pengembalian.toJson(),
);
}
await batch.commit();
}
Future<List> fetchPetiData() async {
var dbclient = await conn.db;
List petiList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.petiTable, orderBy: 'id DESC');
for (var item in maps) {
petiList.add(item);
}
} catch (e) {
print(e.toString());
}
return petiList;
}
Future<List> fetchTipePetiData() async {
var dbclient = await conn.db;
List tipePetiList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.typePetiTable, orderBy: 'id DESC');
for (var item in maps) {
tipePetiList.add(item);
}
} catch (e) {
print(e.toString());
}
return tipePetiList;
}
Future<List> fetchCustomerData() async {
var dbclient = await conn.db;
List customerList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.customerTable, orderBy: 'id DESC');
for (var item in maps) {
customerList.add(item);
}
} catch (e) {
print(e.toString());
}
return customerList;
}
Future<List> fetchWarehouseData() async {
var dbclient = await conn.db;
List warehouseList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.warehouseTable, orderBy: 'id DESC');
for (var item in maps) {
warehouseList.add(item);
}
} catch (e) {
print(e.toString());
}
return warehouseList;
}
Future<List> fetchConditionData() async {
var dbclient = await conn.db;
List conditionList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.conditionPetiTable, orderBy: 'id DESC');
for (var item in maps) {
conditionList.add(item);
}
} catch (e) {
print(e.toString());
}
return conditionList;
}
Future<List> fetchDisposalData() async {
var dbclient = await conn.db;
List disposalList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.disposalTable, orderBy: 'id DESC');
for (var item in maps) {
disposalList.add(item);
}
} catch (e) {
print(e.toString());
}
return disposalList;
}
}

764
lib/pages/pengembalian_barang/edit.dart

@ -1,22 +1,39 @@
import 'dart:convert';
import 'dart:core';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:siopas/models/asset_status_model.dart';
import 'package:siopas/models/condition_peti_model.dart';
import 'package:siopas/models/customer_model.dart';
import 'package:siopas/models/type_peti_model.dart';
import 'package:siopas/pages/peminjaman_barang/conn/syncronize.dart';
import 'package:siopas/pages/pengembalian_barang/conn/syncronize.dart';
import 'package:siopas/pages/pengembalian_barang/controller/pengembalian_controller.dart';
import 'package:siopas/services/controllerApi.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:siopas/connection/connection.dart';
import 'package:http/http.dart' as http;
import 'package:siopas/models/asset_status_model.dart';
// import 'package:siopas/models/m_asset_status_model.dart';
import 'package:siopas/models/user_model.dart';
import 'package:siopas/models/m_asset_status_model.dart';
import 'package:siopas/models/warehouse_mode.dart';
import 'package:siopas/providers/auth_provider.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 '../../connection/connection.dart';
import 'package:http/http.dart' as http;
import '../../models/user_model.dart';
import '../../providers/auth_provider.dart';
import '../peminjaman_barang/controller/peminjaman_controller.dart';
import 'package:collection/collection.dart';
// import 'conn/syncronizeAPI.dart';
// import 'controller/peminjaman_controller.dart';
class CreatePengembalianBarangPage extends StatefulWidget {
const CreatePengembalianBarangPage({super.key});
const CreatePengembalianBarangPage({Key? key}) : super(key: key);
@override
State<CreatePengembalianBarangPage> createState() =>
@ -25,15 +42,32 @@ class CreatePengembalianBarangPage extends StatefulWidget {
class _CreatePengembalianBarangPageState
extends State<CreatePengembalianBarangPage> {
List<AssetStatusModel> _dataAsset = [];
List<WarehouseModel> _dataWarehouse = [];
bool _isLoading = false;
List<AssetStatusModel>? _data;
String? token;
AssetStatusModel? _valAsset;
WarehouseModel? _valWarehouse;
List<TypePetiModel>? typePetiSqfliteApi;
// List<CustomerModel>? customerSqfliteApi;
PetiAssetModel? petiSqfliteApi;
ConditionPetiModel? conditionPetiSqfliteApi;
WarehouseModel? warehouseSqfliteApi;
List<PetiAssetModel>? _valpeti; // Change this line
List<WarehouseModel>? _valwarehouse;
List<ConditionPetiModel>? _valconditionPeti;
CustomerModel? customerSqfliteApi;
List<CustomerModel>? _valcustomer;
List<PetiAssetModel> _unrestrictedPetiList = [];
List<PetiAssetModel> _filteredPetiList = [];
bool isQRCodeScanned = false;
bool loading = true;
TextEditingController _enterAtController = TextEditingController();
TextEditingController _enterPicController = TextEditingController();
TextEditingController _kondisiPetiController = TextEditingController();
// TextEditingController _enterPicController = TextEditingController();
// TextEditingController _kondisiPetiController = TextEditingController();
// TextEditingController _penanggungJawabController = TextEditingController();
final _formKey = GlobalKey<FormState>();
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
@ -44,9 +78,15 @@ class _CreatePengembalianBarangPageState
void initState() {
super.initState();
_getUserToken();
fetchDataWarehouse();
fetchDataAsset();
initializeDateFormatting('id_ID');
warehouseListAPI();
datatablesAssetStatusList();
// typePetiListAPI();
// customerListAPI();
petiListAPI();
kondisiPetiListAPI();
initializeDateFormatting('id_ID', null);
}
void _getUserToken() async {
@ -54,75 +94,70 @@ class _CreatePengembalianBarangPageState
if (mounted) {
setState(() {
token = prefs.getString('token');
loading = false;
});
}
}
Future<void> fetchDataAsset() async {
setState(() {
_isLoading = true;
});
final response =
await http.get(Uri.parse('$baseUrl/asset-status/pengembalian/create'));
Future warehouseListAPI() async {
if (mounted) {
// Periksa apakah widget masih "mounted"
if (response.statusCode == 200) {
final jsonData = json.decode(response.body)['data']['asset_status'];
final List<AssetStatusModel> newDataAsset = (jsonData as List)
.map((item) => AssetStatusModel.fromJson(item))
.toList();
if (mounted) {
// Periksa lagi sebelum memanggil setState
setState(() {
_dataAsset.addAll(newDataAsset);
_isLoading = false;
});
}
} else {
if (mounted) {
setState(() {
_isLoading = false;
});
}
throw Exception('Failed to fetch data Asset Status');
}
await ControllerApi().fetchWarehouseDataAPI().then((value) {
setState(() {
_valwarehouse = (value as List<dynamic>)
.map((item) => WarehouseModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
Future<void> fetchDataWarehouse() async {
setState(() {
_isLoading = true;
Future datatablesAssetStatusList() async {
await Controller().fetchAssetStatusLocalController().then((value) {
setState(() {
_data = (value as List<dynamic>)
.map((e) => AssetStatusModel.fromJson(e))
.toList();
loading = false;
});
});
}
final response = await http.get(Uri.parse('$baseUrl/m-warehouse'));
Future petiListAPI() async {
if (mounted) {
if (response.statusCode == 200) {
final jsonData = json.decode(response.body)['data']['warehouse'];
await ControllerApi().fetchPetiDataAPI().then((value) {
setState(() {
_valpeti = (value as List<dynamic>)
.map((item) => PetiAssetModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
final List<WarehouseModel> newDataWarehouse = (jsonData as List)
.map((item) => WarehouseModel.fromJson(item))
.toList();
Future kondisiPetiListAPI() async {
if (mounted) {
await ControllerApi().fetchKondisiPetiDataAPI().then((value) {
setState(() {
_valconditionPeti = (value as List<dynamic>)
.map((item) => ConditionPetiModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
if (mounted) {
setState(() {
_dataWarehouse.addAll(newDataWarehouse);
_isLoading = false;
});
}
Future<void> isInteret() async {
await SyncronizationPengembalianData.isInternet().then((connection) {
if (connection) {
print("Internet connection available");
} else {
if (mounted) {
setState(() {
_isLoading = false;
});
}
throw Exception('Failed to fetch data Warehouse');
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("No Internet")));
}
}
});
}
Future<void> _onQRViewCreated(QRViewController controller) async {
@ -134,108 +169,164 @@ class _CreatePengembalianBarangPageState
await Future.delayed(const Duration(milliseconds: 400));
controller.flipCamera();
controller.scannedDataStream.listen((scanData) {
if (!scanned) {
try {
setState(() {
result = scanData;
List<String> lines = result!.code!.split('\n');
String idPeti = '';
for (String line in lines) {
if (line.contains(';')) {
List<String> values = line.split(';');
if (values.length >= 3) {
idPeti = values[1];
break;
controller.scannedDataStream.listen(
(scanData) {
if (!scanned) {
try {
setState(() {
result = scanData;
List<String> lines = result!.code!.split('\n');
String idPeti = '';
String idWarehouse = '';
for (String line in lines) {
if (line.contains(';')) {
List<String> values = line.split(';');
if (values.length >= 3) {
idPeti = values[1];
idWarehouse = values[2];
break;
}
}
}
}
int? petiId = int.tryParse(idPeti);
if (petiId != null) {
_valAsset = _dataAsset.firstWhere(
(peminjaman) => peminjaman.peti_id == petiId,
orElse: () => _valAsset!,
);
} else {
// Jika nilai yang dipindai tidak sesuai, tampilkan pesan kesalahan
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Row(
children: [
Icon(
Icons.warning,
color: Colors.black, // Warna ikon
),
SizedBox(width: 8), // Jarak antara ikon dan teks
Text(
'Nilai QR Code tidak sesuai dengan yang diharapkan.',
int? petiId = int.tryParse(idPeti);
int? warehouseId = int.tryParse(idWarehouse);
// AuthProvider authProvider = Provider.of<AuthProvider>(context, listen: false);
// UserModel user = authProvider.user;
// Dalam fungsi yang menangani pemindaian QR code
// Dalam fungsi yang menangani pemindaian QR code
if (petiId != null && warehouseId != null) {
// Check apakah peti dengan warehouse_id yang sesuai ada dalam daftar yang diizinkan
PetiAssetModel? allowedPeti = _valpeti?.firstWhereOrNull(
(peti) =>
peti.id == petiId &&
peti.deleted_at != true &&
peti.status == 'AKTIF',
);
if (allowedPeti != null) {
setState(() {
isQRCodeScanned = true;
// Mengisi _filteredPetiList untuk dropdown hasil QR Code
_filteredPetiList = [
_valpeti!.firstWhere((peti) => peti.id == allowedPeti.id)
];
petiSqfliteApi = allowedPeti;
warehouseSqfliteApi = _valwarehouse?.firstWhereOrNull(
(warehouse) => warehouse.id == allowedPeti.warehouse_id,
);
customerSqfliteApi = _valcustomer?.firstWhereOrNull(
(customer) => customer.id == allowedPeti.customer_id,
);
});
} else {
// Tampilkan pesan error jika data tidak sesuai dengan hak akses
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Data Peti tidak ditemukan atau tidak sesuai dengan hak akses.',
style: TextStyle(
color: Colors.black,
color: Colors.white,
fontSize: 12,
), // Warna teks
),
),
],
backgroundColor: Colors.red[700],
action: SnackBarAction(
label: 'Tutup',
onPressed: () {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
},
),
),
);
setState(() {
isQRCodeScanned = false;
petiSqfliteApi = null;
warehouseSqfliteApi = null;
});
}
} else {
// Tampilkan pesan error jika nilai yang dipindai tidak sesuai
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Row(
children: [
Icon(
Icons.warning,
color: Colors.black,
),
SizedBox(width: 8),
Text(
'Nilai QR Code tidak sesuai dengan yang diharapkan.',
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
),
],
),
backgroundColor: Colors.yellow[700],
),
backgroundColor: Colors.yellow[700],
),
);
}
scanned = true;
});
controller.stopCamera();
Future.delayed(Duration(milliseconds: 500), () {
if (mounted) {
Navigator.pop(context);
}
});
} catch (e) {
controller.stopCamera();
if (mounted) {
Navigator.pushNamed(context, '/pengembalian-barang/create');
}
print('Error scanning QR Code: $e');
);
setState(() {
isQRCodeScanned = false;
petiSqfliteApi = null;
warehouseSqfliteApi = null;
});
}
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Row(
children: [
Icon(
Icons.error, // Icon error
color: Colors.red[400], // Warna merah
),
SizedBox(width: 8),
Flexible(
// Menggunakan Flexible untuk menghindari overflow
child: Text(
'Peti ini belum ada di menu pinjaman, silahkan untuk mengecek kembali.',
style: TextStyle(
color: Colors.white,
fontSize: 12,
), // Warna teks merah
scanned = true;
});
controller.stopCamera();
Future.delayed(Duration(milliseconds: 500), () {
if (mounted) {
Navigator.of(context).pop();
}
});
} catch (e) {
controller.stopCamera();
// Reset nilai dropdown Peti dan Warehouse
setState(() {
petiSqfliteApi = null;
warehouseSqfliteApi = null;
});
print('Error scanning QR Code: $e');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Row(
children: [
Icon(
Icons.error,
color: Colors.red[400],
),
),
],
SizedBox(width: 8),
Flexible(
child: Text(
e.toString(),
style: TextStyle(
color: Colors.white,
fontSize: 12,
),
),
),
],
),
backgroundColor: Colors.red[700],
),
backgroundColor: Colors.red[700],
),
);
);
}
}
}
});
}
@override
void dispose() {
super.dispose();
controller?.dispose();
},
);
}
@override
@ -243,110 +334,71 @@ class _CreatePengembalianBarangPageState
AuthProvider authProvider =
Provider.of<AuthProvider>(context, listen: false);
UserModel user = authProvider.user;
var scanArea = (MediaQuery.of(context).size.width < 400 ||
MediaQuery.of(context).size.height < 400)
? 150.0
: 300.0;
Future<void> _updatePeminjaman() async {
setState(() {
_isLoading = true;
});
// var uuid = Uuid();
try {
final response = await http.put(
Uri.parse('$baseUrl/asset-status/update/${_valAsset!.id}'),
headers: {
'Content-Type': 'application/json',
'Authorization': token!,
},
body: jsonEncode({
'enter_at': _enterAtController.text,
'enter_pic': _enterPicController.text,
'enter_warehouse': _valWarehouse!.id,
'kondisi_peti': _kondisiPetiController.text,
'updated_by': user.fullname,
}),
);
print(response.body);
DateTime? parseDateTime(String? dateTimeString) {
if (dateTimeString == null || dateTimeString.isEmpty) {
return null;
}
if (response.statusCode == 200) {
final jsonData = json.decode(response.body)['data']['asset_status'];
try {
return DateTime.parse(dateTimeString);
} catch (e) {
print('Error parsing DateTime: $e');
return null;
}
}
print('Berhasil memperbarui data: $jsonData');
Future<void> saveAssetData() async {
DateTime now = DateTime.now().toLocal();
String formattedDate = DateFormat('yyyy-MM-dd HH:mm:ss.SSS').format(now);
if (_enterAtController.text.isNotEmpty) {
AssetStatusModel pengembalianAddModel = AssetStatusModel(
id: null,
peti_id: petiSqfliteApi!.id,
enter_at: parseDateTime(_enterAtController.text),
enter_pic: user.fullname,
enter_warehouse: warehouseSqfliteApi!.id,
kondisi_peti_id: conditionPetiSqfliteApi!.id,
updated_by: user.fullname,
updated_at: parseDateTime(formattedDate),
);
// Tampilkan snackbar
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.greenAccent[700],
content: Row(
children: [
Icon(
Icons.check_circle_outline,
color: Colors.white,
),
SizedBox(width: 5),
Text('Data berhasil dikembalikan'),
],
),
duration: Duration(seconds: 3), // Durasi tampilan snackbar
),
);
// Reset form input
_valAsset = null;
_enterAtController.text = '';
_enterPicController.text = '';
_kondisiPetiController.text = '';
_valWarehouse = null;
// Call addData function
int result = await ControllerPengembalian()
.addPengembalianData(pengembalianAddModel);
if (result > 0) {
print("Success Tambah data");
// print(result);
Navigator.pushNamed(context, '/pengembalian-barang');
EasyLoading.showSuccess("Data Berhasil Disimpan");
} else {
throw Exception('Gagal memperbarui data Asset Status');
}
} catch (e) {
print('Error updating data: $e');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent[700],
content: Row(
children: [
Icon(
Icons.error_outline,
color: Colors.white,
),
SizedBox(width: 5),
Text('Gagal memperbarui data'),
],
),
duration: Duration(seconds: 2), // Durasi tampilan snackbar
),
);
} finally {
if (mounted) {
setState(() {
_isLoading = false;
});
print("Failed");
}
}
}
var scanArea = (MediaQuery.of(context).size.width < 400 ||
MediaQuery.of(context).size.height < 400)
? 250.0
: 300.0;
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.indigo[700],
elevation: 0,
backgroundColor: Color.fromARGB(255, 5, 28, 158),
title: Text('Pengembalian Barang'),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.pushNamed(context, '/pengembalian-barang');
},
),
title: Text('Buat Pengembalian barang',
style: TextStyle(
fontSize: 16,
)),
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
body: loading
? Center(child: CircularProgressIndicator())
: SingleChildScrollView(
child: Container(
padding: EdgeInsets.all(10.0),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Form(
key: _formKey,
child: Column(
@ -358,8 +410,7 @@ class _CreatePengembalianBarangPageState
elevation: 2,
child: Container(
margin: EdgeInsets.all(8),
child:
DropdownButtonFormField<AssetStatusModel>(
child: DropdownButtonFormField<PetiAssetModel>(
validator: (value) {
if (value == null) {
return 'Harus diisi';
@ -371,24 +422,48 @@ class _CreatePengembalianBarangPageState
border: OutlineInputBorder(),
),
hint: Text("Pilih Peti"),
value: _valAsset,
items:
_dataAsset.map((AssetStatusModel item) {
return DropdownMenuItem<AssetStatusModel>(
child: Text('${item.peti!.fix_lot!}'),
value: item,
value: petiSqfliteApi,
items: (isQRCodeScanned
? _filteredPetiList
: (_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}',
style: TextStyle(
fontSize: 12,
),
),
value: peti,
);
}).toList(),
onChanged: (AssetStatusModel? value) {
onChanged: (PetiAssetModel? value) {
setState(() {
_valAsset = value;
petiSqfliteApi = value;
if (value != null) {
warehouseSqfliteApi =
_valwarehouse?.firstWhere(
(warehouse) =>
warehouse.id ==
value.warehouse_id,
);
// Perbarui _unrestrictedPetiList sesuai pemilihan manual
_unrestrictedPetiList = [
_valpeti!.firstWhere(
(peti) => peti.id == value.id)
];
}
});
},
),
),
),
),
SizedBox(width: 8), // Spacer antara dua card
Card(
elevation: 2,
@ -401,10 +476,6 @@ class _CreatePengembalianBarangPageState
),
child: IconButton(
onPressed: () {
setState(() {
_valAsset =
null; // Mengatur _valAsset menjadi null
});
showModalBottomSheet(
context: context,
isScrollControlled:
@ -468,32 +539,6 @@ class _CreatePengembalianBarangPageState
),
],
),
SizedBox(height: 16),
// Visibility(
// visible: false,
// child:
Card(
elevation: 2,
child: Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller: _enterPicController =
TextEditingController(text: user.fullname),
decoration: InputDecoration(
labelText: 'Penanggung Jawab',
border: OutlineInputBorder(),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Harus diisi';
}
return null; // Return null jika tidak ada kesalahan
},
),
),
),
// ),
SizedBox(height: 16),
Card(
elevation: 2,
@ -512,7 +557,8 @@ class _CreatePengembalianBarangPageState
color: Colors.white,
),
SizedBox(width: 5),
Text('Tanggal Pengembalian'),
Text(
'Tanggal Pengembalian harus diisi'),
],
),
duration: Duration(seconds: 2),
@ -525,8 +571,10 @@ class _CreatePengembalianBarangPageState
controller: _enterAtController,
name: 'tanggal',
inputType: InputType.date,
// format: DateFormat('dd-MMMM-yyyy', 'id_ID'),
// format: DateFormat('yyyy-MM-dd HH:mm:ss.SSS'),
format: DateFormat('yyyy-MM-dd', 'id_ID'),
// format: DateFormat('yyyy-MM-dd'),
decoration: InputDecoration(
labelText: 'Tanggal Pengembalian',
border: OutlineInputBorder(),
@ -535,12 +583,10 @@ class _CreatePengembalianBarangPageState
),
),
),
SizedBox(height: 16),
SizedBox(height: 13),
Card(
elevation: 2,
child: Padding(
padding: const EdgeInsets.all(8),
padding: const EdgeInsets.all(8.0),
child: DropdownButtonFormField<WarehouseModel>(
validator: (value) {
if (value == null) {
@ -553,74 +599,80 @@ class _CreatePengembalianBarangPageState
border: OutlineInputBorder(),
),
hint: Text("Pilih Gudang"),
value: _valWarehouse,
items:
_dataWarehouse.map((WarehouseModel warehouse) {
return DropdownMenuItem<WarehouseModel>(
child: Text('${warehouse.name}'),
value: warehouse,
);
}).toList(),
value: warehouseSqfliteApi,
items: (_valwarehouse ?? [])
.where((warehouse) =>
warehouse.deleted_at != true)
.map((WarehouseModel warehouse) {
return DropdownMenuItem<WarehouseModel>(
child: Text('${warehouse.name}'),
value: warehouse,
);
}).toList() ??
[],
onChanged: (WarehouseModel? value) {
setState(() {
_valWarehouse = value;
warehouseSqfliteApi = value;
});
},
),
),
),
SizedBox(height: 16.0),
SizedBox(height: 13),
Card(
elevation: 2,
child: Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller: _kondisiPetiController,
decoration: InputDecoration(
labelText: 'Kondisi Barang',
border: OutlineInputBorder(),
),
padding: const EdgeInsets.all(8.0),
child: DropdownButtonFormField<ConditionPetiModel>(
validator: (value) {
if (value == null || value.isEmpty) {
if (value == null) {
return 'Harus diisi';
}
return null; // Return null jika tidak ada kesalahan
return null;
},
),
),
),
SizedBox(height: 20.0),
Visibility(
visible: false,
child: FractionallySizedBox(
widthFactor: 1.0,
child: Card(
elevation: 1,
child: Padding(
padding: const EdgeInsets.all(8),
child: Column(
children: [
Text(
'Data dari QR Code:',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 8),
Text(
result != null && result!.code != null
? result!.code!
: 'Belum ada data QR Code terpindai',
style: TextStyle(fontSize: 14),
),
],
),
decoration: InputDecoration(
labelText: 'Pilih Kondisi Peti',
border: OutlineInputBorder(),
),
hint: Text("Pilih Kondisi Peti"),
value: conditionPetiSqfliteApi,
items: (_valconditionPeti ?? [])
.where(
(kondisi) => kondisi.deleted_at != true)
.map((ConditionPetiModel kondisi) {
return DropdownMenuItem<ConditionPetiModel>(
child: Text('${kondisi.nama_kondisi}'),
value: kondisi,
);
}).toList() ??
[],
onChanged: (ConditionPetiModel? value) {
setState(() {
conditionPetiSqfliteApi = value;
});
},
),
),
),
// SizedBox(height: 16.0),
// Card(
// elevation: 2,
// child: Padding(
// padding: const EdgeInsets.all(8),
// child: TextFormField(
// controller: _kondisiPetiController,
// decoration: InputDecoration(
// labelText: 'Kondisi Barang',
// border: OutlineInputBorder(),
// ),
// validator: (value) {
// if (value == null || value.isEmpty) {
// return 'Harus diisi';
// }
// return null; // Return null jika tidak ada kesalahan
// },
// ),
// ),
// ),
],
),
),
@ -668,11 +720,13 @@ class _CreatePengembalianBarangPageState
color: Colors.green, // Warna hijau untuk save
),
child: IconButton(
onPressed: () {
onPressed: () async {
if (_formKey.currentState!.validate()) {
try {
if (_enterAtController.text.isNotEmpty) {
_updatePeminjaman();
if (_enterAtController.text.isNotEmpty &&
petiSqfliteApi != null &&
warehouseSqfliteApi != null) {
await saveAssetData();
}
} catch (e) {
print('Error storing data: $e');

801
lib/pages/pengembalian_barang/index.dart

@ -0,0 +1,801 @@
import 'dart:async';
import 'dart:convert';
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:siopas/models/condition_peti_model.dart';
import 'package:siopas/models/customer_model.dart';
import 'package:siopas/models/disposal_model.dart';
import 'package:siopas/models/m_asset_status_model.dart';
import 'package:siopas/models/type_peti_model.dart';
import 'package:siopas/models/warehouse_mode.dart';
import 'package:siopas/pages/pengembalian_barang/conn/syncronize.dart';
import 'package:siopas/pages/pengembalian_barang/controller/pengembalian_controller.dart';
import 'package:siopas/pages/pengembalian_barang/show.dart';
import 'package:siopas/services/syncronizeAPI.dart';
import 'package:siopas/services/controllerApi.dart';
import 'package:siopas/pages/peminjaman_barang/controller/peminjaman_controller.dart';
import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:siopas/models/asset_status_model.dart';
import 'package:collection/collection.dart';
import '../peminjaman_barang/show.dart';
// import 'show.dart';
class PengembalianBarangPage extends StatefulWidget {
const PengembalianBarangPage({super.key});
@override
State<PengembalianBarangPage> createState() => PengembalianBarangPageState();
}
class PengembalianBarangPageState extends State<PengembalianBarangPage> {
String? token;
bool loading = true;
// Reinit atau Upload Only
WarehouseModel? warehouseSqfliteApi;
List<TypePetiModel>? typePetiSqfliteApi;
List<CustomerModel>? customerSqfliteApi;
PetiAssetModel? petiSqfliteApi;
ConditionPetiModel? conditionPetiSqfliteApi;
DisposalPetiModel? disposalSqfliteApi;
List<PetiAssetModel>? _valpeti; // Change this line
List<WarehouseModel>? _valwarehouse;
List<ConditionPetiModel>? _valconditionPeti;
List<DisposalPetiModel>? _valdisposal;
// Datatable
int _currentPage = 1;
int _pageSize = 10;
List<AssetStatusModel>? _data;
List<PetiAssetModel>? _petiData;
List<TypePetiModel>? _tipePetiData;
List<CustomerModel>? _customerData;
List<WarehouseModel>? _warehouseData;
List<ConditionPetiModel>? _conditionData;
bool _isLoading = false;
Timer? _timer;
@override
void initState() {
super.initState();
_getUserToken();
warehouseListAPI();
conditionPetiListAPI();
typePetiListAPI();
customerListAPI();
petiListAPI();
// disposalListAPI();
// Tampil data Datatables
datatablesPengembalianList();
datatablesPetiList();
datatablesTipePetiList();
datatablesCustomerList();
datatablesWarehouseList();
datatablesConditionList();
_data = <AssetStatusModel>[];
}
void _getUserToken() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
if (mounted) {
setState(() {
token = prefs.getString('token');
});
}
}
// Reinit atau Upload Only ------------------------------------------------------------------------
Future warehouseListAPI() async {
if (mounted) {
await ControllerApi().fetchWarehouseDataAPI().then((value) {
setState(() {
_valwarehouse = (value as List<dynamic>)
.map((item) => WarehouseModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
// Future disposalListAPI() async {
// if (mounted) {
// await ControllerApi().fetchDisposalDataAPI().then((value) {
// setState(() {
// _valdisposal = (value as List<dynamic>)
// .map((item) => DisposalPetiModel.fromJson(item))
// .toList();
// loading = false;
// });
// });
// }
// }
Future typePetiListAPI() async {
if (mounted) {
await ControllerApi().fetchTipePetiDataAPI().then((value) {
setState(() {
typePetiSqfliteApi = (value as List<dynamic>)
.map((item) => TypePetiModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
Future customerListAPI() async {
if (mounted) {
await ControllerApi().fetchCustomerDataAPI().then((value) {
setState(() {
customerSqfliteApi = (value as List<dynamic>)
.map((item) => CustomerModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
Future petiListAPI() async {
if (mounted) {
await ControllerApi().fetchPetiDataAPI().then((value) {
setState(() {
_valpeti = (value as List<dynamic>)
.map((item) => PetiAssetModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
Future conditionPetiListAPI() async {
if (mounted) {
await ControllerApi().fetchKondisiPetiDataAPI().then((value) {
setState(() {
_valconditionPeti = (value as List<dynamic>)
.map((item) => ConditionPetiModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
// Future<void> reinitAssetStatusApi() async {
// List<AssetStatusModel> assetStatusApiData =
// await SyncronizationDataAPI().fetchAssetStatusFromApi();
// await ControllerApi()
// .deleteAllAssetStatusDataAPI(); // Clear existing data in SQLite
// await ControllerApi()
// .addAllAssetStatusDataAPI(assetStatusApiData); // Add new data to SQLite
// }
Future<void> reinitWarehouseApi() async {
EasyLoading.show(status: 'Mengambil data Warehouse...');
List<WarehouseModel> warehouseApiData =
await SyncronizationDataAPI().fetchWarehouseFromApi();
await ControllerApi()
.deleteAllWarehouseDataAPI(); // Clear existing data in SQLite
await ControllerApi()
.addAllWarehouseDataAPI(warehouseApiData); // Add new data to SQLite
EasyLoading.dismiss();
}
Future<void> reinitPetiApi() async {
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
EasyLoading.dismiss();
}
Future<void> reinitCustomerApi() async {
EasyLoading.show(status: 'Mengambil data Customer...');
List<CustomerModel> customerApiData =
await SyncronizationDataAPI().fetchCustomerFromApi();
await ControllerApi()
.deleteAllCustomerDataAPI(); // Clear existing data in SQLite
await ControllerApi()
.addAllCustomerDataAPI(customerApiData); // Add new data to SQLite
EasyLoading.dismiss();
}
Future<void> reinitConditionPetiApi() async {
EasyLoading.show(status: 'Mengambil data Condition Peti...');
List<ConditionPetiModel> conditionPetiApiData =
await SyncronizationDataAPI().fetchKondisiPetiFromApi();
await ControllerApi()
.deleteAllKondisiPetiDataAPI(); // Clear existing data in SQLite
await ControllerApi().addAllKondisiPetiDataAPI(
conditionPetiApiData); // Add new data to SQLite
EasyLoading.dismiss();
}
// Future<void> reinitDisposalApi() async {
// List<DisposalPetiModel> disposalApiData =
// await SyncronizationDataAPI().fetchDisposalFromApi();
// await ControllerApi()
// .deleteAllDisposalDataAPI(); // Clear existing data in SQLite
// await ControllerApi()
// .addAllDisposalDataAPI(disposalApiData); // Add new data to SQLite
// }
Future<void> fetchDataFromApiAndSync() async {
EasyLoading.show(status: 'Mengambil data dari Server...');
try {
await syncToMysql();
// await reinitAssetStatusApi();
await reinitWarehouseApi();
await reinitPetiApi();
await reinitCustomerApi();
// await reinitTypePetiApi();
await reinitConditionPetiApi();
// await reinitDisposalApi();
await datatablesPengembalianList();
EasyLoading.showSuccess('Data berhasil diperbarui');
} catch (e) {
EasyLoading.showError('Gagal memperbarui data: $e');
} finally {
EasyLoading.dismiss();
}
}
Future syncToMysql() async {
await SyncronizationPengembalianData()
.fetchAllInfo()
.then((assetList) async {
EasyLoading.show(
status: 'Jangan tutup aplikasi. Kami sedang menyinkronkan...');
await Future.delayed(Duration(seconds: 3));
// Tambahkan penanganan pengunggahan
bool uploadSuccess = await SyncronizationPengembalianData()
.savePengembalianToServerWith(assetList);
// Jika pengunggahan berhasil, hapus data lokal
if (uploadSuccess) {
await SyncronizationPengembalianData().deleteAllAssetStatusData();
// Setelah selesai, tampilkan pesan sukses
await datatablesPengembalianList();
EasyLoading.showSuccess('Berhasil disinkronkan dengan Server');
} else {
// Tampilkan pesan gagal jika pengunggahan tidak berhasil
EasyLoading.showError('Gagal disinkronkan dengan Server');
}
});
}
// Future syncToMysql() async {
// await SyncronizationData().fetchAllInfo().then((assetList) async {
// EasyLoading.show(status: 'Don\'t close app. We are syncing...');
// await SyncronizationData().saveToMysqlWith(assetList);
// await SyncronizationData().deleteAllAssetStatusData();
// // EasyLoading.showSuccess('Successfully saved to MySQL');
// });
// }
Future<void> isInteret() async {
await SyncronizationPengembalianData.isInternet().then((connection) {
if (connection) {
print("Internet connection available");
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("No Internet")));
}
});
}
// Datatables ------------------------------------------------------------------------
Future datatablesPengembalianList() async {
await ControllerPengembalian()
.fetchPengembalianLocalController()
.then((value) {
setState(() {
_data = (value as List<dynamic>)
.map((e) => AssetStatusModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesPetiList() async {
await ControllerPengembalian().fetchPetiData().then((value) {
setState(() {
_petiData = (value as List<dynamic>)
.map((e) => PetiAssetModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesTipePetiList() async {
await ControllerPengembalian().fetchTipePetiData().then((value) {
setState(() {
_tipePetiData = (value as List<dynamic>)
.map((e) => TypePetiModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesCustomerList() async {
await ControllerPengembalian().fetchCustomerData().then((value) {
setState(() {
_customerData = (value as List<dynamic>)
.map((e) => CustomerModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesWarehouseList() async {
await ControllerPengembalian().fetchWarehouseData().then((value) {
setState(() {
_warehouseData = (value as List<dynamic>)
.map((e) => WarehouseModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesConditionList() async {
await ControllerPengembalian().fetchConditionData().then((value) {
setState(() {
_conditionData = (value as List<dynamic>)
.map((e) => ConditionPetiModel.fromJson(e))
.toList();
loading = false;
});
});
}
void _loadMoreData() {
if (mounted && !_isLoading) {
setState(() {
_currentPage++;
});
datatablesPengembalianList();
}
}
@override
Widget build(BuildContext context) {
// Add this function outside the build method
void showSyncDialog(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
// Dialog shape and style
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
backgroundColor: Colors.grey[100],
elevation: 0,
// Dialog content
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Dialog title with close button
Container(
width: double.infinity,
color: Colors.indigo[700], // Indigo background
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
"Sync Server Pengembalian",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 16.0,
),
),
),
IconButton(
icon: Icon(
Icons.close,
color: Colors.white,
),
onPressed: () {
Navigator.pop(context); // Close dialog
},
),
],
),
),
// Divider
Divider(
height: 1,
thickness: 1,
color: Colors.black, // Black divider
),
// Re-init Button
Container(
width: double.infinity,
child: TextButton(
onPressed: () {
Navigator.pop(context); // Close dialog
fetchDataFromApiAndSync();
},
child: Text(
"Upload + Download",
style: TextStyle(
color: Colors.black,
fontSize: 16.0,
fontFamily: 'Poppins',
),
),
),
),
// Divider
// Divider(
// height: 1,
// thickness: 1,
// color: Colors.black, // Black divider
// ),
// Upload Only Button
// Container(
// width: double.infinity,
// child: TextButton(
// onPressed: () {
// Navigator.pop(context); // Close dialog
// syncToMysql();
// },
// child: Text(
// "Upload Only",
// style: TextStyle(
// color: Colors.black,
// fontSize: 16.0,
// fontFamily: 'Poppins',
// ),
// ),
// ),
// ),
],
),
);
},
);
}
return DefaultTabController(
length: 1,
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text('Data Pengembalian Barang',
style: TextStyle(
fontSize: 16,
)),
actions: [
IconButton(
icon: Icon(Icons.backup),
onPressed: () async {
if (await SyncronizationPengembalianData.isInternet()) {
// Display custom dialog when the IconButton is pressed
showSyncDialog(context);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("No internet connection")),
);
}
},
),
],
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
Navigator.pushNamed(context, '/home');
},
),
bottom: TabBar(
indicator: BoxDecoration(color: Color.fromARGB(255, 50, 39, 122)),
tabs: [
Tab(text: 'Pengembalian Peti Hari ini'),
],
),
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: TabBarView(
children: [
SingleChildScrollView(
child: Column(
children: [
SizedBox(
width: double.infinity,
child: PaginatedDataTable(
// header: Text('Searching'), // Removed const
rowsPerPage: _pageSize,
availableRowsPerPage: [10, 25, 50], // Removed const
onRowsPerPageChanged: (value) {
setState(() {
_pageSize = value!;
});
},
columns: [
DataColumn(label: Text('No')),
DataColumn(label: Text('')),
DataColumn(label: Text('Kode Peti')),
DataColumn(label: Text('Tgl Pengembalian')),
DataColumn(label: Text('PJ Pengembalian')),
DataColumn(label: Text('Tujuan WH Pengembalian')),
DataColumn(label: Text('Kondisi Peti')),
],
source: _DataSourceLokal(
data: _data!,
context: context,
petiData: _petiData != null ? _petiData : [],
tipePetiData:
_tipePetiData != null ? _tipePetiData : [],
customerData:
_customerData != null ? _customerData : [],
warehouseData:
_warehouseData != null ? _warehouseData : [],
conditionData:
_conditionData != null ? _conditionData : [],
),
),
),
],
),
),
],
),
bottomNavigationBar: BottomAppBar(
color: Color.fromARGB(255, 5, 28, 158), // Warna latar belakang
child: Container(
height: 65.0,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
InkWell(
customBorder: CircleBorder(),
onTap: () {
// Aksi ketika ikon diklik
Navigator.pushNamed(context, '/pengembalian-barang/edit');
},
child: Container(
width: 45,
height: 45,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.greenAccent[700],
),
child: Icon(
Icons.add,
size: 30,
color: Colors.white,
),
),
),
],
),
),
),
),
);
}
}
class _DataSourceLokal extends DataTableSource {
final List<AssetStatusModel> data;
List<PetiAssetModel>? petiData;
List<TypePetiModel>? tipePetiData;
List<CustomerModel>? customerData;
List<WarehouseModel>? warehouseData;
List<ConditionPetiModel>? conditionData;
final BuildContext context;
_DataSourceLokal({
required this.data,
required this.petiData,
required this.tipePetiData,
required this.customerData,
required this.warehouseData,
required this.conditionData,
required this.context,
});
@override
DataRow? getRow(int index) {
if (index >= data.length) {
return null;
}
data.sort((a, b) {
if (a.created_at == null && b.created_at == null) {
return 0; // Both dates are null, consider them equal
} else if (a.created_at == null) {
return 1; // Null is considered greater than non-null
} else if (b.created_at == null) {
return -1; // Non-null is considered smaller than null
} else {
return b.created_at!.compareTo(a.created_at!); // Compare non-null dates
}
});
final item = data[index];
// Menemukan data peti yang sesuai dengan asset
PetiAssetModel? petiSqfliteApi;
if (item.peti_id != null) {
petiSqfliteApi = petiData!.firstWhere(
(peti) => peti.id == item.peti_id,
orElse: () => PetiAssetModel(
id: null,
tipe_peti_id: null,
warna: 'null',
packing_no: null,
customer_id: null,
warehouse_id: null,
kondisipeti_id: null,
jumlah: null,
date_pembuatan: DateTime.now(),
created_by: 'null',
updated_by: 'null',
fix_lot: '',
),
);
}
TypePetiModel? tipePetiSqfliteApi;
if (petiSqfliteApi != null && petiSqfliteApi.tipe_peti_id != null) {
tipePetiSqfliteApi = tipePetiData?.firstWhere(
(tipePeti) => tipePeti.id == petiSqfliteApi?.tipe_peti_id,
orElse: () => TypePetiModel(
id: null,
type: 'null',
size_peti: 'null',
description: 'null',
created_by: 'null',
updated_by: 'null',
),
);
}
CustomerModel? customerSqfliteApi;
if (petiSqfliteApi != null && petiSqfliteApi.customer_id != null) {
customerSqfliteApi = customerData?.firstWhere(
(customer) => customer.id == petiSqfliteApi?.customer_id,
orElse: () => CustomerModel(
id: null,
name: 'null',
code_customer: 'null',
lot_no: 'null',
created_by: 'null',
updated_by: 'null',
),
);
}
ConditionPetiModel? conditionSqfliteApi;
if (item.kondisi_peti_id != null) {
conditionSqfliteApi = conditionData?.firstWhere(
(warehouse) => warehouse.id == item.kondisi_peti_id,
orElse: () => ConditionPetiModel(
id: null,
nama_kondisi: 'null',
created_by: 'null',
updated_by: 'null',
),
);
}
WarehouseModel? warehouseSqfliteApi;
if (item.enter_warehouse != null) {
warehouseSqfliteApi = warehouseData?.firstWhere(
(warehouse) => warehouse.id == item.enter_warehouse,
orElse: () => WarehouseModel(
id: null,
name: 'null',
created_by: 'null',
updated_by: 'null',
),
);
}
return DataRow(cells: [
DataCell(
Text(
(index + 1).toString(),
),
),
DataCell(
GestureDetector(
onTap: () {
if (item.id != null) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailPengembalianBarangPage(
pengembalianId: 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
? petiSqfliteApi!.fix_lot.toString()
: '-',
),
),
DataCell(
Text(
item.enter_at != null
? DateFormat('dd-MM-yyyy').format(item.enter_at!)
: '-',
),
),
DataCell(
Text(
item.enter_pic.toString() != 'null' ? item.enter_pic.toString() : '-',
),
),
DataCell(
Text(
(item.enter_warehouse != null && item.enter_warehouse != 'null')
? warehouseSqfliteApi != null &&
warehouseSqfliteApi.id == item.enter_warehouse
? warehouseSqfliteApi.name.toString()
: '-'
: '-',
),
),
DataCell(
Text(
conditionSqfliteApi != null &&
conditionSqfliteApi.nama_kondisi != null
? conditionSqfliteApi!.nama_kondisi.toString()
: '-',
),
),
]);
}
@override
bool get isRowCountApproximate => false;
@override
int get rowCount => data.length;
@override
int get selectedRowCount => 0;
}

296
lib/pages/pengembalian_barang/pengembalian_index.dart

@ -1,296 +0,0 @@
import 'dart:convert';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:data_table_2/data_table_2.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:siopas/models/asset_status_model.dart';
import 'package:siopas/pages/pengembalian_barang/show.dart';
import 'package:siopas/providers/asset_status_provider.dart';
import 'package:http/http.dart' as http;
import '../../connection/connection.dart';
import '../peminjaman_barang/show.dart';
class PengembalianBarangPage extends StatefulWidget {
const PengembalianBarangPage({super.key});
@override
State<PengembalianBarangPage> createState() => PengembalianBarangPageState();
}
class PengembalianBarangPageState extends State<PengembalianBarangPage> {
String? token;
int _currentPage = 1;
int _pageSize = 10;
List<AssetStatusModel> _data = [];
bool _isLoading = false;
@override
void initState() {
super.initState();
_getUserToken();
fetchData();
}
void _getUserToken() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
if (mounted) {
setState(() {
token = prefs.getString('token');
});
}
}
Future<void> fetchData() async {
if (mounted) {
setState(() {
_isLoading = true;
});
try {
final response =
await http.get(Uri.parse('$baseUrl/asset-status/pengembalian'));
if (response.statusCode == 200) {
final jsonData = json.decode(response.body)['data']['asset_status'];
final List<AssetStatusModel> newData = (jsonData as List)
.map((item) => AssetStatusModel.fromJson(item))
.toList();
if (mounted) {
setState(() {
_data.addAll(newData);
_isLoading = false;
});
}
} else {
if (mounted) {
setState(() {
_isLoading = false;
});
}
throw Exception('Failed to fetch data');
}
} catch (e) {
if (mounted) {
setState(() {
_isLoading = false;
});
}
print('Error fetching data: $e');
}
}
}
void _loadMoreData() {
if (mounted && !_isLoading) {
setState(() {
_currentPage++;
});
fetchData();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text('Data Pengembalian Barang',
style: TextStyle(
fontSize: 16,
)),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
Navigator.pushNamed(context, '/home');
},
),
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: SingleChildScrollView(
child: SizedBox(
width: double.infinity,
child: PaginatedDataTable(
header: const Text('Pengembalian Barang'),
rowsPerPage: _pageSize,
availableRowsPerPage: const [10, 25, 50],
onRowsPerPageChanged: (value) {
setState(() {
_pageSize = value!;
});
},
columns: const [
DataColumn(label: Text('No')),
DataColumn(label: Text('')),
DataColumn(label: Text('Kode Peti')),
DataColumn(label: Text('Tgl Peminjaman')),
DataColumn(label: Text('Estimasi Pengembalian')),
DataColumn(label: Text('PJ Peminjaman')),
DataColumn(label: Text('Asal WH Peminjaman')),
DataColumn(label: Text('Tgl Pengembalian')),
DataColumn(label: Text('PJ Pengembalian')),
DataColumn(label: Text('Tujuan WH Pengembalian')),
DataColumn(label: Text('Kondisi Peti')),
DataColumn(label: Text('Status')),
],
source: _DataSource(data: _data, context: context),
),
),
),
bottomNavigationBar: BottomAppBar(
color: Color.fromARGB(255, 5, 28, 158), // Warna latar belakang
child: Container(
height: 65.0,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
InkWell(
customBorder: CircleBorder(),
onTap: () {
// Aksi ketika ikon diklik
Navigator.pushNamed(context, '/pengembalian-barang/create');
},
child: Container(
width: 45,
height: 45,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.greenAccent[700],
),
child: Icon(
Icons.add,
size: 30,
color: Colors.white,
),
),
),
],
),
),
),
);
}
}
class _DataSource extends DataTableSource {
final List<AssetStatusModel> data;
final BuildContext context;
_DataSource({required this.data, required this.context});
@override
DataRow? getRow(int index) {
if (index >= data.length) {
return null;
}
final item = data[index];
return DataRow(cells: [
DataCell(
Text(
(index + 1).toString(),
),
),
DataCell(
GestureDetector(
onTap: () {
if (item.id != null) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailPengembalianBarangPage(
pengembalianId: item.id!,
),
),
);
print('asset id: ${item.id}');
}
},
child: Icon(
Icons.article_outlined,
size: 30,
color: Colors.indigo[700],
),
),
),
DataCell(
Text(
// item.asset.exit_at.toString(),
item.peti!.customer!.code_customer.toString() +
'-' +
item.peti!.tipe_peti!.type.toString(),
),
),
DataCell(
Text(
item.exit_at != null
? DateFormat('dd-MM-yyyy').format(item.exit_at!)
: '-',
),
),
DataCell(
Text(
// item.asset.exit_at.toString(),
item.est_pengembalian != null
? DateFormat('dd-MM-yyyy').format(item.est_pengembalian!)
: '-',
),
),
DataCell(
Text(
item.exit_pic.toString() != 'null' ? item.exit_pic.toString() : '-',
),
),
DataCell(
Text(item.warehouse!.name.toString() != 'null'
? item.warehouse!.name.toString()
: '-'),
),
DataCell(
Text(
item.enter_at != null
? DateFormat('dd-MM-yyyy').format(item.enter_at!)
: '-',
),
),
DataCell(
Text(
item.enter_pic.toString() != 'null' ? item.enter_pic.toString() : '-',
),
),
DataCell(
Text(
item.warehouse_enter!.id == item.enter_warehouse
? item.warehouse_enter!.name.toString()
: '-',
),
),
DataCell(
Text(item.kondisi_peti.toString() != 'null'
? item.kondisi_peti.toString()
: '-'),
),
DataCell(
Text(item.warehouse_enter!.name == 'null' ? '-' : 'Sudah Dikembalikan'),
),
]);
}
@override
bool get isRowCountApproximate => false;
@override
int get rowCount => data.length;
@override
int get selectedRowCount => 0;
}

274
lib/pages/pengembalian_barang/show.dart

@ -1,12 +1,19 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:siopas/models/asset_status_model.dart';
import 'package:siopas/models/condition_peti_model.dart';
import 'package:siopas/models/customer_model.dart';
import 'package:siopas/models/m_asset_status_model.dart';
import 'package:siopas/pages/pengembalian_barang/controller/pengembalian_controller.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:intl/intl.dart';
import 'package:siopas/connection/connection.dart';
import 'package:collection/collection.dart';
import '../../models/warehouse_mode.dart';
import '../../services/controllerApi.dart';
class DetailPengembalianBarangPage extends StatefulWidget {
final int pengembalianId;
final String pengembalianId;
const DetailPengembalianBarangPage({Key? key, required this.pengembalianId})
: super(key: key);
@ -17,60 +24,134 @@ class DetailPengembalianBarangPage extends StatefulWidget {
class _DetailPengembalianBarangPageState
extends State<DetailPengembalianBarangPage> {
Map<String, dynamic>? assetStatusData;
AssetStatusModel? pengembalianInfo;
WarehouseModel? warehouseInfo;
String _formatDate(String date) {
try {
DateTime parsedDate = DateTime.parse(date);
String formattedDate =
DateFormat('EEEE, dd MMMM yyyy', 'id_ID').format(parsedDate);
return formattedDate;
} catch (e) {
// Handle the case where the date string is not valid
return 'Invalid date format';
}
}
List<PetiAssetModel>? petiData;
List<CustomerModel>? customerData;
List<WarehouseModel>? warehouseData;
List<ConditionPetiModel>? _valconditionPeti;
bool loading = true;
@override
void initState() {
super.initState();
_fetchAssetStatusDataPengembalian();
getPengembalianIdData();
customerListAPI();
petiListAPI();
warehouseListAPI();
kondisiPetiListAPI();
initializeDateFormatting('id_ID', null);
}
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 kondisiPetiListAPI() async {
if (mounted) {
await ControllerApi().fetchKondisiPetiDataAPI().then((value) {
setState(() {
_valconditionPeti = (value as List<dynamic>)
.map((item) => ConditionPetiModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
Future<void> _fetchAssetStatusDataPengembalian() async {
try {
final response = await http.get(
Uri.parse(
'$baseUrl/asset-status/pengembalian/show/${widget.pengembalianId}'),
headers: {
'Content-Type': 'application/json',
},
);
if (response.statusCode == 200) {
Future warehouseListAPI() async {
if (mounted) {
await ControllerApi().fetchWarehouseDataAPI().then((value) {
setState(() {
assetStatusData = json.decode(response.body)['data']['asset_status'];
warehouseData = (value as List<dynamic>)
.map((item) => WarehouseModel.fromJson(item))
.toList();
loading = false;
});
} else {
throw Exception('Failed to load data');
}
} catch (e) {
print('Error fetching data: $e');
});
}
}
Future<void> getPengembalianIdData() async {
List<AssetStatusModel> pengembalians =
await ControllerPengembalian().fetchPengembalianDataId();
pengembalianInfo = pengembalians.firstWhereOrNull(
(pengembalian) => pengembalian.id.toString() == widget.pengembalianId,
);
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 '';
}
}
@override
Widget build(BuildContext context) {
PetiAssetModel? petiSqfliteApi;
petiSqfliteApi = petiData?.firstWhereOrNull(
(peti) => peti.id == pengembalianInfo!.peti_id,
);
CustomerModel? customerSqfliteApi;
customerSqfliteApi = customerData?.firstWhereOrNull(
(customer) => customer.id == pengembalianInfo?.customer_id,
);
WarehouseModel? warehouseSqfliteApi;
warehouseSqfliteApi = warehouseData?.firstWhereOrNull(
(warehouse) => warehouse.id == pengembalianInfo!.enter_warehouse,
);
ConditionPetiModel? conditionPetiSqfliteApi;
conditionPetiSqfliteApi = _valconditionPeti?.firstWhereOrNull(
(conditionPeti) => conditionPeti.id == pengembalianInfo!.kondisi_peti_id,
);
return Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text('Detail Pengembalian Barang',
style: TextStyle(
color: Colors.white,
fontSize: 16,
)),
title: Text(
'Detail Pengembalian Barang',
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
@ -97,89 +178,76 @@ class _DetailPengembalianBarangPageState
color: Colors.indigo[700],
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(Icons.article,
size: 40,
color: Colors.white), // Ganti ikon sesuai kebutuhan
SizedBox(width: 10),
Text(
'ID: ${widget.pengembalianId}',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
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 (assetStatusData != null) ...[
if (pengembalianInfo != null) ...[
_buildDetailItem(
'Kode Peti',
assetStatusData!['peti']['customer']['code_customer'] +
' - ' +
assetStatusData!['peti']['tipe_peti']['type'],
petiSqfliteApi != null && petiSqfliteApi.fix_lot != null
? petiSqfliteApi!.fix_lot.toString()
: '-',
),
Divider(thickness: 1),
_buildDetailItem(
'Nama Customer',
assetStatusData!['peti']['customer']['name'] != null
? assetStatusData!['peti']['customer']['name']
.toString()
: '-'),
Divider(thickness: 1),
_buildDetailItem(
'Tgl Peminjaman',
_formatDate(assetStatusData!['exit_at'] != null
? assetStatusData!['exit_at']
: '-')),
_buildDetailItem('Tgl Pengembalian',
_formatDate(pengembalianInfo!.enter_at.toString())),
Divider(thickness: 1),
_buildDetailItem(
'PJ Peminjaman',
assetStatusData!['exit_pic'] != null
? assetStatusData!['exit_pic'].toString()
: '-'),
'PJ Pengembalian', pengembalianInfo!.enter_pic.toString()),
Divider(thickness: 1),
_buildDetailItem(
'Asal WH Peminjaman',
assetStatusData!['warehouse']['name'] != null
? assetStatusData!['warehouse']['name'].toString()
'Gudang',
warehouseSqfliteApi != null &&
warehouseSqfliteApi.name != null
? warehouseSqfliteApi!.name.toString()
: '-'),
Divider(thickness: 1),
_buildDetailItem(
'Tgl Pengembalian',
assetStatusData!['enter_at'] != null &&
assetStatusData!['enter_at'] != '0000-00-00 00:00:00'
? _formatDate(assetStatusData!['enter_at'])
'Kondisi Peti',
conditionPetiSqfliteApi != null &&
conditionPetiSqfliteApi.nama_kondisi != null
? conditionPetiSqfliteApi!.nama_kondisi.toString()
: '-',
),
Divider(thickness: 1),
_buildDetailItem(
'PJ Pengembalian',
assetStatusData!['enter_pic'] != null
? assetStatusData!['enter_pic'].toString()
: '-'),
Divider(thickness: 1),
_buildDetailItem(
'Tujuan WH Pengembalian',
assetStatusData!['warehouse_enter'] != null
? assetStatusData!['warehouse_enter']['name'].toString()
: '-'),
Divider(thickness: 1),
_buildDetailItem(
'Kondisi Peti',
assetStatusData!['kondisi_peti'] != null
? assetStatusData!['kondisi_peti'].toString()
: '-'),
Divider(thickness: 1),
_buildDetailItem(
'Status',
assetStatusData!['warehouse_enter'] != null
? assetStatusData!['warehouse_enter']['name'].toString()
: '-'),
// ... tambahkan data lainnya sesuai kebutuhan
],
],
),
@ -196,7 +264,7 @@ class _DetailPengembalianBarangPageState
children: [
Text(
label,
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
style: TextStyle(fontSize: 12.5, fontWeight: FontWeight.bold),
),
Text(value),
],

174
lib/pages/sign_in_page.dart

@ -19,38 +19,69 @@ class _SignInPageState extends State<SignInPage> {
bool isLoading = false;
bool _isPasswordVisible = false;
// Create controllers for IP Address and Port
TextEditingController ipAddressController = TextEditingController();
TextEditingController portController = TextEditingController();
@override
Widget build(BuildContext context) {
final bool isSmallScreen = MediaQuery.of(context).size.width < 600;
AuthProvider authProvider = Provider.of<AuthProvider>(context);
UserModel user = authProvider.user;
// Function to show the SettingsModal
void _showSettingsModal(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return SettingsModal();
},
);
}
return Scaffold(
body: Center(
child: isSmallScreen
? SingleChildScrollView(
reverse: true,
scrollDirection: Axis.vertical, // Tambahkan ini
child: Column(
mainAxisSize: MainAxisSize.min,
children: const [
_Logo(),
_FormContent(),
],
),
)
: Container(
padding: const EdgeInsets.all(30.0),
constraints: const BoxConstraints(maxWidth: 800),
child: Row(
children: const [
Expanded(child: _Logo()),
Expanded(
child: Center(child: _FormContent()),
),
],
body: Center(
child: isSmallScreen
? SingleChildScrollView(
reverse: true,
scrollDirection: Axis.vertical, // Tambahkan ini
child: Column(
mainAxisSize: MainAxisSize.min,
children: const [
_Logo(),
_FormContent(),
],
),
)
: Container(
padding: const EdgeInsets.all(30.0),
constraints: const BoxConstraints(maxWidth: 800),
child: Row(
children: [
Expanded(child: _Logo()),
Expanded(
child: Center(child: _FormContent()),
),
)));
],
),
),
),
bottomNavigationBar: BottomAppBar(
color: Colors.grey[50],
elevation: 0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: () {
_showSettingsModal(context); // Show the modal
},
child: Text('Settings'),
),
],
),
),
);
}
}
@ -122,6 +153,9 @@ class __FormContentState extends State<_FormContent> {
// Simpan token pengguna ke SharedPreferences
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('token', user.token!); // Pastikan user.token tidak null
// Role ID Operator
// final String roleId = 'A5C7B207-1A1C-43B8-89BF-222222222222';
print('token dapat login: ${user.token}');
if (user.role_id == 2) {
print('Berhasil login HALAMAN USER');
@ -277,3 +311,95 @@ class __FormContentState extends State<_FormContent> {
Widget _gap() => const SizedBox(height: 16);
}
class SettingsModal extends StatefulWidget {
const SettingsModal({Key? key}) : super(key: key);
@override
State<SettingsModal> createState() => _SettingsModalState();
}
class _SettingsModalState extends State<SettingsModal> {
TextEditingController ipAddressController = TextEditingController();
TextEditingController portController = TextEditingController();
@override
void initState() {
super.initState();
// Load saved IP Address and Port when the modal is initialized
loadSettings();
}
void loadSettings() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String ipAddress = prefs.getString('ipAddress') ?? '';
String port = prefs.getString('port') ?? '';
setState(() {
ipAddressController.text = ipAddress;
portController.text = port;
});
}
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Settings'),
GestureDetector(
onTap: () {
Navigator.of(context).pop(); // Close the modal
},
child: Icon(Icons.close),
),
],
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
controller: ipAddressController,
keyboardType: TextInputType.number, // Set numeric keyboard
decoration: InputDecoration(labelText: 'IP Address'),
),
SizedBox(height: 16),
TextFormField(
controller: portController,
keyboardType: TextInputType.number, // Set numeric keyboard
decoration: InputDecoration(labelText: 'Port'),
),
],
),
actions: [
ElevatedButton(
onPressed: () {
// Save IP Address and Port to SharedPreferences
saveSettings(ipAddressController.text, portController.text);
Navigator.of(context).pop(); // Close the modal
},
child: Text('Save'),
),
],
);
}
void saveSettings(String ipAddress, String port) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('ipAddress', ipAddress);
prefs.setString('port', port);
// Print the saved data
print('IP Address saved: $ipAddress');
print('Port saved: $port');
}
// Function to clear the IP Address and Port in SharedPreferences
void clearSettings() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.remove('ipAddress');
prefs.remove('port');
print('IP Address and Port cleared');
}
}

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

@ -0,0 +1,224 @@
import 'dart:convert';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:siopas/models/transfer_peti_model.dart';
import 'package:internet_connection_checker/internet_connection_checker.dart';
import 'package:intl/intl.dart';
import '../../../connection/connection.dart';
import '../../../migrations/databasehelper.dart';
import '../../../models/asset_status_model.dart';
import 'package:http/http.dart' as http;
class SyncronizationTransferPetiData {
Future<int> addData(TransferPetiModel transferPetiModel) async {
final dbClient = await conn.db;
late int result;
try {
result = await dbClient!.insert(
SqfliteDatabaseHelper.transferPetiTable, transferPetiModel.toJson());
} catch (e) {
print('Error adding data to local SQLite: $e');
result = 0; // Handle the error appropriately
}
return result;
}
Future<List> fetchData() async {
var dbclient = await conn.db;
List transferPetiList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.transferPetiTable, orderBy: 'id DESC');
for (var item in maps) {
transferPetiList.add(item);
}
} catch (e) {
print(e.toString());
}
return transferPetiList;
}
static Future<bool> isInternet() async {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
if (await InternetConnectionChecker().hasConnection) {
print("Mobile data detected & internet connection confirmed.");
return true;
} else {
print('No internet :( Reason:');
return false;
}
} else if (connectivityResult == ConnectivityResult.wifi) {
if (await InternetConnectionChecker().hasConnection) {
print("wifi data detected & internet connection confirmed.");
return true;
} else {
print('No internet :( Reason:');
return false;
}
} else {
print(
"Neither mobile data or WIFI detected, not internet connection found.");
return false;
}
}
final conn = SqfliteDatabaseHelper.instance;
Future<List<TransferPetiModel>> fetchAllInfoTransferPeti() async {
final dbClient = await conn.db;
List<TransferPetiModel> transferPetiList = [];
try {
final maps =
await dbClient!.query(SqfliteDatabaseHelper.transferPetiTable);
for (var item in maps) {
transferPetiList.add(TransferPetiModel.fromJson(item));
}
} catch (e) {
print(e.toString());
}
return transferPetiList;
}
Future<void> deleteAllTransferPetiData() async {
var dbClient = await conn.db;
await dbClient!.delete(SqfliteDatabaseHelper.transferPetiTable);
}
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<List> fetchAllPetiTransferInfo() async {
final dbClient = await conn.db;
List transferPetiList = [];
try {
final maps =
await dbClient!.query(SqfliteDatabaseHelper.transferPetiTable);
for (var item in maps) {
transferPetiList.add(item);
}
} catch (e) {
print(e.toString());
}
return transferPetiList;
}
Future saveToMysql(List transferPetiLocalList) async {
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;
}
}
for (var i = 0; i < transferPetiLocalList.length; i++) {
// 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(), // "id": "1
"created_at": formattedCreatedAt,
};
final response = await http.post(
Uri.parse(await getBaseUrl() + '/m-transfer-peti/store'),
body: data);
if (response.statusCode == 200) {
print(response.body);
print("Saving Data Transfer Peti");
} else {
print(response.statusCode);
print(
"Failed to upload data for index $i. Status code: ${response.statusCode}");
}
}
}
Future<List<TransferPetiModel>> fetchTransferPetiFromApi() async {
final response = await http.get(
Uri.parse(await getBaseUrl() + '/m-transfer-peti'),
);
if (response.statusCode == 200) {
List<dynamic> data = json.decode(response.body)['data']['transfer_peti'];
List<TransferPetiModel> transferPetiDBList = data
.map((item) =>
TransferPetiModel.fromJson(item as Map<String, dynamic>))
.toList();
return transferPetiDBList;
} else {
throw Exception('Failed to fetch data from API Transfer Peti');
}
}
}

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

@ -0,0 +1,191 @@
import 'dart:async';
import 'package:connectivity_plus/connectivity_plus.dart';
// import 'package:siopas/models/asset_status_model.dart';
import 'package:siopas/models/transfer_peti_model.dart';
// import 'package:http/http.dart' as http;
import 'package:internet_connection_checker/internet_connection_checker.dart';
import 'package:sqflite/sqflite.dart';
import '../../../migrations/databasehelper.dart';
class ControllerTransferPeti {
final conn = SqfliteDatabaseHelper.instance;
Future<List<TransferPetiModel>> fetchAllInfo() async {
final dbClient = await conn.db;
List<TransferPetiModel> transferPetiList = [];
try {
final maps =
await dbClient!.query(SqfliteDatabaseHelper.transferPetiTable);
for (var item in maps) {
transferPetiList.add(TransferPetiModel.fromJson(item));
}
} catch (e) {
print(e.toString());
}
return transferPetiList;
}
static Future<bool> isInternet() async {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
if (await InternetConnectionChecker().hasConnection) {
print("Mobile data detected & internet connection confirmed.");
return true;
} else {
print('No internet :( Reason:');
return false;
}
} else if (connectivityResult == ConnectivityResult.wifi) {
if (await InternetConnectionChecker().hasConnection) {
print("wifi data detected & internet connection confirmed.");
return true;
} else {
print('No internet :( Reason:');
return false;
}
} else {
print(
"Neither mobile data or WIFI detected, not internet connection found.");
return false;
}
}
Future<int> addData(TransferPetiModel transferPetiAddModel) async {
var dbclient = await conn.db;
int result = 0; // Provide an initial value
try {
result = await dbclient!.insert(SqfliteDatabaseHelper.transferPetiTable,
transferPetiAddModel.toJson());
} catch (e) {
print(e.toString());
}
return result;
}
Future<int> updateData(TransferPetiModel transferPetiAddModel) async {
var dbclient = await conn.db;
late int result;
try {
result = await dbclient!.update(
SqfliteDatabaseHelper.transferPetiTable,
transferPetiAddModel.toJson(),
where: 'id=?',
whereArgs: [transferPetiAddModel.id],
);
} catch (e) {
print(e.toString());
}
return result;
}
Future<List> fetchTransferPetiLocalController() async {
var dbclient = await conn.db;
List transferPetiList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.transferPetiTable, orderBy: 'id DESC');
for (var item in maps) {
transferPetiList.add(item);
}
} catch (e) {
print(e.toString());
}
return transferPetiList;
}
Future<List<TransferPetiModel>> fetchDataId() async {
var dbclient = await conn.db;
List<TransferPetiModel> transferPetiList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.transferPetiTable, orderBy: 'id DESC');
for (var item in maps) {
transferPetiList.add(TransferPetiModel.fromJson(item));
}
} catch (e) {
print(e.toString());
}
return transferPetiList;
}
Future<void> deleteAllData() async {
var dbClient = await conn.db;
await dbClient!.delete(SqfliteDatabaseHelper.transferPetiTable);
}
Future<void> addAllData(List<TransferPetiModel> transferPetiList) async {
var dbclient = await conn.db;
Batch batch = dbclient!.batch();
for (var transferPeti in transferPetiList) {
batch.insert(
SqfliteDatabaseHelper.transferPetiTable,
transferPeti.toJson(),
);
}
await batch.commit();
}
Future<List> fetchPetiData() async {
var dbclient = await conn.db;
List petiList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.petiTable, orderBy: 'id DESC');
for (var item in maps) {
petiList.add(item);
}
} catch (e) {
print(e.toString());
}
return petiList;
}
Future<List> fetchTipePetiData() async {
var dbclient = await conn.db;
List tipePetiList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.typePetiTable, orderBy: 'id DESC');
for (var item in maps) {
tipePetiList.add(item);
}
} catch (e) {
print(e.toString());
}
return tipePetiList;
}
Future<List> fetchCustomerData() async {
var dbclient = await conn.db;
List customerList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.customerTable, orderBy: 'id DESC');
for (var item in maps) {
customerList.add(item);
}
} catch (e) {
print(e.toString());
}
return customerList;
}
Future<List> fetchWarehouseData() async {
var dbclient = await conn.db;
List warehouseList = [];
try {
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.warehouseTable, orderBy: 'id DESC');
for (var item in maps) {
warehouseList.add(item);
}
} catch (e) {
print(e.toString());
}
return warehouseList;
}
}

812
lib/pages/transfer_peti/edit.dart

@ -1,38 +1,71 @@
import 'dart:convert';
import 'dart:core';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:siopas/models/asset_status_model.dart';
import 'package:siopas/models/condition_peti_model.dart';
import 'package:siopas/models/customer_model.dart';
import 'package:siopas/models/transfer_peti_model.dart';
import 'package:siopas/models/type_peti_model.dart';
import 'package:siopas/pages/peminjaman_barang/conn/syncronize.dart';
import 'package:siopas/pages/pengembalian_barang/conn/syncronize.dart';
import 'package:siopas/pages/transfer_peti/controller/transfer_peti_controller.dart';
import 'package:siopas/services/controllerApi.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:siopas/connection/connection.dart';
import 'package:http/http.dart' as http;
import 'package:siopas/models/asset_status_model.dart';
import 'package:siopas/models/m_asset_status_model.dart';
// import 'package:siopas/models/m_asset_status_model.dart';
import 'package:siopas/models/user_model.dart';
import 'package:siopas/models/warehouse_mode.dart';
import 'package:siopas/providers/auth_provider.dart';
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 '../../models/user_model.dart';
import '../../providers/auth_provider.dart';
import 'package:collection/collection.dart';
// import 'conn/syncronizeAPI.dart';
// import 'controller/peminjaman_controller.dart';
class EditTransferPetiPage extends StatefulWidget {
const EditTransferPetiPage({super.key});
const EditTransferPetiPage({Key? key}) : super(key: key);
@override
State<EditTransferPetiPage> createState() => EditTransferPetiPageState();
State<EditTransferPetiPage> createState() => _EditTransferPetiPageState();
}
class EditTransferPetiPageState extends State<EditTransferPetiPage> {
List<PetiAssetModel> _dataAsset = [];
List<WarehouseModel> _dataWarehouse = [];
bool _isLoading = false;
class _EditTransferPetiPageState extends State<EditTransferPetiPage> {
List<TransferPetiModel>? _data;
String? token;
PetiAssetModel? _valAsset;
WarehouseModel? _valWarehouse_asal_gudang;
WarehouseModel? _valWarehouse_tujuan_gudang;
// TextEditingController _exit_atController = TextEditingController();
// TextEditingController _est_pengembalianController = TextEditingController();
List<TypePetiModel>? typePetiSqfliteApi;
// List<CustomerModel>? customerSqfliteApi;
// List<WarehouseModel>? warehouseTujuanSqfliteApi;
PetiAssetModel? petiSqfliteApi;
ConditionPetiModel? conditionPetiSqfliteApi;
WarehouseModel? warehouseSqfliteApi;
WarehouseModel? warehouseTujuanSqfliteApi;
CustomerModel? customerItemSqfliteApi;
List<PetiAssetModel>? _valpeti; // Change this line
List<WarehouseModel>? _valwarehouse;
List<WarehouseModel>? _valWarehouse_tujuan_gudang;
List<ConditionPetiModel>? _valconditionPeti;
List<CustomerModel>? _valcustomer;
CustomerModel? customerSqfliteApi;
List<PetiAssetModel> _unrestrictedPetiList = [];
List<PetiAssetModel> _filteredPetiList = [];
bool isQRCodeScanned = false;
bool loading = true;
TextEditingController _dateController = TextEditingController();
// TextEditingController _enterPicController = TextEditingController();
// TextEditingController _kondisiPetiController = TextEditingController();
// TextEditingController _penanggungJawabController = TextEditingController();
final _formKey = GlobalKey<FormState>();
@ -44,9 +77,15 @@ class EditTransferPetiPageState extends State<EditTransferPetiPage> {
void initState() {
super.initState();
_getUserToken();
fetchDataWarehouse();
fetchDataAsset();
initializeDateFormatting('id_ID');
warehouseListAPI();
datatablesTransferPetiList();
// typePetiListAPI();
customerListAPI();
petiListAPI();
kondisiPetiListAPI();
initializeDateFormatting('id_ID', null);
}
void _getUserToken() async {
@ -54,74 +93,85 @@ class EditTransferPetiPageState extends State<EditTransferPetiPage> {
if (mounted) {
setState(() {
token = prefs.getString('token');
loading = false;
});
}
}
Future<void> fetchDataAsset() async {
setState(() {
_isLoading = true;
});
final response = await http.get(Uri.parse('$baseUrl/peti-asset'));
Future warehouseListAPI() async {
if (mounted) {
// Periksa apakah widget masih "mounted"
if (response.statusCode == 200) {
final jsonData = json.decode(response.body)['data']['petis'];
final List<PetiAssetModel> newDataAsset = (jsonData as List)
.map((item) => PetiAssetModel.fromJson(item))
.toList();
await ControllerApi().fetchWarehouseDataAPI().then((value) {
setState(() {
_valwarehouse = (value as List<dynamic>)
.map((item) => WarehouseModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
if (mounted) {
// Periksa lagi sebelum memanggil setState
setState(() {
_dataAsset.addAll(newDataAsset);
_isLoading = false;
});
}
} else {
if (mounted) {
setState(() {
_isLoading = false;
});
}
throw Exception('Failed to fetch data Asset Status');
}
Future customerListAPI() async {
if (mounted) {
await ControllerApi().fetchCustomerDataAPI().then((value) {
setState(() {
_valcustomer = (value as List<dynamic>)
.map((item) => CustomerModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
Future<void> fetchDataWarehouse() async {
setState(() {
_isLoading = true;
Future datatablesTransferPetiList() async {
await ControllerTransferPeti()
.fetchTransferPetiLocalController()
.then((value) {
setState(() {
_data = (value as List<dynamic>)
.map((e) => TransferPetiModel.fromJson(e))
.toList();
loading = false;
});
});
}
final response = await http.get(Uri.parse('$baseUrl/m-warehouse'));
Future petiListAPI() async {
if (mounted) {
if (response.statusCode == 200) {
final jsonData = json.decode(response.body)['data']['warehouse'];
await ControllerApi().fetchPetiDataAPI().then((value) {
setState(() {
_valpeti = (value as List<dynamic>)
.map((item) => PetiAssetModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
final List<WarehouseModel> newDataWarehouse = (jsonData as List)
.map((item) => WarehouseModel.fromJson(item))
.toList();
Future kondisiPetiListAPI() async {
if (mounted) {
await ControllerApi().fetchKondisiPetiDataAPI().then((value) {
setState(() {
_valconditionPeti = (value as List<dynamic>)
.map((item) => ConditionPetiModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
if (mounted) {
setState(() {
_dataWarehouse.addAll(newDataWarehouse);
_isLoading = false;
});
}
Future<void> isInteret() async {
await SyncronizationPengembalianData.isInternet().then((connection) {
if (connection) {
print("Internet connection available");
} else {
if (mounted) {
setState(() {
_isLoading = false;
});
}
throw Exception('Failed to fetch data Warehouse');
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("No Internet")));
}
}
});
}
Future<void> _onQRViewCreated(QRViewController controller) async {
@ -133,93 +183,164 @@ class EditTransferPetiPageState extends State<EditTransferPetiPage> {
await Future.delayed(const Duration(milliseconds: 400));
controller.flipCamera();
controller.scannedDataStream.listen((scanData) {
if (!scanned) {
try {
setState(() {
result = scanData;
controller.scannedDataStream.listen(
(scanData) {
if (!scanned) {
try {
setState(() {
result = scanData;
List<String> lines = result!.code!.split('\n');
String idPeti = '';
String idWarehouse = '';
for (String line in lines) {
if (line.contains(';')) {
List<String> values = line.split(';');
if (values.length >= 3) {
idPeti = values[1];
idWarehouse = values[2];
break;
}
}
}
List<String> lines = result!.code!.split('\n');
int? petiId = int.tryParse(idPeti);
int? warehouseId = int.tryParse(idWarehouse);
// AuthProvider authProvider = Provider.of<AuthProvider>(context, listen: false);
// UserModel user = authProvider.user;
// Dalam fungsi yang menangani pemindaian QR code
// Dalam fungsi yang menangani pemindaian QR code
if (petiId != null && warehouseId != null) {
// Check apakah peti dengan warehouse_id yang sesuai ada dalam daftar yang diizinkan
PetiAssetModel? allowedPeti = _valpeti?.firstWhereOrNull(
(peti) =>
peti.id == petiId &&
peti.deleted_at != true &&
peti.status == 'AKTIF',
);
if (allowedPeti != null) {
setState(() {
isQRCodeScanned = true;
// Mengisi _filteredPetiList untuk dropdown hasil QR Code
_filteredPetiList = [
_valpeti!.firstWhere((peti) => peti.id == allowedPeti.id)
];
petiSqfliteApi = allowedPeti;
warehouseSqfliteApi = _valwarehouse?.firstWhereOrNull(
(warehouse) => warehouse.id == allowedPeti.warehouse_id,
);
customerItemSqfliteApi = _valcustomer?.firstWhereOrNull(
(customer) => customer.id == allowedPeti.customer_id,
);
});
} else {
// Tampilkan pesan error jika data tidak sesuai dengan hak akses
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Data Peti tidak ditemukan atau tidak sesuai dengan hak akses.',
style: TextStyle(
color: Colors.white,
fontSize: 12,
),
),
backgroundColor: Colors.red[700],
action: SnackBarAction(
label: 'Tutup',
onPressed: () {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
},
),
),
);
setState(() {
isQRCodeScanned = false;
petiSqfliteApi = null;
warehouseSqfliteApi = null;
});
}
} else {
// Tampilkan pesan error jika nilai yang dipindai tidak sesuai
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Row(
children: [
Icon(
Icons.warning,
color: Colors.black,
),
SizedBox(width: 8),
Text(
'Nilai QR Code tidak sesuai dengan yang diharapkan.',
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
),
],
),
backgroundColor: Colors.yellow[700],
),
);
setState(() {
isQRCodeScanned = false;
petiSqfliteApi = null;
warehouseSqfliteApi = null;
});
}
String idPeti = '';
String idWarehouse = '';
scanned = true;
});
for (String line in lines) {
if (line.contains(';')) {
List<String> values = line.split(';');
if (values.length >= 3) {
idPeti = values[1];
idWarehouse = values[2];
break;
}
controller.stopCamera();
Future.delayed(Duration(milliseconds: 500), () {
if (mounted) {
Navigator.of(context).pop();
}
}
int? petiId = int.tryParse(idPeti);
int? warehouseId = int.tryParse(idWarehouse);
if (petiId != null && warehouseId != null) {
_valAsset = _dataAsset.firstWhere(
(peti) => peti.id == petiId,
orElse: () => _valAsset!,
);
_valWarehouse_asal_gudang = _dataWarehouse.firstWhere(
(warehouse) => warehouse.id == warehouseId,
orElse: () => _valWarehouse_asal_gudang!,
);
} else {
// Jika nilai yang dipindai tidak sesuai, tampilkan pesan kesalahan
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Row(
children: [
Icon(
Icons.warning,
color: Colors.black, // Warna ikon
),
SizedBox(width: 8), // Jarak antara ikon dan teks
Text(
'Nilai QR Code tidak sesuai dengan yang diharapkan.',
});
} catch (e) {
controller.stopCamera();
// Reset nilai dropdown Peti dan Warehouse
setState(() {
petiSqfliteApi = null;
warehouseSqfliteApi = null;
});
print('Error scanning QR Code: $e');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Row(
children: [
Icon(
Icons.error,
color: Colors.red[400],
),
SizedBox(width: 8),
Flexible(
child: Text(
e.toString(),
style: TextStyle(
color: Colors.black,
color: Colors.white,
fontSize: 12,
), // Warna teks
),
),
],
),
backgroundColor:
Colors.yellow[700], // Warna latar belakang SnackBar
),
],
),
);
}
scanned = true;
});
controller.stopCamera();
Future.delayed(Duration(milliseconds: 500), () {
if (mounted) {
Navigator.of(context).pop();
}
});
} catch (e) {
print('Error scanning QR Code: $e');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Error scanning QR Code: $e'),
),
);
backgroundColor: Colors.red[700],
),
);
}
}
}
});
}
@override
void dispose() {
super.dispose();
controller?.dispose();
},
);
}
@override
@ -227,117 +348,73 @@ class EditTransferPetiPageState extends State<EditTransferPetiPage> {
AuthProvider authProvider =
Provider.of<AuthProvider>(context, listen: false);
UserModel user = authProvider.user;
var scanArea = (MediaQuery.of(context).size.width < 400 ||
MediaQuery.of(context).size.height < 400)
? 150.0
: 300.0;
// var now = DateTime.now();
// var dt = DateTime(DateTime.now().year, DateTime.now().month,
// DateTime.now().day, DateTime.now().hour, DateTime.now().minute);
// // _exit_atController.text = DateFormat('yyyy-MM-dd HH:mm:ss').format(dt);
// _exit_atController.text = DateFormat('dd-MM-yyyy').format(dt);
var uuid = Uuid();
Future<void> _updateTransferPeti() async {
setState(() {
_isLoading = true;
});
DateTime? parseDateTime(String? dateTimeString) {
if (dateTimeString == null || dateTimeString.isEmpty) {
return null;
}
try {
final response = await http.put(
Uri.parse('$baseUrl/peti-asset/update/${_valAsset!.id}'),
headers: {
'Content-Type': 'application/json',
'Authorization': token!,
},
body: jsonEncode({
'warehouse_id': _valWarehouse_tujuan_gudang!.id,
'updated_by': user.fullname,
}),
);
print(response.body);
if (response.statusCode == 200) {
final jsonData = json.decode(response.body)['data']['petis'];
return DateTime.parse(dateTimeString);
} catch (e) {
print('Error parsing DateTime: $e');
return null;
}
}
print('Berhasil memperbarui data: $jsonData');
Future<void> saveAssetData() async {
DateTime now = DateTime.now().toLocal();
String formattedDate = DateFormat('yyyy-MM-dd HH:mm:ss.SSS').format(now);
if (_dateController.text.isNotEmpty) {
TransferPetiModel transferPetiAddModel = TransferPetiModel(
id: null,
mobile_id: uuid.v4(),
peti_id: petiSqfliteApi!.id,
name_customer: customerItemSqfliteApi!.id,
source_warehouse: warehouseSqfliteApi!.id,
destination_warehouse: warehouseTujuanSqfliteApi!.id,
date: parseDateTime(_dateController.text),
created_by: user.fullname,
created_at: parseDateTime(formattedDate),
);
// Tampilkan snackbar
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.greenAccent[700],
content: Row(
children: [
Icon(
Icons.check_circle_outline,
color: Colors.white,
),
SizedBox(width: 5),
Text('Data berhasil ditransferkan'),
],
),
duration: Duration(seconds: 3), // Durasi tampilan snackbar
),
);
// Reset form input
_valAsset = null;
_valWarehouse_asal_gudang = null;
_valWarehouse_tujuan_gudang = null;
// _enterAtController.text = '';
// _enterPicController.text = '';
// _kondisiPetiController.text = '';
// _valWarehouse = null;
// Call addData function
int result =
await ControllerTransferPeti().addData(transferPetiAddModel);
if (result > 0) {
print("Success Tambah data");
// print(result);
Navigator.pushNamed(context, '/transfer-peti');
EasyLoading.showSuccess("Data Berhasil Disimpan Transfer Peti");
} else {
_valAsset = null;
_valWarehouse_asal_gudang = null;
_valWarehouse_tujuan_gudang = null;
throw Exception('Gagal memperbarui data Asset Status');
}
} catch (e) {
print('Error updating data: $e');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent[700],
content: Row(
children: [
Icon(
Icons.error_outline,
color: Colors.white,
),
SizedBox(width: 5),
Text('Gagal memperbarui data'),
],
),
duration: Duration(seconds: 2), // Durasi tampilan snackbar
),
);
} finally {
if (mounted) {
setState(() {
_isLoading = false;
});
print("Failed");
}
}
}
var scanArea = (MediaQuery.of(context).size.width < 400 ||
MediaQuery.of(context).size.height < 400)
? 250.0
: 300.0;
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text('Buat Peminjaman Barang',
title: Text('Buat Transfer Peti',
style: TextStyle(
fontSize: 16,
)),
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
body: loading
? Center(child: CircularProgressIndicator())
: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
padding: const EdgeInsets.all(8.0),
child: Form(
key: _formKey,
child: Column(
@ -361,25 +438,46 @@ class EditTransferPetiPageState extends State<EditTransferPetiPage> {
border: OutlineInputBorder(),
),
hint: Text("Pilih Peti"),
value: _valAsset,
items: _dataAsset.map((PetiAssetModel item) {
value: petiSqfliteApi,
items: (isQRCodeScanned
? _filteredPetiList
: (_valpeti ?? []).where((peti) =>
peti.deleted_at != true &&
(peti.warehouse_id ==
user.warehouse_id) &&
(peti.status == 'AKTIF')))
.map((PetiAssetModel peti) {
return DropdownMenuItem<PetiAssetModel>(
child: Text('${item.fix_lot}'),
value: item,
child: Text(
'${peti.fix_lot}',
style: TextStyle(
fontSize: 12,
),
),
value: peti,
);
}).toList(),
onChanged: (PetiAssetModel? value) {
setState(() {
_valAsset = value;
petiSqfliteApi = value;
if (value != null) {
// Set _valWarehouse berdasarkan warehouse_id dari PetiAssetModel
_valWarehouse_asal_gudang =
_dataWarehouse.firstWhere(
warehouseSqfliteApi =
_valwarehouse?.firstWhere(
(warehouse) =>
warehouse.id ==
int.parse(value.warehouse_id
.toString()),
value.warehouse_id,
);
customerItemSqfliteApi =
_valcustomer?.firstWhereOrNull(
(customer) =>
customer.id == value.customer_id,
);
// Perbarui _unrestrictedPetiList sesuai pemilihan manual
_unrestrictedPetiList = [
_valpeti!.firstWhere(
(peti) => peti.id == value.id)
];
}
});
},
@ -467,7 +565,50 @@ class EditTransferPetiPageState extends State<EditTransferPetiPage> {
elevation: 2,
child: Padding(
padding: const EdgeInsets.all(8),
child: DropdownButtonFormField<WarehouseModel>(
child: FormBuilderDateTimePicker(
validator: (value) {
if (_dateController.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent[700],
content: Row(
children: [
Icon(
Icons.error_outline,
color: Colors.white,
),
SizedBox(width: 5),
Text(
'Tanggal Transfer Peti harus diisi'),
],
),
duration: Duration(seconds: 2),
),
);
return null; // Return null jika ada kesalahan
}
return null; // Return null jika tidak ada kesalahan
},
controller: _dateController,
name: 'tanggal',
inputType: InputType.date,
// format: DateFormat('yyyy-MM-dd HH:mm:ss.SSS'),
format: DateFormat('yyyy-MM-dd', 'id_ID'),
// format: DateFormat('yyyy-MM-dd'),
decoration: InputDecoration(
labelText: 'Tanggal Transfer Peti',
border: OutlineInputBorder(),
suffixIcon: Icon(Icons.calendar_today),
),
),
),
),
SizedBox(height: 13),
Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: DropdownButtonFormField<CustomerModel>(
validator: (value) {
if (value == null) {
return 'Harus diisi';
@ -475,32 +616,33 @@ class EditTransferPetiPageState extends State<EditTransferPetiPage> {
return null;
},
decoration: InputDecoration(
labelText: 'Asal Gudang',
labelText: 'Pilih Customer',
border: OutlineInputBorder(),
),
hint: Text("Asal Gudang"),
value: _valWarehouse_asal_gudang,
items:
_dataWarehouse.map((WarehouseModel warehouse) {
return DropdownMenuItem<WarehouseModel>(
child: Text('${warehouse.name}'),
value: warehouse,
);
}).toList(),
onChanged: null,
// (WarehouseModel? value) {
// setState(() {
// _valWarehouse_asal_gudang = value;
// });
// },
hint: Text("Pilih Customer"),
value: customerItemSqfliteApi,
items: (_valcustomer ?? [])
.where((customer) =>
customer.deleted_at != true)
.map((CustomerModel customer) {
return DropdownMenuItem<CustomerModel>(
child: Text('${customer.name}'),
value: customer,
);
}).toList() ??
[],
onChanged: (CustomerModel? value) {
setState(() {
customerItemSqfliteApi = value;
});
},
),
),
),
SizedBox(height: 16),
SizedBox(height: 13),
Card(
elevation: 2,
child: Padding(
padding: const EdgeInsets.all(8),
padding: const EdgeInsets.all(8.0),
child: DropdownButtonFormField<WarehouseModel>(
validator: (value) {
if (value == null) {
@ -509,56 +651,102 @@ class EditTransferPetiPageState extends State<EditTransferPetiPage> {
return null;
},
decoration: InputDecoration(
labelText: 'Tujuan Gudang',
labelText: 'Pilih Asal Gudang',
border: OutlineInputBorder(),
),
hint: Text("Tujuan Gudang"),
value: _valWarehouse_tujuan_gudang,
items:
_dataWarehouse.map((WarehouseModel warehouse) {
return DropdownMenuItem<WarehouseModel>(
child: Text('${warehouse.name}'),
value: warehouse,
);
}).toList(),
hint: Text("Pilih Asal Gudang"),
value: warehouseSqfliteApi,
items: (_valwarehouse ?? [])
.where((warehouse) =>
warehouse.deleted_at != true)
.map((WarehouseModel warehouse) {
return DropdownMenuItem<WarehouseModel>(
child: Text('${warehouse.name}'),
value: warehouse,
);
}).toList() ??
[],
onChanged: (WarehouseModel? value) {
setState(() {
_valWarehouse_tujuan_gudang = value;
warehouseSqfliteApi = value;
});
},
),
),
),
Visibility(
visible: false,
child: FractionallySizedBox(
widthFactor: 1.0,
child: Card(
elevation: 1,
child: Padding(
padding: const EdgeInsets.all(8),
child: Column(
children: [
Text(
'Data dari QR Code:',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 8),
Text(
result != null && result!.code != null
? result!.code!
: 'Belum ada data QR Code terpindai',
style: TextStyle(fontSize: 14),
),
],
),
SizedBox(height: 13),
Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: DropdownButtonFormField<WarehouseModel>(
validator: (value) {
if (value == null) {
return 'Harus diisi';
}
return null;
},
decoration: InputDecoration(
labelText: 'Pilih Tujuan Gudang',
border: OutlineInputBorder(),
),
hint: Text("Pilih Tujuan Gudang"),
value: warehouseTujuanSqfliteApi,
items: (_valwarehouse ?? [])
.where((warehouseTujuan) =>
warehouseTujuan.deleted_at != true)
.map((WarehouseModel warehouseTujuan) {
return DropdownMenuItem<WarehouseModel>(
child: Text('${warehouseTujuan.name}'),
value: warehouseTujuan,
);
}).toList() ??
[],
onChanged: (WarehouseModel? value) {
setState(() {
warehouseTujuanSqfliteApi = value;
});
},
),
),
),
// SizedBox(height: 16),
// Card(
// elevation: 2,
// child: Padding(
// padding: const EdgeInsets.all(8),
// child: DropdownButtonFormField<WarehouseModel>(
// validator: (value) {
// if (value == null) {
// return 'Harus diisi';
// }
// return null;
// },
// decoration: InputDecoration(
// labelText: 'Pilih Tujuan Gudang',
// border: OutlineInputBorder(),
// ),
// hint: Text("Pilih Tujuan Gudang"),
// value: warehouseTujuanSqfliteApi,
// items: (_valWarehouse_tujuan_gudang ?? [])
// .where(
// (warehouse) => warehouse.deleted_at != true)
// .map((WarehouseModel warehouse)
// // _valWarehouse_tujuan_gudang?.map((warehouse)
// {
// return DropdownMenuItem<WarehouseModel>(
// child: Text('${warehouse.name}'),
// value: warehouse,
// );
// }).toList(),
// onChanged: (WarehouseModel? value) {
// setState(() {
// warehouseTujuanSqfliteApi = value;
// });
// },
// ),
// ),
// ),
],
),
),
@ -606,10 +794,14 @@ class EditTransferPetiPageState extends State<EditTransferPetiPage> {
color: Colors.green, // Warna hijau untuk save
),
child: IconButton(
onPressed: () {
onPressed: () async {
if (_formKey.currentState!.validate()) {
try {
_updateTransferPeti();
if (_dateController.text.isNotEmpty &&
petiSqfliteApi != null &&
warehouseSqfliteApi != null) {
await saveAssetData();
}
} catch (e) {
print('Error storing data: $e');
}

751
lib/pages/transfer_peti/index.dart

@ -0,0 +1,751 @@
import 'dart:async';
import 'dart:convert';
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:siopas/models/customer_model.dart';
import 'package:siopas/models/disposal_model.dart';
import 'package:siopas/models/m_asset_status_model.dart';
import 'package:siopas/models/transfer_peti_model.dart';
import 'package:siopas/models/type_peti_model.dart';
import 'package:siopas/models/warehouse_mode.dart';
import 'package:siopas/pages/peminjaman_barang/conn/syncronize.dart';
import 'package:siopas/pages/transfer_peti/conn/syncronize.dart';
import 'package:siopas/pages/transfer_peti/controller/transfer_peti_controller.dart';
import 'package:siopas/services/syncronizeAPI.dart';
import 'package:siopas/services/controllerApi.dart';
import 'package:siopas/pages/peminjaman_barang/controller/peminjaman_controller.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:siopas/models/asset_status_model.dart';
import 'package:siopas/providers/asset_status_provider.dart';
import 'package:http/http.dart' as http;
import '../../connection/connection.dart';
import '../../models/condition_peti_model.dart';
class TransferPetiPage extends StatefulWidget {
const TransferPetiPage({super.key});
@override
State<TransferPetiPage> createState() => TransferPetiPageState();
}
class TransferPetiPageState extends State<TransferPetiPage> {
String? token;
bool loading = true;
// Reinit atau Upload Only
WarehouseModel? warehouseSqfliteApi;
List<TypePetiModel>? typePetiSqfliteApi;
List<CustomerModel>? customerSqfliteApi;
PetiAssetModel? petiSqfliteApi;
DisposalPetiModel? disposalSqfliteApi;
List<PetiAssetModel>? _valpeti; // Change this line
List<WarehouseModel>? _valwarehouse;
List<DisposalPetiModel>? _valdisposal;
// Datatable
int _currentPage = 1;
int _pageSize = 10;
List<TransferPetiModel>? _data;
List<PetiAssetModel>? _petiData;
List<TypePetiModel>? _tipePetiData;
List<CustomerModel>? _customerData;
List<WarehouseModel>? _warehouseData;
bool _isLoading = false;
Timer? _timer;
@override
void initState() {
super.initState();
_getUserToken();
warehouseListAPI();
typePetiListAPI();
customerListAPI();
petiListAPI();
// disposalListAPI();
// Tampil data Datatables
// datatablesAssetStatusList();
datatablesTransferPetiList();
datatablesPetiList();
datatablesTipePetiList();
datatablesCustomerList();
datatablesWarehouseList();
_data = <TransferPetiModel>[];
}
void _getUserToken() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
if (mounted) {
setState(() {
token = prefs.getString('token');
});
}
}
// Reinit atau Upload Only ------------------------------------------------------------------------
Future warehouseListAPI() async {
if (mounted) {
await ControllerApi().fetchWarehouseDataAPI().then((value) {
setState(() {
_valwarehouse = (value as List<dynamic>)
.map((item) => WarehouseModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
// Future disposalListAPI() async {
// if (mounted) {
// await ControllerApi().fetchDisposalDataAPI().then((value) {
// setState(() {
// _valdisposal = (value as List<dynamic>)
// .map((item) => DisposalPetiModel.fromJson(item))
// .toList();
// loading = false;
// });
// });
// }
// }
Future typePetiListAPI() async {
if (mounted) {
await ControllerApi().fetchTipePetiDataAPI().then((value) {
setState(() {
typePetiSqfliteApi = (value as List<dynamic>)
.map((item) => TypePetiModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
Future customerListAPI() async {
if (mounted) {
await ControllerApi().fetchCustomerDataAPI().then((value) {
setState(() {
customerSqfliteApi = (value as List<dynamic>)
.map((item) => CustomerModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
Future petiListAPI() async {
if (mounted) {
await ControllerApi().fetchPetiDataAPI().then((value) {
setState(() {
_valpeti = (value as List<dynamic>)
.map((item) => PetiAssetModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
// Future<void> reinitAssetStatusApi() async {
// List<AssetStatusModel> assetStatusApiData =
// await SyncronizationDataAPI().fetchAssetStatusFromApi();
// await ControllerApi()
// .deleteAllAssetStatusDataAPI(); // Clear existing data in SQLite
// await ControllerApi()
// .addAllAssetStatusDataAPI(assetStatusApiData); // Add new data to SQLite
// }
Future<void> reinitWarehouseApi() async {
EasyLoading.show(status: 'Mengambil data Warehouse...');
List<WarehouseModel> warehouseApiData =
await SyncronizationDataAPI().fetchWarehouseFromApi();
await ControllerApi()
.deleteAllWarehouseDataAPI(); // Clear existing data in SQLite
await ControllerApi()
.addAllWarehouseDataAPI(warehouseApiData); // Add new data to SQLite
EasyLoading.dismiss();
}
Future<void> reinitPetiApi() async {
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
EasyLoading.dismiss();
}
Future<void> reinitCustomerApi() async {
EasyLoading.show(status: 'Mengambil data Customer...');
List<CustomerModel> customerApiData =
await SyncronizationDataAPI().fetchCustomerFromApi();
await ControllerApi()
.deleteAllCustomerDataAPI(); // Clear existing data in SQLite
await ControllerApi()
.addAllCustomerDataAPI(customerApiData); // Add new data to SQLite
EasyLoading.dismiss();
}
Future<void> reinitConditionPetiApi() async {
EasyLoading.show(status: 'Mengambil data Condition Peti...');
List<ConditionPetiModel> conditionPetiApiData =
await SyncronizationDataAPI().fetchKondisiPetiFromApi();
await ControllerApi()
.deleteAllKondisiPetiDataAPI(); // Clear existing data in SQLite
await ControllerApi().addAllKondisiPetiDataAPI(
conditionPetiApiData); // Add new data to SQLite
EasyLoading.dismiss();
}
// Future<void> reinitDisposalApi() async {
// List<DisposalPetiModel> disposalApiData =
// await SyncronizationDataAPI().fetchDisposalFromApi();
// await ControllerApi()
// .deleteAllDisposalDataAPI(); // Clear existing data in SQLite
// await ControllerApi()
// .addAllDisposalDataAPI(disposalApiData); // Add new data to SQLite
// }
Future<void> fetchDataFromApiAndSync() async {
EasyLoading.show(status: 'Mengambil data dari Server...');
try {
await syncToMysql();
// await reinitAssetStatusApi();
await reinitWarehouseApi();
await reinitPetiApi();
await reinitCustomerApi();
// await reinitTypePetiApi();
await reinitConditionPetiApi();
// await reinitDisposalApi();
// await datatablesAssetStatusList();
await datatablesTransferPetiList();
EasyLoading.showSuccess('Data berhasil diperbarui');
} catch (e) {
EasyLoading.showError('Gagal memperbarui data: $e');
} finally {
EasyLoading.dismiss();
}
}
Future syncToMysql() async {
await SyncronizationTransferPetiData()
.fetchAllInfoTransferPeti()
.then((transferPetiList) async {
EasyLoading.show(
status: 'Jangan tutup aplikasi. Kami sedang menyinkronkan...');
await Future.delayed(Duration(seconds: 3));
// Tambahkan penanganan pengunggahan
bool uploadSuccess = await SyncronizationTransferPetiData()
.saveTransferPetiServerWith(transferPetiList);
// Jika pengunggahan berhasil, hapus data lokal
if (uploadSuccess) {
await SyncronizationTransferPetiData().deleteAllTransferPetiData();
// Setelah selesai, tampilkan pesan sukses
EasyLoading.showSuccess('Berhasil disinkronkan dengan Server');
// await datatablesAssetStatusList();
await datatablesTransferPetiList();
} else {
// Tampilkan pesan gagal jika pengunggahan tidak berhasil
EasyLoading.showError('Gagal disinkronkan dengan Server');
}
});
}
// Future syncToMysql() async {
// await SyncronizationData().fetchAllInfo().then((assetList) async {
// EasyLoading.show(status: 'Don\'t close app. We are syncing...');
// await SyncronizationData().saveToMysqlWith(assetList);
// await SyncronizationData().deleteAllAssetStatusData();
// // EasyLoading.showSuccess('Successfully saved to MySQL');
// });
// }
Future<void> isInteret() async {
await SyncronizationPeminjamanData.isInternet().then((connection) {
if (connection) {
print("Internet connection available");
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("No Internet")));
}
});
}
// Datatables ------------------------------------------------------------------------
Future datatablesTransferPetiList() async {
await ControllerTransferPeti()
.fetchTransferPetiLocalController()
.then((value) {
setState(() {
_data = (value as List<dynamic>)
.map((e) => TransferPetiModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesPetiList() async {
await Controller().fetchPetiData().then((value) {
setState(() {
_petiData = (value as List<dynamic>)
.map((e) => PetiAssetModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesTipePetiList() async {
await Controller().fetchTipePetiData().then((value) {
setState(() {
_tipePetiData = (value as List<dynamic>)
.map((e) => TypePetiModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesCustomerList() async {
await Controller().fetchCustomerData().then((value) {
setState(() {
_customerData = (value as List<dynamic>)
.map((e) => CustomerModel.fromJson(e))
.toList();
loading = false;
});
});
}
Future datatablesWarehouseList() async {
await Controller().fetchWarehouseData().then((value) {
setState(() {
_warehouseData = (value as List<dynamic>)
.map((e) => WarehouseModel.fromJson(e))
.toList();
loading = false;
});
});
}
void _loadMoreData() {
if (mounted && !_isLoading) {
setState(() {
_currentPage++;
});
// datatablesAssetStatusList();
datatablesTransferPetiList();
}
}
@override
Widget build(BuildContext context) {
// Add this function outside the build method
void showSyncDialog(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
// Dialog shape and style
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
backgroundColor: Colors.grey[100],
elevation: 0,
// Dialog content
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Dialog title with close button
Container(
width: double.infinity,
color: Colors.indigo[700], // Indigo background
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
"Sync Server Transfer Peti",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 16.0,
),
),
),
IconButton(
icon: Icon(
Icons.close,
color: Colors.white,
),
onPressed: () {
Navigator.pop(context); // Close dialog
},
),
],
),
),
// Divider
Divider(
height: 1,
thickness: 1,
color: Colors.black, // Black divider
),
// Re-init Button
Container(
width: double.infinity,
child: TextButton(
onPressed: () {
Navigator.pop(context); // Close dialog
fetchDataFromApiAndSync();
},
child: Text(
"Upload + Download",
style: TextStyle(
color: Colors.black,
fontSize: 16.0,
fontFamily: 'Poppins',
),
),
),
),
// Divider
// Divider(
// height: 1,
// thickness: 1,
// color: Colors.black, // Black divider
// ),
// Upload Only Button
// Container(
// width: double.infinity,
// child: TextButton(
// onPressed: () {
// Navigator.pop(context); // Close dialog
// syncToMysql();
// },
// child: Text(
// "Upload Only",
// style: TextStyle(
// color: Colors.black,
// fontSize: 16.0,
// fontFamily: 'Poppins',
// ),
// ),
// ),
// ),
],
),
);
},
);
}
return DefaultTabController(
length: 1,
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text('Data Transfer Peti',
style: TextStyle(
fontSize: 16,
)),
actions: [
IconButton(
icon: Icon(Icons.backup),
onPressed: () async {
if (await SyncronizationPeminjamanData.isInternet()) {
// Display custom dialog when the IconButton is pressed
showSyncDialog(context);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("No internet connection")),
);
}
},
),
],
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
Navigator.pushNamed(context, '/home');
},
),
bottom: TabBar(
indicator: BoxDecoration(color: Color.fromARGB(255, 50, 39, 122)),
tabs: [
Tab(text: 'Transfer Peti Hari ini'),
],
),
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: TabBarView(
children: [
SingleChildScrollView(
child: Column(
children: [
SizedBox(
width: double.infinity,
child: PaginatedDataTable(
// header: Text('Searching'), // Removed const
rowsPerPage: _pageSize,
availableRowsPerPage: [10, 25, 50], // Removed const
onRowsPerPageChanged: (value) {
setState(() {
_pageSize = value!;
});
},
columns: [
DataColumn(label: Text('No')),
DataColumn(label: Text('Kode Peti')),
DataColumn(label: Text('Customer')),
DataColumn(label: Text('Tgl Transfer')),
DataColumn(label: Text('Asal Gudang')),
DataColumn(label: Text('Tujuan Gudang')),
],
source: _DataSourceLokal(
// data: _data!,
data: _data != null ? _data! : [],
context: context,
petiData: _petiData != null ? _petiData : [],
tipePetiData:
_tipePetiData != null ? _tipePetiData : [],
customerData:
_customerData != null ? _customerData : [],
warehouseData:
_warehouseData != null ? _warehouseData : [],
),
),
),
],
),
),
],
),
bottomNavigationBar: BottomAppBar(
color: Color.fromARGB(255, 5, 28, 158), // Warna latar belakang
child: Container(
height: 65.0,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
InkWell(
customBorder: CircleBorder(),
onTap: () {
// Aksi ketika ikon diklik
Navigator.pushNamed(context, '/transfer-peti/edit');
},
child: Container(
width: 45,
height: 45,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.greenAccent[700],
),
child: Icon(
Icons.add,
size: 30,
color: Colors.white,
),
),
),
],
),
),
),
),
);
}
}
class _DataSourceLokal extends DataTableSource {
final List<TransferPetiModel> data;
List<PetiAssetModel>? petiData;
List<TypePetiModel>? tipePetiData;
List<CustomerModel>? customerData;
List<WarehouseModel>? warehouseData;
final BuildContext context;
_DataSourceLokal({
required this.data,
required this.petiData,
required this.tipePetiData,
required this.customerData,
required this.warehouseData,
required this.context,
});
@override
DataRow? getRow(int index) {
if (index >= data.length) {
return null;
}
data.sort((a, b) {
if (a.created_at == null && b.created_at == null) {
return 0; // Both dates are null, consider them equal
} else if (a.created_at == null) {
return 1; // Null is considered greater than non-null
} else if (b.created_at == null) {
return -1; // Non-null is considered smaller than null
} else {
return b.created_at!.compareTo(a.created_at!); // Compare non-null dates
}
});
final item = data[index];
// Menemukan data peti yang sesuai dengan asset
PetiAssetModel? petiSqfliteApi;
if (item.peti_id != null) {
petiSqfliteApi = petiData!.firstWhere(
(peti) => peti.id == item.peti_id,
orElse: () => PetiAssetModel(
id: null,
tipe_peti_id: null,
warna: 'null',
packing_no: null,
customer_id: null,
warehouse_id: null,
kondisipeti_id: null,
jumlah: null,
date_pembuatan: DateTime.now(),
created_by: 'null',
updated_by: 'null',
fix_lot: '',
),
);
}
TypePetiModel? tipePetiSqfliteApi;
if (petiSqfliteApi != null && petiSqfliteApi.tipe_peti_id != null) {
tipePetiSqfliteApi = tipePetiData?.firstWhere(
(tipePeti) => tipePeti.id == petiSqfliteApi?.tipe_peti_id,
orElse: () => TypePetiModel(
id: null,
type: 'null',
size_peti: 'null',
description: 'null',
created_by: 'null',
updated_by: 'null',
),
);
}
CustomerModel? customerSqfliteApi;
if (petiSqfliteApi != null && petiSqfliteApi.customer_id != null) {
customerSqfliteApi = customerData?.firstWhere(
(customer) => customer.id == petiSqfliteApi?.customer_id,
orElse: () => CustomerModel(
id: null,
name: 'null',
code_customer: 'null',
lot_no: 'null',
created_by: 'null',
updated_by: 'null',
),
);
}
WarehouseModel? warehouseAsalGudangSqfliteApi;
if (item.source_warehouse != null) {
warehouseAsalGudangSqfliteApi = warehouseData?.firstWhere(
(warehouse) => warehouse.id == item.source_warehouse,
orElse: () => WarehouseModel(
id: null,
name: 'null',
created_by: 'null',
updated_by: 'null',
),
);
}
WarehouseModel? warehouseTujuanGudangSqfliteApi;
if (item.destination_warehouse != null) {
warehouseTujuanGudangSqfliteApi = warehouseData?.firstWhere(
(warehouse) => warehouse.id == item.destination_warehouse,
orElse: () => WarehouseModel(
id: null,
name: 'null',
created_by: 'null',
updated_by: 'null',
),
);
}
return DataRow(cells: [
DataCell(
Text(
(index + 1).toString(),
),
),
DataCell(
Text(
petiSqfliteApi != null && petiSqfliteApi.fix_lot != null
? petiSqfliteApi!.fix_lot.toString()
: '-',
),
),
DataCell(
Text(
customerSqfliteApi != null && customerSqfliteApi.name != null
? customerSqfliteApi!.name.toString()
: '-',
),
),
DataCell(
Text(
item.date != null ? DateFormat('dd-MM-yyyy').format(item.date!) : '-',
),
),
DataCell(
Text(
warehouseAsalGudangSqfliteApi != null &&
warehouseAsalGudangSqfliteApi.name != null
? warehouseAsalGudangSqfliteApi!.name.toString()
: '-',
),
),
DataCell(
Text(
warehouseTujuanGudangSqfliteApi != null &&
warehouseTujuanGudangSqfliteApi.name != null
? warehouseTujuanGudangSqfliteApi!.name.toString()
: '-',
),
),
]);
}
@override
bool get isRowCountApproximate => false;
@override
int get rowCount => data.length;
@override
int get selectedRowCount => 0;
}

175
lib/pages/transfer_peti/show.dart

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

287
lib/pages/transfer_peti/transfer_peti_index.dart

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

4
lib/services/asset_status_service.dart

@ -12,7 +12,7 @@ import '../models/asset_status_model.dart';
class AssetStatusService {
Future<List<AssetStatusModel>> getAssetStatus() async {
// var url = Uri.parse('$baseUrl/products');
var url = Uri.parse("$baseUrl/asset-status");
var url = Uri.parse(await getBaseUrl() + "/asset-status");
var headers = {'Content-Type': 'application/json'};
var response = await http.get(url, headers: headers);
@ -43,7 +43,7 @@ class AssetStatusService {
// int? exit_warehouse,
String? token,
}) async {
var url = Uri.parse('$baseUrl/asset-status/store');
var url = Uri.parse(await getBaseUrl() + 'asset-status/store');
var headers = {
'Content-Type': 'application/json',
'Authorization': token!,

13
lib/services/auth_service.dart

@ -1,6 +1,5 @@
import 'dart:convert';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import '../connection/connection.dart';
@ -8,7 +7,7 @@ import '../models/user_model.dart';
class AuthService {
Future<UserModel?> getUserInfoFromServer(String token) async {
var url = Uri.parse('$baseUrl/user');
var url = Uri.parse(await getBaseUrl() + '/user');
var headers = {
'Content-Type': 'application/json',
'Authorization': token,
@ -30,7 +29,7 @@ class AuthService {
String? email,
String? password,
}) async {
var url = Uri.parse('$baseUrl/register');
var url = Uri.parse(await getBaseUrl() + '/register');
var headers = {'Content-Type': 'application/json'};
var body = jsonEncode({
'name': name,
@ -59,7 +58,7 @@ class AuthService {
String? email,
String? password,
}) async {
var url = Uri.parse('$baseUrl/login');
var url = Uri.parse(await getBaseUrl() + '/login');
var headers = {'Content-Type': 'application/json'};
var body = jsonEncode({
'email': email,
@ -85,7 +84,7 @@ class AuthService {
return user;
} else {
throw Exception('Gagal Login');
throw Exception('Failed to login');
}
}
@ -96,7 +95,7 @@ class AuthService {
FutureOr<bool> logout(String token) async {
try {
var url = Uri.parse('$baseUrl/logout');
var url = Uri.parse(await getBaseUrl() + '/logout');
var headers = {
'Content-Type': 'application/json',
'Authorization': token,
@ -130,7 +129,7 @@ class AuthService {
String? token,
}) async {
try {
var url = Uri.parse('$baseUrl/user');
var url = Uri.parse(await getBaseUrl() + '/user');
var headers = {
'Content-Type': 'application/json',
'Authorization': token!,

372
lib/services/controllerApi.dart

@ -0,0 +1,372 @@
import 'dart:async';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:siopas/models/asset_status_model.dart';
import 'package:siopas/models/customer_model.dart';
import 'package:siopas/models/disposal_model.dart';
import 'package:siopas/models/m_asset_status_model.dart';
import 'package:siopas/models/warehouse_mode.dart';
import 'package:http/http.dart' as http;
import 'package:internet_connection_checker/internet_connection_checker.dart';
import 'package:sqflite/sqflite.dart';
import '../migrations/databasehelper.dart';
import '../models/condition_peti_model.dart';
import '../models/type_peti_model.dart';
class ControllerApi {
final conn = SqfliteDatabaseHelper.instance;
static Future<bool> isInternetApi() async {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile) {
if (await InternetConnectionChecker().hasConnection) {
print("Mobile data detected & internet connection confirmed.");
return true;
} else {
print('No internet :( Reason:');
return false;
}
} else if (connectivityResult == ConnectivityResult.wifi) {
if (await InternetConnectionChecker().hasConnection) {
print("wifi data detected & internet connection confirmed.");
return true;
} else {
print('No internet :( Reason:');
return false;
}
} else {
print(
"Neither mobile data or WIFI detected, not internet connection found.");
return false;
}
}
// Asset Status ------------------------------------------------------------------------------------------------------------------
Future<List> fetchAssetStatusLocalControllerApi() async {
var dbclient = await conn.db;
List assetStatusApiList = [];
try {
// Ensure that the table name is correct
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.asset_statusesTable, orderBy: 'id DESC');
for (var item in maps) {
assetStatusApiList.add(item);
}
} catch (e) {
print('Error fetching data from SQLite: $e');
}
return assetStatusApiList;
}
Future<void> deleteAllAssetStatusDataAPI() async {
var dbClient = await conn.db;
await dbClient!.delete(SqfliteDatabaseHelper.asset_statusesTable);
}
Future<void> addAllAssetStatusDataAPI(
List<AssetStatusModel> assetStatusListApi) async {
var dbclient = await conn.db;
Batch batch = dbclient!.batch();
for (var assetStatus in assetStatusListApi) {
// Ensure that toJson() correctly converts the model to a map
batch.insert(
SqfliteDatabaseHelper.asset_statusesTable,
assetStatus.toJson(),
);
}
await batch.commit();
}
// End Asset Status ------------------------------------------------------------------------------------------------------------------
// Peti ------------------------------------------------------------------------------------------------------------------
Future<List> fetchPetiDataAPI() async {
var dbclient = await conn.db;
List petiApiList = [];
try {
// Ensure that the table name is correct
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.petiTable, orderBy: 'id DESC');
for (var item in maps) {
petiApiList.add(item);
}
} catch (e) {
print('Error fetching data from SQLite: $e');
}
return petiApiList;
}
Future<void> deleteAllPetiDataAPI() async {
var dbClient = await conn.db;
await dbClient!.delete(SqfliteDatabaseHelper.petiTable);
}
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();
}
// End Peti ------------------------------------------------------------------------------------------------------------------
// Warehouse ------------------------------------------------------------------------------------------------------------------
Future<List> fetchWarehouseDataAPI() async {
var dbclient = await conn.db;
List warehouseApiList = [];
try {
// Ensure that the table name is correct
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.warehouseTable, orderBy: 'id DESC');
for (var item in maps) {
warehouseApiList.add(item);
}
} catch (e) {
print('Error fetching data from SQLite: $e');
}
return warehouseApiList;
}
Future<void> deleteAllWarehouseDataAPI() async {
var dbClient = await conn.db;
await dbClient!.delete(SqfliteDatabaseHelper.warehouseTable);
}
Future<void> addAllWarehouseDataAPI(
List<WarehouseModel> warehouseListApi) async {
var dbclient = await conn.db;
Batch batch = dbclient!.batch();
for (var warehouse in warehouseListApi) {
// Ensure that toJson() correctly converts the model to a map
batch.insert(
SqfliteDatabaseHelper.warehouseTable,
warehouse.toJson(),
);
}
await batch.commit();
}
// End Warehouse ------------------------------------------------------------------------------------------------------------------
// Customer ------------------------------------------------------------------------------------------------------------------
Future<List> fetchCustomerDataAPI() async {
var dbclient = await conn.db;
List customerApiList = [];
try {
// Ensure that the table name is correct
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.customerTable, orderBy: 'id DESC');
for (var item in maps) {
customerApiList.add(item);
}
} catch (e) {
print('Error fetching data from SQLite: $e');
}
return customerApiList;
}
Future<void> deleteAllCustomerDataAPI() async {
var dbClient = await conn.db;
await dbClient!.delete(SqfliteDatabaseHelper.customerTable);
}
Future<void> addAllCustomerDataAPI(
List<CustomerModel> customerApiList) async {
var dbclient = await conn.db;
Batch batch = dbclient!.batch();
for (var customer in customerApiList) {
// Ensure that toJson() correctly converts the model to a map
batch.insert(
SqfliteDatabaseHelper.customerTable,
customer.toJson(),
);
}
await batch.commit();
}
// End Customer ------------------------------------------------------------------------------------------------------------------
// Tipe Peti ------------------------------------------------------------------------------------------------------------------
Future<List> fetchTipePetiDataAPI() async {
var dbclient = await conn.db;
List tipePetiApiList = [];
try {
// Ensure that the table name is correct
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.typePetiTable, orderBy: 'id DESC');
for (var item in maps) {
tipePetiApiList.add(item);
}
} catch (e) {
print('Error fetching data from SQLite: $e');
}
return tipePetiApiList;
}
Future<void> deleteAllTipePetiDataAPI() async {
var dbClient = await conn.db;
await dbClient!.delete(SqfliteDatabaseHelper.typePetiTable);
}
Future<void> addAllTipePetiDataAPI(
List<TypePetiModel> tipePetiApiList) async {
var dbclient = await conn.db;
Batch batch = dbclient!.batch();
for (var tipePeti in tipePetiApiList) {
// Ensure that toJson() correctly converts the model to a map
batch.insert(
SqfliteDatabaseHelper.typePetiTable,
tipePeti.toJson(),
);
}
await batch.commit();
}
// End Tipe Peti ------------------------------------------------------------------------------------------------------------------
// Tipe Kondisi ------------------------------------------------------------------------------------------------------------------
// Future<List> fetchKondisiPetiDataAPI() async {
// var dbclient = await conn.db;
// List kondisiPetiApiList = [];
// try {
// // Ensure that the table name is correct
// List<Map<String, dynamic>> maps = await dbclient!
// .query(SqfliteDatabaseHelper.conditionPetiTable, orderBy: 'id DESC');
// for (var item in maps) {
// kondisiPetiApiList.add(item);
// }
// } catch (e) {
// print('Error fetching data from SQLite: $e');
// }
// return kondisiPetiApiList;
// }
Future<List> fetchKondisiPetiDataAPI() async {
var dbclient = await conn.db;
List conditionApiList = [];
try {
// Ensure that the table name is correct
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.conditionPetiTable, orderBy: 'id DESC');
for (var item in maps) {
conditionApiList.add(item);
}
} catch (e) {
print('Error fetching data from SQLite: $e');
}
return conditionApiList;
}
Future<void> deleteAllKondisiPetiDataAPI() async {
var dbClient = await conn.db;
await dbClient!.delete(SqfliteDatabaseHelper.conditionPetiTable);
}
Future<void> addAllKondisiPetiDataAPI(
List<ConditionPetiModel> kondisiPetiApiList) async {
var dbclient = await conn.db;
Batch batch = dbclient!.batch();
for (var kondisiPeti in kondisiPetiApiList) {
// Ensure that toJson() correctly converts the model to a map
batch.insert(
SqfliteDatabaseHelper.conditionPetiTable,
kondisiPeti.toJson(),
);
}
await batch.commit();
}
// End Kondisi Peti ------------------------------------------------------------------------------------------------------------------
// Transfer Kondisi ------------------------------------------------------------------------------------------------------------------
Future<List> fetchTransferPetiDataAPI() async {
var dbclient = await conn.db;
List transferPetiApiList = [];
try {
// Ensure that the table name is correct
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.transferPetiTable, orderBy: 'id DESC');
for (var item in maps) {
transferPetiApiList.add(item);
}
} catch (e) {
print('Error fetching data from SQLite: $e');
}
return transferPetiApiList;
}
Future<void> deleteAllTransferPetiDataAPI() async {
var dbClient = await conn.db;
await dbClient!.delete(SqfliteDatabaseHelper.transferPetiTable);
}
Future<void> addAllTransferPetiDataAPI(
List<ConditionPetiModel> transferPetiApiList) async {
var dbclient = await conn.db;
Batch batch = dbclient!.batch();
for (var transferPeti in transferPetiApiList) {
// Ensure that toJson() correctly converts the model to a map
batch.insert(
SqfliteDatabaseHelper.transferPetiTable,
transferPeti.toJson(),
);
}
await batch.commit();
}
// End Transfer Peti ------------------------------------------------------------------------------------------------------------------
// Disposal ------------------------------------------------------------------------------------------------------------------
Future<List> fetchDisposalDataAPI() async {
var dbclient = await conn.db;
List disposalApiList = [];
try {
// Ensure that the table name is correct
List<Map<String, dynamic>> maps = await dbclient!
.query(SqfliteDatabaseHelper.disposalTable, orderBy: 'id DESC');
for (var item in maps) {
disposalApiList.add(item);
}
} catch (e) {
print('Error fetching data from SQLite: $e');
}
return disposalApiList;
}
Future<void> deleteAllDisposalDataAPI() async {
var dbClient = await conn.db;
await dbClient!.delete(SqfliteDatabaseHelper.disposalTable);
}
Future<void> addAllDisposalDataAPI(
List<DisposalPetiModel> disposalApiList) async {
var dbclient = await conn.db;
Batch batch = dbclient!.batch();
for (var disposal in disposalApiList) {
// Ensure that toJson() correctly converts the model to a map
batch.insert(
SqfliteDatabaseHelper.disposalTable,
disposal.toJson(),
);
}
await batch.commit();
}
// End Disposal ------------------------------------------------------------------------------------------------------------------
}

2
lib/services/m_status_service.dart

@ -8,7 +8,7 @@ import 'dart:async';
class M_assetStatusService {
Future<List<PetiAssetModel>> getAssetStatus() async {
var url = Uri.parse("$baseUrl/m-status");
var url = Uri.parse("${await getBaseUrl()}/m-status");
var headers = {'Content-Type': 'application/json'};
var response = await http.get(url, headers: headers);

224
lib/services/syncronizeAPI.dart

@ -0,0 +1,224 @@
import 'dart:convert';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:siopas/connection/connection.dart';
import 'package:siopas/models/asset_status_model.dart';
import 'package:siopas/models/condition_peti_model.dart';
import 'package:siopas/models/customer_model.dart';
import 'package:siopas/models/transfer_peti_model.dart';
import 'package:siopas/models/type_peti_model.dart';
import 'package:siopas/models/warehouse_mode.dart';
import 'package:internet_connection_checker/internet_connection_checker.dart';
import '../migrations/databasehelper.dart';
import 'package:http/http.dart' as http;
import '../models/disposal_model.dart';
import '../models/m_asset_status_model.dart';
class SyncronizationDataAPI {
final conn = SqfliteDatabaseHelper.instance;
Future<List<AssetStatusModel>> fetchAssetStatusFromApi() async {
final apiURL = '${await getBaseUrl()}/asset-status';
final response = await http.get(Uri.parse(apiURL));
if (response.statusCode == 200) {
List<dynamic> data = json.decode(response.body)['data']['asset_status'];
print('Success Fetch Data API Asset Status');
List<AssetStatusModel> assetStatusApiList = data
.map(
(item) => AssetStatusModel.fromJson(item as Map<String, dynamic>))
.toList();
return assetStatusApiList;
} else {
throw Exception('Failed to fetch data from API Peti');
}
}
Future<List<PetiAssetModel>> fetchPetiFromApi() async {
final apiURL = '${await getBaseUrl()}/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> petiDBList = data
.map((item) => PetiAssetModel.fromJson(item as Map<String, dynamic>))
.toList();
return petiDBList;
} else {
throw Exception('Failed to fetch data from API Peti');
}
}
// 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';
final response = await http.get(Uri.parse(apiURL));
if (response.statusCode == 200) {
List<dynamic> data = json.decode(response.body)['data']['warehouse'];
print('Success Fetch Data Warehouse');
List<WarehouseModel> warehouseDBList = data
.map((item) => WarehouseModel.fromJson(item as Map<String, dynamic>))
.toList();
return warehouseDBList;
} else {
throw Exception('Failed to fetch data from API Warehouse');
}
}
Future<List<CustomerModel>> fetchCustomerFromApi() async {
final apiURL = '${await getBaseUrl()}/m-customer';
final response = await http.get(Uri.parse(apiURL));
if (response.statusCode == 200) {
List<dynamic> data = json.decode(response.body)['data']['customers'];
print('Success Fetch Data Customer');
List<CustomerModel> customerDBList = data
.map((item) => CustomerModel.fromJson(item as Map<String, dynamic>))
.toList();
return customerDBList;
} else {
throw Exception('Failed to fetch data from API Customer');
}
}
Future<List<TypePetiModel>> fetchTipePetiFromApi() async {
final apiURL = '${await getBaseUrl()}/m-type-peti';
final response = await http.get(Uri.parse(apiURL));
if (response.statusCode == 200) {
List<dynamic> data = json.decode(response.body)['data']['tipe_peti'];
print('Success Fetch Data Tipe Peti');
List<TypePetiModel> tipePetiDBList = data
.map((item) => TypePetiModel.fromJson(item as Map<String, dynamic>))
.toList();
return tipePetiDBList;
} else {
throw Exception('Failed to fetch data from API Tipe Peti');
}
}
Future<List<ConditionPetiModel>> fetchKondisiPetiFromApi() async {
final apiURL = '${await getBaseUrl()}/m-kondisi-peti';
final response = await http.get(Uri.parse(apiURL));
if (response.statusCode == 200) {
List<dynamic> data = json.decode(response.body)['data']['kondisi_peti'];
print('Success Fetch Data Master Kondisi Peti');
List<ConditionPetiModel> kondisiPetiDBList = data
.map((item) =>
ConditionPetiModel.fromJson(item as Map<String, dynamic>))
.toList();
return kondisiPetiDBList;
} else {
throw Exception('Failed to fetch data from API Master Kondisi Peti');
}
}
Future<List<TransferPetiModel>> fetchTransferPetiFromApi() async {
final apiURL = '${await getBaseUrl()}/m-transfer-peti';
final response = await http.get(Uri.parse(apiURL));
if (response.statusCode == 200) {
List<dynamic> data = json.decode(response.body)['data']['transfer_peti'];
print('Success Fetch Data Transfer Peti');
List<TransferPetiModel> transferPetiDBList = data
.map((item) =>
TransferPetiModel.fromJson(item as Map<String, dynamic>))
.toList();
return transferPetiDBList;
} else {
throw Exception('Failed to fetch data from API Transfer Peti');
}
}
Future<List<DisposalPetiModel>> fetchDisposalFromApi() async {
final apiURL = '${await getBaseUrl()}/m-disposal-peti';
final response = await http.get(Uri.parse(apiURL));
if (response.statusCode == 200) {
List<dynamic> data = json.decode(response.body)['data']['disposals'];
print('Success Fetch Data Disposal Peti');
List<DisposalPetiModel> disposalPetiDBList = data
.map((item) =>
DisposalPetiModel.fromJson(item as Map<String, dynamic>))
.toList();
return disposalPetiDBList;
} else {
throw Exception('Failed to fetch data from API Disposal Peti');
}
}
}

2
macos/Flutter/GeneratedPluginRegistrant.swift

@ -5,11 +5,13 @@
import FlutterMacOS
import Foundation
import connectivity_plus
import path_provider_foundation
import shared_preferences_foundation
import sqflite
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))

164
pubspec.lock

@ -1,6 +1,22 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
archive:
dependency: transitive
description:
name: archive
sha256: "7b875fd4a20b165a3084bd2d210439b22ebc653f21cea4842729c0c30c82596b"
url: "https://pub.dev"
source: hosted
version: "3.4.9"
args:
dependency: transitive
description:
name: args
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
url: "https://pub.dev"
source: hosted
version: "2.4.2"
async:
dependency: transitive
description:
@ -49,6 +65,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.0"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
url: "https://pub.dev"
source: hosted
version: "2.0.3"
cli_util:
dependency: transitive
description:
name: cli_util
sha256: b8db3080e59b2503ca9e7922c3df2072cf13992354d5e944074ffa836fba43b7
url: "https://pub.dev"
source: hosted
version: "0.4.0"
clock:
dependency: transitive
description:
@ -65,6 +97,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.17.2"
connectivity_plus:
dependency: "direct main"
description:
name: connectivity_plus
sha256: "224a77051d52a11fbad53dd57827594d3bd24f945af28bd70bab376d68d437f0"
url: "https://pub.dev"
source: hosted
version: "5.0.2"
connectivity_plus_platform_interface:
dependency: transitive
description:
name: connectivity_plus_platform_interface
sha256: cf1d1c28f4416f8c654d7dc3cd638ec586076255d407cef3ddbdaf178272a71a
url: "https://pub.dev"
source: hosted
version: "1.2.4"
convert:
dependency: transitive
description:
name: convert
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
url: "https://pub.dev"
source: hosted
version: "3.1.1"
crypto:
dependency: transitive
description:
@ -89,6 +145,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.5.8"
dbus:
dependency: transitive
description:
name: dbus
sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac"
url: "https://pub.dev"
source: hosted
version: "0.7.10"
fake_async:
dependency: transitive
description:
@ -126,6 +190,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.3.1"
flutter_easyloading:
dependency: "direct main"
description:
name: flutter_easyloading
sha256: ba21a3c883544e582f9cc455a4a0907556714e1e9cf0eababfcb600da191d17c
url: "https://pub.dev"
source: hosted
version: "3.0.5"
flutter_form_builder:
dependency: "direct main"
description:
@ -134,14 +206,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "9.1.1"
flutter_lints:
dependency: "direct dev"
flutter_launcher_icons:
dependency: "direct main"
description:
name: flutter_lints
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
name: flutter_launcher_icons
sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea"
url: "https://pub.dev"
source: hosted
version: "2.0.3"
version: "0.13.1"
flutter_spinkit:
dependency: transitive
description:
name: flutter_spinkit
sha256: b39c753e909d4796906c5696a14daf33639a76e017136c8d82bf3e620ce5bb8e
url: "https://pub.dev"
source: hosted
version: "5.2.0"
flutter_test:
dependency: "direct dev"
description: flutter
@ -176,6 +256,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.0.2"
image:
dependency: transitive
description:
name: image
sha256: "028f61960d56f26414eb616b48b04eb37d700cbe477b7fb09bf1d7ce57fd9271"
url: "https://pub.dev"
source: hosted
version: "4.1.3"
internet_connection_checker:
dependency: "direct main"
description:
name: internet_connection_checker
sha256: "1c683e63e89c9ac66a40748b1b20889fd9804980da732bf2b58d6d5456c8e876"
url: "https://pub.dev"
source: hosted
version: "1.0.0+1"
intl:
dependency: "direct main"
description:
@ -192,14 +288,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.6.7"
lints:
json_annotation:
dependency: transitive
description:
name: lints
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
name: json_annotation
sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "4.8.1"
matcher:
dependency: transitive
description:
@ -232,6 +328,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.0"
nm:
dependency: transitive
description:
name: nm
sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254"
url: "https://pub.dev"
source: hosted
version: "0.5.0"
octo_image:
dependency: transitive
description:
@ -249,7 +353,7 @@ packages:
source: hosted
version: "1.8.3"
path_provider:
dependency: transitive
dependency: "direct main"
description:
name: path_provider
sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
@ -296,6 +400,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.2.1"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750
url: "https://pub.dev"
source: hosted
version: "5.4.0"
platform:
dependency: transitive
description:
@ -312,6 +424,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.6"
pointycastle:
dependency: transitive
description:
name: pointycastle
sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c"
url: "https://pub.dev"
source: hosted
version: "3.7.3"
provider:
dependency: "direct main"
description:
@ -430,7 +550,7 @@ packages:
source: hosted
version: "7.0.0"
sqflite:
dependency: transitive
dependency: "direct main"
description:
name: sqflite
sha256: "591f1602816e9c31377d5f008c2d9ef7b8aca8941c3f89cc5fd9d84da0c38a9a"
@ -502,13 +622,13 @@ packages:
source: hosted
version: "1.3.2"
uuid:
dependency: transitive
dependency: "direct main"
description:
name: uuid
sha256: b715b8d3858b6fa9f68f87d20d98830283628014750c2b09b6f516c1da4af2a7
sha256: df5a4d8f22ee4ccd77f8839ac7cb274ebc11ef9adcce8b92be14b797fe889921
url: "https://pub.dev"
source: hosted
version: "4.1.0"
version: "4.2.1"
vector_math:
dependency: transitive
description:
@ -541,6 +661,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.3"
xml:
dependency: transitive
description:
name: xml
sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84"
url: "https://pub.dev"
source: hosted
version: "6.3.0"
yaml:
dependency: transitive
description:
name: yaml
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
url: "https://pub.dev"
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.1.3 <4.0.0"
flutter: ">=3.10.0"

18
pubspec.yaml

@ -1,5 +1,5 @@
name: siopas
description: A new Flutter project.
description: Apps Siopas ISTW.
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
@ -45,13 +45,27 @@ dependencies:
qr_code_scanner: ^1.0.1
data_table_2: ^2.5.8
flutter_form_builder: ^9.1.1
# dropdown_button2: ^2.3.9
uuid: ^4.2.1
path_provider: ^2.1.1
connectivity_plus: ^5.0.1
internet_connection_checker: ^1.0.0+1
flutter_easyloading: ^3.0.5
sqflite: ^2.3.0
flutter_launcher_icons: ^0.13.1
dev_dependencies:
flutter_test:
sdk: flutter
flutter_launcher_icons:
android: true
ios: true
image_path: "assets/img/siopas_apps.png"
adaptive_icon_background: "#ffffff"
adaptive_icon_foreground: "assets/img/siopas_apps.png"
adaptive_icon_mask: "assets/img/siopas_apps.png"
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your

3
windows/flutter/generated_plugin_registrant.cc

@ -6,6 +6,9 @@
#include "generated_plugin_registrant.h"
#include <connectivity_plus/connectivity_plus_windows_plugin.h>
void RegisterPlugins(flutter::PluginRegistry* registry) {
ConnectivityPlusWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
}

1
windows/flutter/generated_plugins.cmake

@ -3,6 +3,7 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
connectivity_plus
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST

Loading…
Cancel
Save