feat: Add organization selection and related API integration in attendance module
This commit is contained in:
parent
8d3c900262
commit
6863769b8a
@ -15,7 +15,7 @@ import 'package:marco/model/employees/employee_model.dart';
|
||||
import 'package:marco/model/attendance/attendance_log_model.dart';
|
||||
import 'package:marco/model/regularization_log_model.dart';
|
||||
import 'package:marco/model/attendance/attendance_log_view_model.dart';
|
||||
|
||||
import 'package:marco/model/attendance/organization_per_project_list_model.dart';
|
||||
import 'package:marco/controller/project_controller.dart';
|
||||
|
||||
class AttendanceController extends GetxController {
|
||||
@ -26,9 +26,13 @@ class AttendanceController extends GetxController {
|
||||
List<AttendanceLogModel> attendanceLogs = [];
|
||||
List<RegularizationLogModel> regularizationLogs = [];
|
||||
List<AttendanceLogViewModel> attendenceLogsView = [];
|
||||
// ------------------ Organizations ------------------
|
||||
List<Organization> organizations = [];
|
||||
Organization? selectedOrganization;
|
||||
final isLoadingOrganizations = false.obs;
|
||||
|
||||
// States
|
||||
String selectedTab = 'Employee List';
|
||||
String selectedTab = 'todaysAttendance';
|
||||
DateTime? startDateAttendance;
|
||||
DateTime? endDateAttendance;
|
||||
|
||||
@ -45,11 +49,16 @@ class AttendanceController extends GetxController {
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
_initializeDefaults();
|
||||
|
||||
// 🔹 Fetch organizations for the selected project
|
||||
final projectId = Get.find<ProjectController>().selectedProject?.id;
|
||||
if (projectId != null) {
|
||||
fetchOrganizations(projectId);
|
||||
}
|
||||
}
|
||||
|
||||
void _initializeDefaults() {
|
||||
_setDefaultDateRange();
|
||||
fetchProjects();
|
||||
}
|
||||
|
||||
void _setDefaultDateRange() {
|
||||
@ -104,29 +113,15 @@ class AttendanceController extends GetxController {
|
||||
.toList();
|
||||
}
|
||||
|
||||
Future<void> fetchProjects() async {
|
||||
isLoadingProjects.value = true;
|
||||
|
||||
final response = await ApiService.getProjects();
|
||||
if (response != null && response.isNotEmpty) {
|
||||
projects = response.map((e) => ProjectModel.fromJson(e)).toList();
|
||||
logSafe("Projects fetched: ${projects.length}");
|
||||
} else {
|
||||
projects = [];
|
||||
logSafe("Failed to fetch projects or no projects available.",
|
||||
level: LogLevel.error);
|
||||
}
|
||||
|
||||
isLoadingProjects.value = false;
|
||||
update(['attendance_dashboard_controller']);
|
||||
}
|
||||
|
||||
Future<void> fetchEmployeesByProject(String? projectId) async {
|
||||
Future<void> fetchTodaysAttendance(String? projectId) async {
|
||||
if (projectId == null) return;
|
||||
|
||||
isLoadingEmployees.value = true;
|
||||
|
||||
final response = await ApiService.getEmployeesByProject(projectId);
|
||||
final response = await ApiService.getTodaysAttendance(
|
||||
projectId,
|
||||
organizationId: selectedOrganization?.id,
|
||||
);
|
||||
if (response != null) {
|
||||
employees = response.map((e) => EmployeeModel.fromJson(e)).toList();
|
||||
for (var emp in employees) {
|
||||
@ -141,6 +136,20 @@ class AttendanceController extends GetxController {
|
||||
update();
|
||||
}
|
||||
|
||||
Future<void> fetchOrganizations(String projectId) async {
|
||||
isLoadingOrganizations.value = true;
|
||||
final response = await ApiService.getAssignedOrganizations(projectId);
|
||||
if (response != null) {
|
||||
organizations = response.data;
|
||||
logSafe("Organizations fetched: ${organizations.length}");
|
||||
} else {
|
||||
logSafe("Failed to fetch organizations for project $projectId",
|
||||
level: LogLevel.error);
|
||||
}
|
||||
isLoadingOrganizations.value = false;
|
||||
update();
|
||||
}
|
||||
|
||||
// ------------------ Attendance Capture ------------------
|
||||
|
||||
Future<bool> captureAndUploadAttendance(
|
||||
@ -262,8 +271,12 @@ class AttendanceController extends GetxController {
|
||||
|
||||
isLoadingAttendanceLogs.value = true;
|
||||
|
||||
final response = await ApiService.getAttendanceLogs(projectId,
|
||||
dateFrom: dateFrom, dateTo: dateTo);
|
||||
final response = await ApiService.getAttendanceLogs(
|
||||
projectId,
|
||||
dateFrom: dateFrom,
|
||||
dateTo: dateTo,
|
||||
organizationId: selectedOrganization?.id,
|
||||
);
|
||||
if (response != null) {
|
||||
attendanceLogs =
|
||||
response.map((e) => AttendanceLogModel.fromJson(e)).toList();
|
||||
@ -306,7 +319,10 @@ class AttendanceController extends GetxController {
|
||||
|
||||
isLoadingRegularizationLogs.value = true;
|
||||
|
||||
final response = await ApiService.getRegularizationLogs(projectId);
|
||||
final response = await ApiService.getRegularizationLogs(
|
||||
projectId,
|
||||
organizationId: selectedOrganization?.id,
|
||||
);
|
||||
if (response != null) {
|
||||
regularizationLogs =
|
||||
response.map((e) => RegularizationLogModel.fromJson(e)).toList();
|
||||
@ -354,14 +370,28 @@ class AttendanceController extends GetxController {
|
||||
Future<void> fetchProjectData(String? projectId) async {
|
||||
if (projectId == null) return;
|
||||
|
||||
await Future.wait([
|
||||
fetchEmployeesByProject(projectId),
|
||||
fetchAttendanceLogs(projectId,
|
||||
dateFrom: startDateAttendance, dateTo: endDateAttendance),
|
||||
fetchRegularizationLogs(projectId),
|
||||
]);
|
||||
await fetchOrganizations(projectId);
|
||||
|
||||
logSafe("Project data fetched for project ID: $projectId");
|
||||
// Call APIs depending on the selected tab only
|
||||
switch (selectedTab) {
|
||||
case 'todaysAttendance':
|
||||
await fetchTodaysAttendance(projectId);
|
||||
break;
|
||||
case 'attendanceLogs':
|
||||
await fetchAttendanceLogs(
|
||||
projectId,
|
||||
dateFrom: startDateAttendance,
|
||||
dateTo: endDateAttendance,
|
||||
);
|
||||
break;
|
||||
case 'regularizationRequests':
|
||||
await fetchRegularizationLogs(projectId);
|
||||
break;
|
||||
}
|
||||
|
||||
logSafe(
|
||||
"Project data fetched for project ID: $projectId, tab: $selectedTab");
|
||||
update();
|
||||
}
|
||||
|
||||
// ------------------ UI Interaction ------------------
|
||||
|
@ -14,7 +14,7 @@ class ApiEndpoints {
|
||||
// Attendance Module API Endpoints
|
||||
static const String getProjects = "/project/list";
|
||||
static const String getGlobalProjects = "/project/list/basic";
|
||||
static const String getEmployeesByProject = "/attendance/project/team";
|
||||
static const String getTodaysAttendance = "/attendance/project/team";
|
||||
static const String getAttendanceLogs = "/attendance/project/log";
|
||||
static const String getAttendanceLogView = "/attendance/log/attendance";
|
||||
static const String getRegularizationLogs = "/attendance/regularize";
|
||||
@ -90,4 +90,7 @@ class ApiEndpoints {
|
||||
|
||||
/// Logs Module API Endpoints
|
||||
static const String uploadLogs = "/log";
|
||||
|
||||
static const String getAssignedOrganizations =
|
||||
"/project/get/assigned/organization";
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import 'package:marco/model/document/master_document_tags.dart';
|
||||
import 'package:marco/model/document/master_document_type_model.dart';
|
||||
import 'package:marco/model/document/document_details_model.dart';
|
||||
import 'package:marco/model/document/document_version_model.dart';
|
||||
import 'package:marco/model/attendance/organization_per_project_list_model.dart';
|
||||
|
||||
class ApiService {
|
||||
static const Duration timeout = Duration(seconds: 30);
|
||||
@ -247,6 +248,36 @@ class ApiService {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get Organizations assigned to a Project
|
||||
static Future<OrganizationListResponse?> getAssignedOrganizations(
|
||||
String projectId) async {
|
||||
final endpoint = "${ApiEndpoints.getAssignedOrganizations}/$projectId";
|
||||
logSafe("Fetching organizations assigned to projectId: $projectId");
|
||||
|
||||
try {
|
||||
final response = await _getRequest(endpoint);
|
||||
|
||||
if (response == null) {
|
||||
logSafe("Assigned Organizations request failed: null response",
|
||||
level: LogLevel.error);
|
||||
return null;
|
||||
}
|
||||
|
||||
final jsonResponse =
|
||||
_parseResponseForAllData(response, label: "Assigned Organizations");
|
||||
|
||||
if (jsonResponse != null) {
|
||||
return OrganizationListResponse.fromJson(jsonResponse);
|
||||
}
|
||||
} catch (e, stack) {
|
||||
logSafe("Exception during getAssignedOrganizations: $e",
|
||||
level: LogLevel.error);
|
||||
logSafe("StackTrace: $stack", level: LogLevel.debug);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static Future<bool> postLogsApi(List<Map<String, dynamic>> logs) async {
|
||||
const endpoint = "${ApiEndpoints.uploadLogs}";
|
||||
logSafe("Posting logs... count=${logs.length}");
|
||||
@ -1733,23 +1764,49 @@ class ApiService {
|
||||
_getRequest(ApiEndpoints.getGlobalProjects).then((res) =>
|
||||
res != null ? _parseResponse(res, label: 'Global Projects') : null);
|
||||
|
||||
static Future<List<dynamic>?> getEmployeesByProject(String projectId) async =>
|
||||
_getRequest(ApiEndpoints.getEmployeesByProject,
|
||||
queryParams: {"projectId": projectId})
|
||||
static Future<List<dynamic>?> getTodaysAttendance(
|
||||
String projectId, {
|
||||
String? organizationId,
|
||||
}) async {
|
||||
final query = {
|
||||
"projectId": projectId,
|
||||
if (organizationId != null) "organizationId": organizationId,
|
||||
};
|
||||
|
||||
return _getRequest(ApiEndpoints.getTodaysAttendance, queryParams: query)
|
||||
.then((res) =>
|
||||
res != null ? _parseResponse(res, label: 'Employees') : null);
|
||||
}
|
||||
|
||||
static Future<List<dynamic>?> getRegularizationLogs(
|
||||
String projectId, {
|
||||
String? organizationId,
|
||||
}) async {
|
||||
final query = {
|
||||
"projectId": projectId,
|
||||
if (organizationId != null) "organizationId": organizationId,
|
||||
};
|
||||
|
||||
return _getRequest(ApiEndpoints.getRegularizationLogs, queryParams: query)
|
||||
.then((res) => res != null
|
||||
? _parseResponse(res, label: 'Regularization Logs')
|
||||
: null);
|
||||
}
|
||||
|
||||
static Future<List<dynamic>?> getAttendanceLogs(
|
||||
String projectId, {
|
||||
DateTime? dateFrom,
|
||||
DateTime? dateTo,
|
||||
String? organizationId,
|
||||
}) async {
|
||||
final query = {
|
||||
"projectId": projectId,
|
||||
if (dateFrom != null)
|
||||
"dateFrom": DateFormat('yyyy-MM-dd').format(dateFrom),
|
||||
if (dateTo != null) "dateTo": DateFormat('yyyy-MM-dd').format(dateTo),
|
||||
if (organizationId != null) "organizationId": organizationId,
|
||||
};
|
||||
|
||||
return _getRequest(ApiEndpoints.getAttendanceLogs, queryParams: query).then(
|
||||
(res) =>
|
||||
res != null ? _parseResponse(res, label: 'Attendance Logs') : null);
|
||||
@ -1759,13 +1816,6 @@ class ApiService {
|
||||
_getRequest("${ApiEndpoints.getAttendanceLogView}/$id").then((res) =>
|
||||
res != null ? _parseResponse(res, label: 'Log Details') : null);
|
||||
|
||||
static Future<List<dynamic>?> getRegularizationLogs(String projectId) async =>
|
||||
_getRequest(ApiEndpoints.getRegularizationLogs,
|
||||
queryParams: {"projectId": projectId})
|
||||
.then((res) => res != null
|
||||
? _parseResponse(res, label: 'Regularization Logs')
|
||||
: null);
|
||||
|
||||
static Future<bool> uploadAttendanceImage(
|
||||
String id,
|
||||
String employeeId,
|
||||
|
@ -193,7 +193,7 @@ class _AttendanceActionButtonState extends State<AttendanceActionButton> {
|
||||
controller.uploadingStates[uniqueLogKey]?.value = false;
|
||||
|
||||
if (success) {
|
||||
await controller.fetchEmployeesByProject(selectedProjectId);
|
||||
await controller.fetchTodaysAttendance(selectedProjectId);
|
||||
await controller.fetchAttendanceLogs(selectedProjectId);
|
||||
await controller.fetchRegularizationLogs(selectedProjectId);
|
||||
await controller.fetchProjectData(selectedProjectId);
|
||||
|
@ -5,6 +5,7 @@ import 'package:marco/controller/attendance/attendance_screen_controller.dart';
|
||||
import 'package:marco/helpers/widgets/my_text.dart';
|
||||
import 'package:marco/helpers/utils/permission_constants.dart';
|
||||
import 'package:marco/helpers/utils/base_bottom_sheet.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class AttendanceFilterBottomSheet extends StatefulWidget {
|
||||
final AttendanceController controller;
|
||||
@ -44,6 +45,59 @@ class _AttendanceFilterBottomSheetState
|
||||
return "Date Range";
|
||||
}
|
||||
|
||||
Widget _popupSelector({
|
||||
required String currentValue,
|
||||
required List<String> items,
|
||||
required ValueChanged<String> onSelected,
|
||||
}) {
|
||||
return PopupMenuButton<String>(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
onSelected: onSelected,
|
||||
itemBuilder: (context) => items
|
||||
.map((e) => PopupMenuItem<String>(
|
||||
value: e,
|
||||
child: MyText(e),
|
||||
))
|
||||
.toList(),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade100,
|
||||
border: Border.all(color: Colors.grey.shade300),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
child: MyText(
|
||||
currentValue,
|
||||
style: const TextStyle(color: Colors.black87),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
const Icon(Icons.arrow_drop_down, color: Colors.grey),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildOrganizationSelector(BuildContext context) {
|
||||
return _popupSelector(
|
||||
currentValue:
|
||||
widget.controller.selectedOrganization?.name ?? "Select Organization",
|
||||
items: widget.controller.organizations.map((e) => e.name).toList(),
|
||||
onSelected: (name) {
|
||||
final selectedOrg = widget.controller.organizations
|
||||
.firstWhere((org) => org.name == name);
|
||||
setState(() {
|
||||
widget.controller.selectedOrganization = selectedOrg;
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> buildMainFilters() {
|
||||
final hasRegularizationPermission = widget.permissionController
|
||||
.hasPermission(Permissions.regularizeAttendance);
|
||||
@ -61,7 +115,7 @@ class _AttendanceFilterBottomSheetState
|
||||
|
||||
final List<Widget> widgets = [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 4),
|
||||
padding: const EdgeInsets.only(bottom: 4),
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: MyText.titleSmall("View", fontWeight: 600),
|
||||
@ -82,11 +136,41 @@ class _AttendanceFilterBottomSheetState
|
||||
}),
|
||||
];
|
||||
|
||||
// 🔹 Organization filter
|
||||
widgets.addAll([
|
||||
const Divider(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 12, bottom: 12),
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: MyText.titleSmall("Select Organization", fontWeight: 600),
|
||||
),
|
||||
),
|
||||
Obx(() {
|
||||
if (widget.controller.isLoadingOrganizations.value) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
} else if (widget.controller.organizations.isEmpty) {
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16.0),
|
||||
child: MyText.bodyMedium(
|
||||
"No organizations found",
|
||||
fontWeight: 500,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return _buildOrganizationSelector(context);
|
||||
}),
|
||||
]);
|
||||
|
||||
// 🔹 Date Range only for attendanceLogs
|
||||
if (tempSelectedTab == 'attendanceLogs') {
|
||||
widgets.addAll([
|
||||
const Divider(),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 12, bottom: 4),
|
||||
padding: const EdgeInsets.only(top: 12, bottom: 4),
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: MyText.titleSmall("Date Range", fontWeight: 600),
|
||||
@ -99,7 +183,7 @@ class _AttendanceFilterBottomSheetState
|
||||
context,
|
||||
widget.controller,
|
||||
);
|
||||
setState(() {}); // rebuild UI after date range is updated
|
||||
setState(() {});
|
||||
},
|
||||
child: Ink(
|
||||
decoration: BoxDecoration(
|
||||
@ -139,6 +223,7 @@ class _AttendanceFilterBottomSheetState
|
||||
onCancel: () => Navigator.pop(context),
|
||||
onSubmit: () => Navigator.pop(context, {
|
||||
'selectedTab': tempSelectedTab,
|
||||
'selectedOrganization': widget.controller.selectedOrganization?.id,
|
||||
}),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
|
106
lib/model/attendance/organization_per_project_list_model.dart
Normal file
106
lib/model/attendance/organization_per_project_list_model.dart
Normal file
@ -0,0 +1,106 @@
|
||||
class OrganizationListResponse {
|
||||
final bool success;
|
||||
final String message;
|
||||
final List<Organization> data;
|
||||
final dynamic errors;
|
||||
final int statusCode;
|
||||
final String timestamp;
|
||||
|
||||
OrganizationListResponse({
|
||||
required this.success,
|
||||
required this.message,
|
||||
required this.data,
|
||||
this.errors,
|
||||
required this.statusCode,
|
||||
required this.timestamp,
|
||||
});
|
||||
|
||||
factory OrganizationListResponse.fromJson(Map<String, dynamic> json) {
|
||||
return OrganizationListResponse(
|
||||
success: json['success'] ?? false,
|
||||
message: json['message'] ?? '',
|
||||
data: (json['data'] as List<dynamic>?)
|
||||
?.map((e) => Organization.fromJson(e))
|
||||
.toList() ??
|
||||
[],
|
||||
errors: json['errors'],
|
||||
statusCode: json['statusCode'] ?? 0,
|
||||
timestamp: json['timestamp'] ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'success': success,
|
||||
'message': message,
|
||||
'data': data.map((e) => e.toJson()).toList(),
|
||||
'errors': errors,
|
||||
'statusCode': statusCode,
|
||||
'timestamp': timestamp,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class Organization {
|
||||
final String id;
|
||||
final String name;
|
||||
final String email;
|
||||
final String contactPerson;
|
||||
final String address;
|
||||
final String contactNumber;
|
||||
final int sprid;
|
||||
final String createdAt;
|
||||
final dynamic createdBy;
|
||||
final dynamic updatedBy;
|
||||
final dynamic updatedAt;
|
||||
final bool isActive;
|
||||
|
||||
Organization({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.email,
|
||||
required this.contactPerson,
|
||||
required this.address,
|
||||
required this.contactNumber,
|
||||
required this.sprid,
|
||||
required this.createdAt,
|
||||
this.createdBy,
|
||||
this.updatedBy,
|
||||
this.updatedAt,
|
||||
required this.isActive,
|
||||
});
|
||||
|
||||
factory Organization.fromJson(Map<String, dynamic> json) {
|
||||
return Organization(
|
||||
id: json['id'] ?? '',
|
||||
name: json['name'] ?? '',
|
||||
email: json['email'] ?? '',
|
||||
contactPerson: json['contactPerson'] ?? '',
|
||||
address: json['address'] ?? '',
|
||||
contactNumber: json['contactNumber'] ?? '',
|
||||
sprid: json['sprid'] ?? 0,
|
||||
createdAt: json['createdAt'] ?? '',
|
||||
createdBy: json['createdBy'],
|
||||
updatedBy: json['updatedBy'],
|
||||
updatedAt: json['updatedAt'],
|
||||
isActive: json['isActive'] ?? false,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'email': email,
|
||||
'contactPerson': contactPerson,
|
||||
'address': address,
|
||||
'contactNumber': contactNumber,
|
||||
'sprid': sprid,
|
||||
'createdAt': createdAt,
|
||||
'createdBy': createdBy,
|
||||
'updatedBy': updatedBy,
|
||||
'updatedAt': updatedAt,
|
||||
'isActive': isActive,
|
||||
};
|
||||
}
|
||||
}
|
@ -47,6 +47,7 @@ class _AttendanceScreenState extends State<AttendanceScreen> with UIMixin {
|
||||
|
||||
Future<void> _loadData(String projectId) async {
|
||||
try {
|
||||
attendanceController.selectedTab = 'todaysAttendance';
|
||||
await attendanceController.loadAttendanceData(projectId);
|
||||
attendanceController.update(['attendance_dashboard_controller']);
|
||||
} catch (e) {
|
||||
@ -56,7 +57,24 @@ class _AttendanceScreenState extends State<AttendanceScreen> with UIMixin {
|
||||
|
||||
Future<void> _refreshData() async {
|
||||
final projectId = projectController.selectedProjectId.value;
|
||||
if (projectId.isNotEmpty) await _loadData(projectId);
|
||||
if (projectId.isEmpty) return;
|
||||
|
||||
// Call only the relevant API for current tab
|
||||
switch (selectedTab) {
|
||||
case 'todaysAttendance':
|
||||
await attendanceController.fetchTodaysAttendance(projectId);
|
||||
break;
|
||||
case 'attendanceLogs':
|
||||
await attendanceController.fetchAttendanceLogs(
|
||||
projectId,
|
||||
dateFrom: attendanceController.startDateAttendance,
|
||||
dateTo: attendanceController.endDateAttendance,
|
||||
);
|
||||
break;
|
||||
case 'regularizationRequests':
|
||||
await attendanceController.fetchRegularizationLogs(projectId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildAppBar() {
|
||||
@ -195,15 +213,26 @@ class _AttendanceScreenState extends State<AttendanceScreen> with UIMixin {
|
||||
final selectedProjectId =
|
||||
projectController.selectedProjectId.value;
|
||||
final selectedView = result['selectedTab'] as String?;
|
||||
final selectedOrgId =
|
||||
result['selectedOrganization'] as String?;
|
||||
|
||||
if (selectedOrgId != null) {
|
||||
attendanceController.selectedOrganization =
|
||||
attendanceController.organizations
|
||||
.firstWhere((o) => o.id == selectedOrgId);
|
||||
}
|
||||
|
||||
if (selectedProjectId.isNotEmpty) {
|
||||
try {
|
||||
await attendanceController
|
||||
.fetchEmployeesByProject(selectedProjectId);
|
||||
await attendanceController
|
||||
.fetchAttendanceLogs(selectedProjectId);
|
||||
await attendanceController
|
||||
.fetchRegularizationLogs(selectedProjectId);
|
||||
await attendanceController.fetchTodaysAttendance(
|
||||
selectedProjectId,
|
||||
);
|
||||
await attendanceController.fetchAttendanceLogs(
|
||||
selectedProjectId,
|
||||
);
|
||||
await attendanceController.fetchRegularizationLogs(
|
||||
selectedProjectId,
|
||||
);
|
||||
await attendanceController
|
||||
.fetchProjectData(selectedProjectId);
|
||||
} catch (_) {}
|
||||
@ -214,6 +243,11 @@ class _AttendanceScreenState extends State<AttendanceScreen> with UIMixin {
|
||||
|
||||
if (selectedView != null && selectedView != selectedTab) {
|
||||
setState(() => selectedTab = selectedView);
|
||||
attendanceController.selectedTab = selectedView;
|
||||
if (selectedProjectId.isNotEmpty) {
|
||||
await attendanceController
|
||||
.fetchProjectData(selectedProjectId);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -408,4 +408,5 @@ class ExpenseFilterBottomSheet extends StatelessWidget {
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user