diff --git a/lib/controller/project_controller.dart b/lib/controller/project_controller.dart index 7baf879..b30bcdb 100644 --- a/lib/controller/project_controller.dart +++ b/lib/controller/project_controller.dart @@ -1,13 +1,13 @@ import 'package:get/get.dart'; import 'package:logger/logger.dart'; import 'package:marco/helpers/services/api_service.dart'; -import 'package:marco/model/project_model.dart'; +import 'package:marco/model/global_project_model.dart'; import 'package:marco/helpers/services/storage/local_storage.dart'; final Logger log = Logger(); class ProjectController extends GetxController { - RxList projects = [].obs; + RxList projects = [].obs; RxString? selectedProjectId; RxBool isProjectListExpanded = false.obs; RxBool isProjectSelectionExpanded = false.obs; @@ -16,7 +16,7 @@ class ProjectController extends GetxController { RxBool isLoading = true.obs; RxBool isLoadingProjects = true.obs; RxMap uploadingStates = {}.obs; - ProjectModel? get selectedProject { + GlobalProjectModel? get selectedProject { if (selectedProjectId == null || selectedProjectId!.value.isEmpty) return null; return projects.firstWhereOrNull((p) => p.id == selectedProjectId!.value); @@ -50,7 +50,7 @@ class ProjectController extends GetxController { if (response != null && response.isNotEmpty) { projects.assignAll( - response.map((json) => ProjectModel.fromJson(json)).toList()); + response.map((json) => GlobalProjectModel.fromJson(json)).toList()); String? savedId = LocalStorage.getString('selectedProjectId'); if (savedId != null && projects.any((p) => p.id == savedId)) { diff --git a/lib/helpers/services/api_service.dart b/lib/helpers/services/api_service.dart index 7e43290..bf3903e 100644 --- a/lib/helpers/services/api_service.dart +++ b/lib/helpers/services/api_service.dart @@ -46,21 +46,29 @@ class ApiService { return null; } - static dynamic _parseResponseForAllData(http.Response response, - {String label = ''}) { - _log("$label Response: ${response.body}"); - try { - final json = jsonDecode(response.body); - if (response.statusCode == 200 && json['success'] == true) { - return json; - } - _log("API Error [$label]: ${json['message'] ?? 'Unknown error'}"); - } catch (e) { - _log("Response parsing error [$label]: $e"); +static dynamic _parseResponseForAllData(http.Response response, + {String label = ''}) { + _log("$label Response: ${response.body}"); + + try { + final body = response.body.trim(); + if (body.isEmpty) throw FormatException("Empty response body"); + + final json = jsonDecode(body); + + if (response.statusCode == 200 && json['success'] == true) { + return json; } - return null; + + _log("API Error [$label]: ${json['message'] ?? 'Unknown error'}"); + } catch (e) { + _log("Response parsing error [$label]: $e"); } + return null; +} + + static Future _getRequest( String endpoint, { Map? queryParams, @@ -144,7 +152,7 @@ class ApiService { (res) => res != null ? _parseResponse(res, label: 'Projects') : null); static Future?> getGlobalProjects() async => - _getRequest(ApiEndpoints.getProjects).then((res) => + _getRequest(ApiEndpoints.getGlobalProjects).then((res) => res != null ? _parseResponse(res, label: 'Global Projects') : null); static Future?> getEmployeesByProject(String projectId) async => @@ -403,10 +411,19 @@ class ApiService { return false; } - static Future?> getWorkStatus() async => - _getRequest(ApiEndpoints.getWorkStatus).then((res) => res != null - ? _parseResponseForAllData(res, label: 'Work Status') - : null); + static Future?> getWorkStatus() async { + final res = await _getRequest(ApiEndpoints.getWorkStatus); + if (res == null) { + _log('Work Status API returned null'); + return null; + } + + _log('Work Status raw response: ${res.body}'); + + return _parseResponseForAllData(res, label: 'Work Status') + as Map?; + } + static Future?> getMasterWorkCategories() async => _getRequest(ApiEndpoints.getmasterWorkCategories).then((res) => res != null diff --git a/lib/model/attendance_model.dart b/lib/model/attendance_model.dart index 0d6f6a1..9a4ef92 100644 --- a/lib/model/attendance_model.dart +++ b/lib/model/attendance_model.dart @@ -6,8 +6,8 @@ class AttendanceModel { final DateTime startDate; final DateTime endDate; final int teamSize; - final int completedWork; - final int plannedWork; + final double completedWork; + final double plannedWork; AttendanceModel({ required this.id, @@ -30,8 +30,8 @@ class AttendanceModel { startDate: DateTime.tryParse(json['startDate']?.toString() ?? '') ?? DateTime.now(), endDate: DateTime.tryParse(json['endDate']?.toString() ?? '') ?? DateTime.now(), teamSize: int.tryParse(json['teamSize']?.toString() ?? '') ?? 0, - completedWork: int.tryParse(json['completedWork']?.toString() ?? '') ?? 0, - plannedWork: int.tryParse(json['plannedWork']?.toString() ?? '') ?? 0, + completedWork: double.tryParse(json['completedWork']?.toString() ?? '') ?? 0, + plannedWork: double.tryParse(json['plannedWork']?.toString() ?? '') ?? 0, ); } diff --git a/lib/model/dailyTaskPlaning/daily_task_planing_model.dart b/lib/model/dailyTaskPlaning/daily_task_planing_model.dart index da2085b..f1e5e64 100644 --- a/lib/model/dailyTaskPlaning/daily_task_planing_model.dart +++ b/lib/model/dailyTaskPlaning/daily_task_planing_model.dart @@ -127,8 +127,8 @@ class WorkItem { final WorkAreaBasic? workArea; final ActivityMaster? activityMaster; final WorkCategoryMaster? workCategoryMaster; - final int? plannedWork; - final int? completedWork; + final double? plannedWork; + final double? completedWork; final DateTime? taskDate; final String? tenantId; final Tenant? tenant; @@ -165,8 +165,12 @@ class WorkItem { ? WorkCategoryMaster.fromJson( json['workCategoryMaster'] as Map) : null, - plannedWork: json['plannedWork'] as int?, - completedWork: json['completedWork'] as int?, + plannedWork: json['plannedWork'] != null + ? (json['plannedWork'] as num).toDouble() + : null, + completedWork: json['completedWork'] != null + ? (json['completedWork'] as num).toDouble() + : null, taskDate: json['taskDate'] != null ? DateTime.tryParse(json['taskDate']) : null, tenantId: json['tenantId'] as String?, diff --git a/lib/model/dailyTaskPlaning/task_action_buttons.dart b/lib/model/dailyTaskPlaning/task_action_buttons.dart index 4b0127a..fd2a5fe 100644 --- a/lib/model/dailyTaskPlaning/task_action_buttons.dart +++ b/lib/model/dailyTaskPlaning/task_action_buttons.dart @@ -82,8 +82,8 @@ class TaskActionButtons { textStyle: const TextStyle(fontSize: 14), ), onPressed: () { - final taskData = - _prepareTaskData(task: task, completed: task.completedTask); + final taskData = _prepareTaskData(task: task, completed: task.completedTask.toInt()); + showModalBottomSheet( context: context, isScrollControlled: true, diff --git a/lib/model/daily_task_model.dart b/lib/model/daily_task_model.dart index 51475fb..4c93b88 100644 --- a/lib/model/daily_task_model.dart +++ b/lib/model/daily_task_model.dart @@ -4,8 +4,8 @@ class TaskModel { final String id; final WorkItem? workItem; final String workItemId; - final int plannedTask; - final int completedTask; + final double plannedTask; + final double completedTask; final AssignedBy assignedBy; final AssignedBy? approvedBy; final List teamMembers; @@ -37,8 +37,8 @@ class TaskModel { workItem: json['workItem'] != null ? WorkItem.fromJson(json['workItem']) : null, workItemId: json['workItemId'], - plannedTask: json['plannedTask'], - completedTask: json['completedTask'], + plannedTask: (json['plannedTask'] as num).toDouble(), + completedTask: (json['completedTask'] as num).toDouble(), assignedBy: AssignedBy.fromJson(json['assignedBy']), approvedBy: json['approvedBy'] != null ? AssignedBy.fromJson(json['approvedBy']) @@ -60,8 +60,8 @@ class WorkItem { final String? id; final ActivityMaster? activityMaster; final WorkArea? workArea; - final int? plannedWork; - final int? completedWork; + final double? plannedWork; + final double? completedWork; final List preSignedUrls; WorkItem({ @@ -81,8 +81,8 @@ class WorkItem { : null, workArea: json['workArea'] != null ? WorkArea.fromJson(json['workArea']) : null, - plannedWork: json['plannedWork'], - completedWork: json['completedWork'], + plannedWork: (json['plannedWork'] as num?)?.toDouble(), + completedWork: (json['completedWork'] as num?)?.toDouble(), preSignedUrls: (json['preSignedUrls'] as List?) ?.map((e) => e.toString()) .toList() ?? diff --git a/lib/model/global_project_model.dart b/lib/model/global_project_model.dart new file mode 100644 index 0000000..5d1c6b5 --- /dev/null +++ b/lib/model/global_project_model.dart @@ -0,0 +1,51 @@ +class GlobalProjectModel { +final String id; +final String name; +final String projectAddress; +final String contactPerson; +final DateTime startDate; +final DateTime endDate; +final int teamSize; +final String projectStatusId; +final String? tenantId; + +GlobalProjectModel({ +required this.id, +required this.name, +required this.projectAddress, +required this.contactPerson, +required this.startDate, +required this.endDate, +required this.teamSize, +required this.projectStatusId, +this.tenantId, +}); + +factory GlobalProjectModel.fromJson(Map json) { +return GlobalProjectModel( +id: json['id'] ?? '', +name: json['name'] ?? '', +projectAddress: json['projectAddress'] ?? '', +contactPerson: json['contactPerson'] ?? '', +startDate: DateTime.parse(json['startDate']), +endDate: DateTime.parse(json['endDate']), +teamSize: json['teamSize'] ?? 0, // ✅ SAFER +projectStatusId: json['projectStatusId'] ?? '', +tenantId: json['tenantId'], +); +} + +Map toJson() { +return { +'id': id, +'name': name, +'projectAddress': projectAddress, +'contactPerson': contactPerson, +'startDate': startDate.toIso8601String(), +'endDate': endDate.toIso8601String(), +'teamSize': teamSize, +'projectStatusId': projectStatusId, +'tenantId': tenantId, +}; +} +} \ No newline at end of file diff --git a/lib/model/project_model.dart b/lib/model/project_model.dart index 066e2ac..9498cf4 100644 --- a/lib/model/project_model.dart +++ b/lib/model/project_model.dart @@ -6,10 +6,10 @@ class ProjectModel { final DateTime startDate; final DateTime endDate; final int teamSize; - final int completedWork; - final int plannedWork; + final double completedWork; + final double plannedWork; final String projectStatusId; - final String? tenantId; + final String? tenantId; ProjectModel({ required this.id, @@ -35,10 +35,14 @@ class ProjectModel { startDate: DateTime.parse(json['startDate']), endDate: DateTime.parse(json['endDate']), teamSize: json['teamSize'], - completedWork: json['completedWork'], - plannedWork: json['plannedWork'], + completedWork: json['completedWork'] != null + ? (json['completedWork'] as num).toDouble() + : 0.0, + plannedWork: json['plannedWork'] != null + ? (json['plannedWork'] as num).toDouble() + : 0.0, projectStatusId: json['projectStatusId'], - tenantId: json['tenantId'], + tenantId: json['tenantId'], ); } diff --git a/lib/view/dashboard/dashboard_screen.dart b/lib/view/dashboard/dashboard_screen.dart index bb3e0b6..33df6b5 100644 --- a/lib/view/dashboard/dashboard_screen.dart +++ b/lib/view/dashboard/dashboard_screen.dart @@ -59,7 +59,7 @@ class _DashboardScreenState extends State with UIMixin { MySpacing.height(12), _buildDashboardStats(), MySpacing.height(24), - AttendanceDashboardChart(), + // AttendanceDashboardChart(), MySpacing.height(300), if (!hasMpin) ...[ diff --git a/lib/view/taskPlaning/daily_progress.dart b/lib/view/taskPlaning/daily_progress.dart index 7076987..9d81018 100644 --- a/lib/view/taskPlaning/daily_progress.dart +++ b/lib/view/taskPlaning/daily_progress.dart @@ -467,7 +467,7 @@ class _DailyProgressReportScreenState extends State TaskActionButtons.reportButton( context: context, task: task, - completed: completed, + completed: completed.toInt(), refreshCallback: _refreshData, ), const SizedBox(width: 8), @@ -478,7 +478,7 @@ class _DailyProgressReportScreenState extends State parentTaskID: parentTaskID, workAreaId: workAreaId.toString(), activityId: activityId.toString(), - completed: completed, + completed: completed.toInt(), refreshCallback: _refreshData, ), const SizedBox(width: 8), diff --git a/lib/view/taskPlaning/daily_task_planing.dart b/lib/view/taskPlaning/daily_task_planing.dart index 2b1c2d2..b28fa77 100644 --- a/lib/view/taskPlaning/daily_task_planing.dart +++ b/lib/view/taskPlaning/daily_task_planing.dart @@ -280,10 +280,10 @@ class _DailyTaskPlaningScreenState extends State floorExpansionState[floorWorkAreaKey] ?? false; final totalPlanned = area.workItems .map((wi) => wi.workItem.plannedWork ?? 0) - .fold(0, (prev, curr) => prev + curr); + .fold(0, (prev, curr) => prev + curr); final totalCompleted = area.workItems .map((wi) => wi.workItem.completedWork ?? 0) - .fold(0, (prev, curr) => prev + curr); + .fold(0, (prev, curr) => prev + curr); final totalProgress = totalPlanned == 0 ? 0.0 : (totalCompleted / totalPlanned).clamp(0.0, 1.0); @@ -430,7 +430,7 @@ class _DailyTaskPlaningScreenState extends State onPressed: () { final pendingTask = (planned - completed) - .clamp(0, planned); + .clamp(0, planned).toInt(); showModalBottomSheet( context: context,