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> 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? ?? []; final currentUserStore = currentUser['store']; // Get current user's store final currentUserDepartmentId = currentUser['department']?['departmentId']; List 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 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 addItemMovement(Map data) async { final uri = Uri.parse('${ApiService.baseUrl}/InvMainAPI/AddItemMovement'); final cookie = SessionManager.instance.getCookie(); final Map 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 updateItemMovementMaster(Map data) async { final uri = Uri.parse('${ApiService.baseUrl}/InvMainAPI/UpdateItemMovementMaster'); final cookie = SessionManager.instance.getCookie(); final Map 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 updateItemMovementUser(Map data) async { final uri = Uri.parse('${ApiService.baseUrl}/InvMainAPI/UpdateItemMovementUser'); final cookie = SessionManager.instance.getCookie(); final Map 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 returnItemMovementUser(Map data) async { final uri = Uri.parse('${ApiService.baseUrl}/InvMainAPI/ReturnItemMovementUser'); final cookie = SessionManager.instance.getCookie(); final Map 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 stationItemMovementUser(Map data) async { final uri = Uri.parse('${ApiService.baseUrl}/InvMainAPI/StationItemMovementUser'); final cookie = SessionManager.instance.getCookie(); final Map 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> getItemMovementById(int id) async { final uri = Uri.parse('${ApiService.baseUrl}/InvMainAPI/GetItemMovementById?id=$id'); final cookie = SessionManager.instance.getCookie(); final Map 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