inventory_mobile/lib/services/item_movement_service.dart
2025-12-15 15:35:35 +08:00

287 lines
9.5 KiB
Dart

import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:inventory_system/services/api_service.dart';
import 'package:inventory_system/services/session_manager.dart';
import 'package:inventory_system/services/user_service.dart';
class ItemMovementService {
Future<List<dynamic>> fetchItemMovements() async {
final currentUser = SessionManager.instance.currentUser;
if (currentUser == null) {
throw Exception('User session not found.');
}
final userId = currentUser['id'];
final currentUserRoles = currentUser['role'] as List<dynamic>? ?? [];
final currentUserStore = currentUser['store']; // Get current user's store
final currentUserDepartmentId = currentUser['department']?['departmentId'];
List<dynamic> itemMovements = [];
String apiUrl = '';
HttpMethod method = HttpMethod.GET; // Default to GET, will be POST
try {
if (currentUserRoles.contains("Super Admin")) {
// Super Admins see all item movements
apiUrl = '${ApiService.baseUrl}/InvMainAPI/ItemMovementList';
method = HttpMethod.POST;
} else if (currentUserRoles.contains("Inventory Master")) {
// Inventory Masters: fetch all movements, client-side filtering in UI based on currentUserStore
apiUrl = '${ApiService.baseUrl}/InvMainAPI/ItemMovementList';
method = HttpMethod.POST;
} else {
// Standard users: fetch only their item movements using specific API
apiUrl = '${ApiService.baseUrl}/InvMainAPI/ItemMovementUser';
method = HttpMethod.POST;
}
final uri = Uri.parse(apiUrl);
final cookie = SessionManager.instance.getCookie();
debugPrint("Fetching item movements from: $uri");
final Map<String, String> headers = {
'Content-Type': 'application/json; charset=UTF-8',
if (cookie != null) 'Cookie': cookie,
};
http.Response response;
if (method == HttpMethod.POST) {
// For ItemMovementUser, need to send userId in body
if (apiUrl == '${ApiService.baseUrl}/InvMainAPI/ItemMovementUser') {
response = await http.post(
uri,
headers: headers,
body: jsonEncode({'userId': userId}),
);
} else {
response = await http.post(uri, headers: headers);
}
} else {
response = await http.get(uri, headers: headers);
}
debugPrint('API Response Status: ${response.statusCode}');
// debugPrint('API Response Body: ${response.body}');
if (response.statusCode == 200) {
itemMovements = response.body.isNotEmpty ? jsonDecode(response.body) : [];
} else {
throw Exception('Failed to load item movements. Status: ${response.statusCode}, Body: ${response.body}');
}
} on SocketException {
throw Exception('No Internet connection.');
} catch (e) {
debugPrint('Error fetching item movements: $e');
rethrow;
}
// Perform client-side filtering for Inventory Master
if (currentUserRoles.contains("Inventory Master")) {
// Filter by Store
if (currentUserStore != null) {
itemMovements = itemMovements
.where((m) {
final toStore = m['toStore'] as int?;
final lastStore = m['lastStore'] as int?;
return (toStore != null && toStore == currentUserStore) ||
(lastStore != null && lastStore == currentUserStore);
})
.toList();
}
// Filter by Department
if (currentUserDepartmentId != null) {
try {
final userService = UserService();
final allUsers = await userService.fetchUsers();
final userDeptMap = {
for (var u in allUsers)
if (u['id'] != null && u['department'] != null)
u['id']: u['department']['departmentId']
};
itemMovements = itemMovements.where((m) {
final fromUser = m['lastUser'];
final toUser = m['toUser'];
final fromUserDept = userDeptMap[fromUser];
final toUserDept = userDeptMap[toUser];
return (fromUserDept == currentUserDepartmentId) || (toUserDept == currentUserDepartmentId);
}).toList();
} catch (e) {
debugPrint("Error filtering by department: $e");
// Optionally handle error, e.g., strictly return empty or allow all if fetch fails
}
}
}
return itemMovements;
}
Future<void> addItemMovement(Map<String, dynamic> data) async {
final uri = Uri.parse('${ApiService.baseUrl}/InvMainAPI/AddItemMovement');
final cookie = SessionManager.instance.getCookie();
final Map<String, String> headers = {
'Content-Type': 'application/json; charset=UTF-8',
if (cookie != null) 'Cookie': cookie,
};
try {
final response = await http.post(
uri,
headers: headers,
body: jsonEncode(data),
);
if (response.statusCode != 200) {
throw Exception('Failed to add item movement. Status: ${response.statusCode}, Body: ${response.body}');
}
} on SocketException {
throw Exception('No Internet connection.');
} catch (e) {
debugPrint('Error adding item movement: $e');
rethrow;
}
}
Future<void> updateItemMovementMaster(Map<String, dynamic> data) async {
final uri = Uri.parse('${ApiService.baseUrl}/InvMainAPI/UpdateItemMovementMaster');
final cookie = SessionManager.instance.getCookie();
final Map<String, String> headers = {
'Content-Type': 'application/json; charset=UTF-8',
if (cookie != null) 'Cookie': cookie,
};
try {
final response = await http.post(
uri,
headers: headers,
body: jsonEncode(data),
);
if (response.statusCode != 200) {
throw Exception('Failed to update item movement master. Status: ${response.statusCode}, Body: ${response.body}');
}
} on SocketException {
throw Exception('No Internet connection.');
} catch (e) {
debugPrint('Error updating item movement master: $e');
rethrow;
}
}
Future<void> updateItemMovementUser(Map<String, dynamic> data) async {
final uri = Uri.parse('${ApiService.baseUrl}/InvMainAPI/UpdateItemMovementUser');
final cookie = SessionManager.instance.getCookie();
final Map<String, String> headers = {
'Content-Type': 'application/json; charset=UTF-8',
if (cookie != null) 'Cookie': cookie,
};
try {
final response = await http.post(
uri,
headers: headers,
body: jsonEncode(data),
);
if (response.statusCode != 200) {
throw Exception('Failed to update item movement user. Status: ${response.statusCode}, Body: ${response.body}');
}
} on SocketException {
throw Exception('No Internet connection.');
} catch (e) {
debugPrint('Error updating item movement user: $e');
rethrow;
}
}
Future<void> returnItemMovementUser(Map<String, dynamic> data) async {
final uri = Uri.parse('${ApiService.baseUrl}/InvMainAPI/ReturnItemMovementUser');
final cookie = SessionManager.instance.getCookie();
final Map<String, String> headers = {
'Content-Type': 'application/json; charset=UTF-8',
if (cookie != null) 'Cookie': cookie,
};
try {
final response = await http.post(
uri,
headers: headers,
body: jsonEncode(data),
);
if (response.statusCode != 200) {
throw Exception('Failed to return item movement user. Status: ${response.statusCode}, Body: ${response.body}');
}
} on SocketException {
throw Exception('No Internet connection.');
} catch (e) {
debugPrint('Error returning item movement user: $e');
rethrow;
}
}
Future<void> stationItemMovementUser(Map<String, dynamic> data) async {
final uri = Uri.parse('${ApiService.baseUrl}/InvMainAPI/StationItemMovementUser');
final cookie = SessionManager.instance.getCookie();
final Map<String, String> headers = {
'Content-Type': 'application/json; charset=UTF-8',
if (cookie != null) 'Cookie': cookie,
};
try {
final response = await http.post(
uri,
headers: headers,
body: jsonEncode(data),
);
if (response.statusCode != 200) {
throw Exception('Failed to assign item movement to station. Status: ${response.statusCode}, Body: ${response.body}');
}
} on SocketException {
throw Exception('No Internet connection.');
} catch (e) {
debugPrint('Error assigning item movement to station: $e');
rethrow;
}
}
Future<Map<String, dynamic>> getItemMovementById(int id) async {
final uri = Uri.parse('${ApiService.baseUrl}/InvMainAPI/GetItemMovementById?id=$id');
final cookie = SessionManager.instance.getCookie();
final Map<String, String> headers = {
'Content-Type': 'application/json; charset=UTF-8',
if (cookie != null) 'Cookie': cookie,
};
try {
final response = await http.get(uri, headers: headers); // Assuming GET for retrieval by ID
if (response.statusCode == 200) {
return response.body.isNotEmpty ? jsonDecode(response.body) : {};
} else {
throw Exception('Failed to get item movement. Status: ${response.statusCode}, Body: ${response.body}');
}
} on SocketException {
throw Exception('No Internet connection.');
} catch (e) {
debugPrint('Error getting item movement: $e');
rethrow;
}
}
}
enum HttpMethod { GET, POST } // Define HttpMethod enum