Merge pull request 'Service_Project_Branching' (#82) from Service_Project_Branching into main
Reviewed-on: #82
This commit is contained in:
commit
c69e4280ef
@ -1,4 +1,4 @@
|
|||||||
# marco
|
# On Field Work
|
||||||
|
|
||||||
A new Flutter project.
|
A new Flutter project.
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:label="Marco"
|
android:label="On Field Work"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/ic_launcher">
|
android:icon="@mipmap/ic_launcher">
|
||||||
<activity
|
<activity
|
||||||
|
|||||||
@ -14,7 +14,7 @@ YELLOW='\033[1;33m'
|
|||||||
NC='\033[0m' # No Color
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
# App info
|
# App info
|
||||||
APP_NAME="Marco"
|
APP_NAME="On Field Work"
|
||||||
BUILD_DIR="build/app/outputs"
|
BUILD_DIR="build/app/outputs"
|
||||||
|
|
||||||
echo -e "${CYAN}🚀 Starting Flutter build script for $APP_NAME...${NC}"
|
echo -e "${CYAN}🚀 Starting Flutter build script for $APP_NAME...${NC}"
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
<key>CFBundleDisplayName</key>
|
<key>CFBundleDisplayName</key>
|
||||||
<string>Marco</string>
|
<string>On Field Work</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
@ -13,7 +13,7 @@
|
|||||||
<key>CFBundleInfoDictionaryVersion</key>
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
<string>6.0</string>
|
<string>6.0</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
<string>marco</string>
|
<string>on field work</string>
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
|
|||||||
@ -8,5 +8,5 @@ class AppConstant {
|
|||||||
static int iOSAppVersion = 1;
|
static int iOSAppVersion = 1;
|
||||||
static String version = "1.0.0";
|
static String version = "1.0.0";
|
||||||
|
|
||||||
static String get appName => 'Marco';
|
static String get appName => 'On Field Work';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,19 +5,19 @@ import 'package:image_picker/image_picker.dart';
|
|||||||
import 'package:geolocator/geolocator.dart';
|
import 'package:geolocator/geolocator.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/helpers/widgets/my_image_compressor.dart';
|
import 'package:on_field_work/helpers/widgets/my_image_compressor.dart';
|
||||||
import 'package:marco/helpers/widgets/time_stamp_image_helper.dart';
|
import 'package:on_field_work/helpers/widgets/time_stamp_image_helper.dart';
|
||||||
|
|
||||||
import 'package:marco/model/attendance/attendance_model.dart';
|
import 'package:on_field_work/model/attendance/attendance_model.dart';
|
||||||
import 'package:marco/model/project_model.dart';
|
import 'package:on_field_work/model/project_model.dart';
|
||||||
import 'package:marco/model/employees/employee_model.dart';
|
import 'package:on_field_work/model/employees/employee_model.dart';
|
||||||
import 'package:marco/model/attendance/attendance_log_model.dart';
|
import 'package:on_field_work/model/attendance/attendance_log_model.dart';
|
||||||
import 'package:marco/model/regularization_log_model.dart';
|
import 'package:on_field_work/model/regularization_log_model.dart';
|
||||||
import 'package:marco/model/attendance/attendance_log_view_model.dart';
|
import 'package:on_field_work/model/attendance/attendance_log_view_model.dart';
|
||||||
import 'package:marco/model/attendance/organization_per_project_list_model.dart';
|
import 'package:on_field_work/model/attendance/organization_per_project_list_model.dart';
|
||||||
import 'package:marco/controller/project_controller.dart';
|
import 'package:on_field_work/controller/project_controller.dart';
|
||||||
|
|
||||||
class AttendanceController extends GetxController {
|
class AttendanceController extends GetxController {
|
||||||
// ------------------ Data Models ------------------
|
// ------------------ Data Models ------------------
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
import 'package:marco/helpers/services/auth_service.dart';
|
import 'package:on_field_work/helpers/services/auth_service.dart';
|
||||||
import 'package:marco/helpers/widgets/my_form_validator.dart';
|
import 'package:on_field_work/helpers/widgets/my_form_validator.dart';
|
||||||
import 'package:marco/helpers/widgets/my_validators.dart';
|
import 'package:on_field_work/helpers/widgets/my_validators.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/services/storage/local_storage.dart';
|
import 'package:on_field_work/helpers/services/storage/local_storage.dart';
|
||||||
|
|
||||||
class ForgotPasswordController extends MyController {
|
class ForgotPasswordController extends MyController {
|
||||||
final MyFormValidator basicValidator = MyFormValidator();
|
final MyFormValidator basicValidator = MyFormValidator();
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
import 'package:marco/helpers/services/auth_service.dart';
|
import 'package:on_field_work/helpers/services/auth_service.dart';
|
||||||
import 'package:marco/helpers/widgets/my_form_validator.dart';
|
import 'package:on_field_work/helpers/widgets/my_form_validator.dart';
|
||||||
import 'package:marco/helpers/widgets/my_validators.dart';
|
import 'package:on_field_work/helpers/widgets/my_validators.dart';
|
||||||
import 'package:marco/helpers/services/storage/local_storage.dart';
|
import 'package:on_field_work/helpers/services/storage/local_storage.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
|
|
||||||
class LoginController extends MyController {
|
class LoginController extends MyController {
|
||||||
final MyFormValidator basicValidator = MyFormValidator();
|
final MyFormValidator basicValidator = MyFormValidator();
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/auth_service.dart';
|
import 'package:on_field_work/helpers/services/auth_service.dart';
|
||||||
import 'package:marco/helpers/services/storage/local_storage.dart';
|
import 'package:on_field_work/helpers/services/storage/local_storage.dart';
|
||||||
import 'package:marco/helpers/widgets/my_form_validator.dart';
|
import 'package:on_field_work/helpers/widgets/my_form_validator.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/services/firebase/firebase_messaging_service.dart';
|
import 'package:on_field_work/helpers/services/firebase/firebase_messaging_service.dart';
|
||||||
import 'package:marco/controller/permission_controller.dart';
|
import 'package:on_field_work/controller/permission_controller.dart';
|
||||||
import 'package:marco/controller/project_controller.dart';
|
import 'package:on_field_work/controller/project_controller.dart';
|
||||||
|
|
||||||
class MPINController extends GetxController {
|
class MPINController extends GetxController {
|
||||||
final MyFormValidator basicValidator = MyFormValidator();
|
final MyFormValidator basicValidator = MyFormValidator();
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:marco/helpers/services/auth_service.dart';
|
import 'package:on_field_work/helpers/services/auth_service.dart';
|
||||||
import 'package:marco/helpers/services/storage/local_storage.dart';
|
import 'package:on_field_work/helpers/services/storage/local_storage.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
|
|
||||||
class OTPController extends GetxController {
|
class OTPController extends GetxController {
|
||||||
final formKey = GlobalKey<FormState>();
|
final formKey = GlobalKey<FormState>();
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
import 'package:marco/helpers/widgets/my_form_validator.dart';
|
import 'package:on_field_work/helpers/widgets/my_form_validator.dart';
|
||||||
import 'package:marco/helpers/widgets/my_validators.dart';
|
import 'package:on_field_work/helpers/widgets/my_validators.dart';
|
||||||
import 'package:marco/helpers/services/auth_service.dart';
|
import 'package:on_field_work/helpers/services/auth_service.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
|
|
||||||
class RegisterAccountController extends MyController {
|
class RegisterAccountController extends MyController {
|
||||||
MyFormValidator basicValidator = MyFormValidator();
|
MyFormValidator basicValidator = MyFormValidator();
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
import 'package:marco/helpers/services/auth_service.dart';
|
import 'package:on_field_work/helpers/services/auth_service.dart';
|
||||||
import 'package:marco/helpers/widgets/my_form_validator.dart';
|
import 'package:on_field_work/helpers/widgets/my_form_validator.dart';
|
||||||
import 'package:marco/helpers/widgets/my_validators.dart';
|
import 'package:on_field_work/helpers/widgets/my_validators.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
|
|
||||||
class ResetPasswordController extends MyController {
|
class ResetPasswordController extends MyController {
|
||||||
MyFormValidator basicValidator = MyFormValidator();
|
MyFormValidator basicValidator = MyFormValidator();
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/controller/project_controller.dart';
|
import 'package:on_field_work/controller/project_controller.dart';
|
||||||
import 'package:marco/model/dashboard/project_progress_model.dart';
|
import 'package:on_field_work/model/dashboard/project_progress_model.dart';
|
||||||
import 'package:marco/model/dashboard/pending_expenses_model.dart';
|
import 'package:on_field_work/model/dashboard/pending_expenses_model.dart';
|
||||||
import 'package:marco/model/dashboard/expense_type_report_model.dart';
|
import 'package:on_field_work/model/dashboard/expense_type_report_model.dart';
|
||||||
import 'package:marco/model/dashboard/monthly_expence_model.dart';
|
import 'package:on_field_work/model/dashboard/monthly_expence_model.dart';
|
||||||
import 'package:marco/model/expense/expense_type_model.dart';
|
import 'package:on_field_work/model/expense/expense_type_model.dart';
|
||||||
|
|
||||||
class DashboardController extends GetxController {
|
class DashboardController extends GetxController {
|
||||||
// =========================
|
// =========================
|
||||||
@ -58,7 +58,7 @@ class DashboardController extends GetxController {
|
|||||||
final Rx<PendingExpensesData?> pendingExpensesData =
|
final Rx<PendingExpensesData?> pendingExpensesData =
|
||||||
Rx<PendingExpensesData?>(null);
|
Rx<PendingExpensesData?>(null);
|
||||||
// =========================
|
// =========================
|
||||||
// Expense Type Report
|
// Expense Category Report
|
||||||
// =========================
|
// =========================
|
||||||
final RxBool isExpenseTypeReportLoading = false.obs;
|
final RxBool isExpenseTypeReportLoading = false.obs;
|
||||||
final Rx<ExpenseTypeReportData?> expenseTypeReportData =
|
final Rx<ExpenseTypeReportData?> expenseTypeReportData =
|
||||||
@ -355,15 +355,15 @@ class DashboardController extends GetxController {
|
|||||||
|
|
||||||
if (response != null && response.success) {
|
if (response != null && response.success) {
|
||||||
expenseTypeReportData.value = response.data;
|
expenseTypeReportData.value = response.data;
|
||||||
logSafe('Expense Type Report fetched successfully.',
|
logSafe('Expense Category Report fetched successfully.',
|
||||||
level: LogLevel.info);
|
level: LogLevel.info);
|
||||||
} else {
|
} else {
|
||||||
expenseTypeReportData.value = null;
|
expenseTypeReportData.value = null;
|
||||||
logSafe('Failed to fetch Expense Type Report.', level: LogLevel.error);
|
logSafe('Failed to fetch Expense Category Report.', level: LogLevel.error);
|
||||||
}
|
}
|
||||||
} catch (e, st) {
|
} catch (e, st) {
|
||||||
expenseTypeReportData.value = null;
|
expenseTypeReportData.value = null;
|
||||||
logSafe('Error fetching Expense Type Report',
|
logSafe('Error fetching Expense Category Report',
|
||||||
level: LogLevel.error, error: e, stackTrace: st);
|
level: LogLevel.error, error: e, stackTrace: st);
|
||||||
} finally {
|
} finally {
|
||||||
isExpenseTypeReportLoading.value = false;
|
isExpenseTypeReportLoading.value = false;
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:marco/controller/directory/directory_controller.dart';
|
import 'package:on_field_work/controller/directory/directory_controller.dart';
|
||||||
import 'package:marco/controller/directory/notes_controller.dart';
|
import 'package:on_field_work/controller/directory/notes_controller.dart';
|
||||||
|
|
||||||
class AddCommentController extends GetxController {
|
class AddCommentController extends GetxController {
|
||||||
final String contactId;
|
final String contactId;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
|
|
||||||
class AddContactController extends GetxController {
|
class AddContactController extends GetxController {
|
||||||
final RxList<String> categories = <String>[].obs;
|
final RxList<String> categories = <String>[].obs;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
|
|
||||||
class BucketController extends GetxController {
|
class BucketController extends GetxController {
|
||||||
RxBool isCreating = false.obs;
|
RxBool isCreating = false.obs;
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:marco/model/directory/contact_model.dart';
|
import 'package:on_field_work/model/directory/contact_model.dart';
|
||||||
import 'package:marco/model/directory/contact_bucket_list_model.dart';
|
import 'package:on_field_work/model/directory/contact_bucket_list_model.dart';
|
||||||
import 'package:marco/model/directory/directory_comment_model.dart';
|
import 'package:on_field_work/model/directory/directory_comment_model.dart';
|
||||||
|
|
||||||
class DirectoryController extends GetxController {
|
class DirectoryController extends GetxController {
|
||||||
// -------------------- CONTACTS --------------------
|
// -------------------- CONTACTS --------------------
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/model/employees/employee_model.dart';
|
import 'package:on_field_work/model/employees/employee_model.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:marco/controller/directory/directory_controller.dart';
|
import 'package:on_field_work/controller/directory/directory_controller.dart';
|
||||||
|
|
||||||
class ManageBucketController extends GetxController {
|
class ManageBucketController extends GetxController {
|
||||||
RxList<EmployeeModel> allEmployees = <EmployeeModel>[].obs;
|
RxList<EmployeeModel> allEmployees = <EmployeeModel>[].obs;
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:marco/model/directory/note_list_response_model.dart';
|
import 'package:on_field_work/model/directory/note_list_response_model.dart';
|
||||||
|
|
||||||
class NotesController extends GetxController {
|
class NotesController extends GetxController {
|
||||||
RxList<NoteModel> notesList = <NoteModel>[].obs;
|
RxList<NoteModel> notesList = <NoteModel>[].obs;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/model/document/document_details_model.dart';
|
import 'package:on_field_work/model/document/document_details_model.dart';
|
||||||
import 'package:marco/model/document/document_version_model.dart';
|
import 'package:on_field_work/model/document/document_version_model.dart';
|
||||||
|
|
||||||
class DocumentDetailsController extends GetxController {
|
class DocumentDetailsController extends GetxController {
|
||||||
/// Observables
|
/// Observables
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/model/document/master_document_type_model.dart';
|
import 'package:on_field_work/model/document/master_document_type_model.dart';
|
||||||
import 'package:marco/model/document/master_document_tags.dart';
|
import 'package:on_field_work/model/document/master_document_tags.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
|
|
||||||
class DocumentUploadController extends GetxController {
|
class DocumentUploadController extends GetxController {
|
||||||
// Observables
|
// Observables
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/model/document/document_filter_model.dart';
|
import 'package:on_field_work/model/document/document_filter_model.dart';
|
||||||
import 'package:marco/model/document/documents_list_model.dart';
|
import 'package:on_field_work/model/document/documents_list_model.dart';
|
||||||
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
|
|
||||||
class DocumentController extends GetxController {
|
class DocumentController extends GetxController {
|
||||||
// ==================== Observables ====================
|
// ==================== Observables ====================
|
||||||
@ -38,7 +39,6 @@ class DocumentController extends GetxController {
|
|||||||
final endDate = Rxn<DateTime>();
|
final endDate = Rxn<DateTime>();
|
||||||
|
|
||||||
// ==================== Lifecycle ====================
|
// ==================== Lifecycle ====================
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onClose() {
|
void onClose() {
|
||||||
// Don't dispose searchController here - it's managed by the page
|
// Don't dispose searchController here - it's managed by the page
|
||||||
@ -87,13 +87,23 @@ class DocumentController extends GetxController {
|
|||||||
entityId: entityId,
|
entityId: entityId,
|
||||||
reset: true,
|
reset: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Show success snackbar
|
||||||
|
showAppSnackbar(
|
||||||
|
title: 'Success',
|
||||||
|
message: isActive ? 'Document deactivated' : 'Document activated',
|
||||||
|
type: SnackbarType.success,
|
||||||
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
errorMessage.value = 'Failed to update document state';
|
errorMessage.value = 'Failed to update document state';
|
||||||
|
_showError('Failed to update document state');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
errorMessage.value = 'Error updating document: $e';
|
errorMessage.value = 'Error updating document: $e';
|
||||||
|
_showError('Error updating document: $e');
|
||||||
debugPrint('❌ Error toggling document state: $e');
|
debugPrint('❌ Error toggling document state: $e');
|
||||||
return false;
|
return false;
|
||||||
} finally {
|
} finally {
|
||||||
@ -110,17 +120,13 @@ class DocumentController extends GetxController {
|
|||||||
bool reset = false,
|
bool reset = false,
|
||||||
}) async {
|
}) async {
|
||||||
try {
|
try {
|
||||||
// Reset pagination if needed
|
|
||||||
if (reset) {
|
if (reset) {
|
||||||
pageNumber.value = 1;
|
pageNumber.value = 1;
|
||||||
documents.clear();
|
documents.clear();
|
||||||
hasMore.value = true;
|
hasMore.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't fetch if no more data
|
|
||||||
if (!hasMore.value && !reset) return;
|
if (!hasMore.value && !reset) return;
|
||||||
|
|
||||||
// Prevent duplicate requests
|
|
||||||
if (isLoading.value) return;
|
if (isLoading.value) return;
|
||||||
|
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
@ -147,12 +153,24 @@ class DocumentController extends GetxController {
|
|||||||
errorMessage.value = response?.message ?? 'Failed to fetch documents';
|
errorMessage.value = response?.message ?? 'Failed to fetch documents';
|
||||||
if (documents.isEmpty) {
|
if (documents.isEmpty) {
|
||||||
_showError('Failed to load documents');
|
_showError('Failed to load documents');
|
||||||
|
} else {
|
||||||
|
showAppSnackbar(
|
||||||
|
title: 'Warning',
|
||||||
|
message: 'No more documents to load',
|
||||||
|
type: SnackbarType.warning,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
errorMessage.value = 'Error fetching documents: $e';
|
errorMessage.value = 'Error fetching documents: $e';
|
||||||
if (documents.isEmpty) {
|
if (documents.isEmpty) {
|
||||||
_showError('Error loading documents');
|
_showError('Error loading documents');
|
||||||
|
} else {
|
||||||
|
showAppSnackbar(
|
||||||
|
title: 'Error',
|
||||||
|
message: 'Error fetching additional documents',
|
||||||
|
type: SnackbarType.error,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
debugPrint('❌ Error fetching documents: $e');
|
debugPrint('❌ Error fetching documents: $e');
|
||||||
} finally {
|
} finally {
|
||||||
@ -185,17 +203,12 @@ class DocumentController extends GetxController {
|
|||||||
isVerified.value != null;
|
isVerified.value != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show error message
|
/// Show error message via snackbar
|
||||||
void _showError(String message) {
|
void _showError(String message) {
|
||||||
Get.snackbar(
|
showAppSnackbar(
|
||||||
'Error',
|
title: 'Error',
|
||||||
message,
|
message: message,
|
||||||
snackPosition: SnackPosition.BOTTOM,
|
type: SnackbarType.error,
|
||||||
backgroundColor: Colors.red.shade100,
|
|
||||||
colorText: Colors.red.shade900,
|
|
||||||
margin: const EdgeInsets.all(16),
|
|
||||||
borderRadius: 8,
|
|
||||||
duration: const Duration(seconds: 3),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/model/dynamicMenu/dynamic_menu_model.dart';
|
import 'package:on_field_work/model/dynamicMenu/dynamic_menu_model.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
|
|
||||||
class DynamicMenuController extends GetxController {
|
class DynamicMenuController extends GetxController {
|
||||||
// UI reactive states
|
// UI reactive states
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import 'package:file_picker/file_picker.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/widgets/my_form_validator.dart';
|
import 'package:on_field_work/helpers/widgets/my_form_validator.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:flutter_contacts/flutter_contacts.dart';
|
import 'package:flutter_contacts/flutter_contacts.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/model/global_project_model.dart';
|
import 'package:on_field_work/model/global_project_model.dart';
|
||||||
import 'package:marco/model/employees/assigned_projects_model.dart';
|
import 'package:on_field_work/model/employees/assigned_projects_model.dart';
|
||||||
import 'package:marco/controller/project_controller.dart';
|
import 'package:on_field_work/controller/project_controller.dart';
|
||||||
|
|
||||||
class AssignProjectController extends GetxController {
|
class AssignProjectController extends GetxController {
|
||||||
final String employeeId;
|
final String employeeId;
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/model/employees/employee_model.dart';
|
import 'package:on_field_work/model/employees/employee_model.dart';
|
||||||
import 'package:marco/model/employees/employee_details_model.dart';
|
import 'package:on_field_work/model/employees/employee_details_model.dart';
|
||||||
|
|
||||||
class EmployeesScreenController extends GetxController {
|
class EmployeesScreenController extends GetxController {
|
||||||
/// ✅ Data lists
|
/// ✅ Data lists
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
|
|
||||||
class ComingSoonController extends MyController {
|
class ComingSoonController extends MyController {
|
||||||
Timer? countdownTimer;
|
Timer? countdownTimer;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
|
|
||||||
class Error404Controller extends MyController {
|
class Error404Controller extends MyController {
|
||||||
void goToDashboardScreen() {
|
void goToDashboardScreen() {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
|
|
||||||
class Error500Controller extends MyController {
|
class Error500Controller extends MyController {
|
||||||
void goToDashboardScreen() {
|
void goToDashboardScreen() {
|
||||||
|
|||||||
@ -10,14 +10,14 @@ import 'package:intl/intl.dart';
|
|||||||
import 'package:mime/mime.dart';
|
import 'package:mime/mime.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
|
|
||||||
import 'package:marco/controller/expense/expense_screen_controller.dart';
|
import 'package:on_field_work/controller/expense/expense_screen_controller.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:marco/model/employees/employee_model.dart';
|
import 'package:on_field_work/model/employees/employee_model.dart';
|
||||||
import 'package:marco/model/expense/expense_type_model.dart';
|
import 'package:on_field_work/model/expense/expense_type_model.dart';
|
||||||
import 'package:marco/model/expense/payment_types_model.dart';
|
import 'package:on_field_work/model/expense/payment_types_model.dart';
|
||||||
import 'package:marco/helpers/widgets/time_stamp_image_helper.dart';
|
import 'package:on_field_work/helpers/widgets/time_stamp_image_helper.dart';
|
||||||
|
|
||||||
class AddExpenseController extends GetxController {
|
class AddExpenseController extends GetxController {
|
||||||
// --- Text Controllers ---
|
// --- Text Controllers ---
|
||||||
@ -196,7 +196,7 @@ class AddExpenseController extends GetxController {
|
|||||||
'Location: ${locationController.text}',
|
'Location: ${locationController.text}',
|
||||||
'Transaction Date: ${transactionDateController.text}',
|
'Transaction Date: ${transactionDateController.text}',
|
||||||
'No. of Persons: ${noOfPersonsController.text}',
|
'No. of Persons: ${noOfPersonsController.text}',
|
||||||
'Expense Type: ${selectedExpenseType.value?.name}',
|
'Expense Category: ${selectedExpenseType.value?.name}',
|
||||||
'Payment Mode: ${selectedPaymentMode.value?.name}',
|
'Payment Mode: ${selectedPaymentMode.value?.name}',
|
||||||
'Paid By: ${selectedPaidBy.value?.name}',
|
'Paid By: ${selectedPaidBy.value?.name}',
|
||||||
'Attachments: ${attachments.length}',
|
'Attachments: ${attachments.length}',
|
||||||
@ -445,7 +445,7 @@ class AddExpenseController extends GetxController {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (expenseType == null) {
|
if (expenseType == null) {
|
||||||
_errorSnackbar("Expense type not selected");
|
_errorSnackbar("Expense Category not selected");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (paymentMode == null) {
|
if (paymentMode == null) {
|
||||||
@ -517,7 +517,7 @@ class AddExpenseController extends GetxController {
|
|||||||
final missing = <String>[];
|
final missing = <String>[];
|
||||||
|
|
||||||
if (selectedProject.value.isEmpty) missing.add("Project");
|
if (selectedProject.value.isEmpty) missing.add("Project");
|
||||||
if (selectedExpenseType.value == null) missing.add("Expense Type");
|
if (selectedExpenseType.value == null) missing.add("Expense Category");
|
||||||
if (selectedPaymentMode.value == null) missing.add("Payment Mode");
|
if (selectedPaymentMode.value == null) missing.add("Payment Mode");
|
||||||
if (selectedPaidBy.value == null) missing.add("Paid By");
|
if (selectedPaidBy.value == null) missing.add("Paid By");
|
||||||
if (amountController.text.trim().isEmpty) missing.add("Amount");
|
if (amountController.text.trim().isEmpty) missing.add("Amount");
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/model/expense/expense_detail_model.dart';
|
import 'package:on_field_work/model/expense/expense_detail_model.dart';
|
||||||
import 'package:marco/model/employees/employee_model.dart';
|
import 'package:on_field_work/model/employees/employee_model.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class ExpenseDetailController extends GetxController {
|
class ExpenseDetailController extends GetxController {
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/model/expense/expense_list_model.dart';
|
import 'package:on_field_work/model/expense/expense_list_model.dart';
|
||||||
import 'package:marco/model/expense/payment_types_model.dart';
|
import 'package:on_field_work/model/expense/payment_types_model.dart';
|
||||||
import 'package:marco/model/expense/expense_type_model.dart';
|
import 'package:on_field_work/model/expense/expense_type_model.dart';
|
||||||
import 'package:marco/model/expense/expense_status_model.dart';
|
import 'package:on_field_work/model/expense/expense_status_model.dart';
|
||||||
import 'package:marco/model/employees/employee_model.dart';
|
import 'package:on_field_work/model/employees/employee_model.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class ExpenseController extends GetxController {
|
class ExpenseController extends GetxController {
|
||||||
@ -213,7 +213,7 @@ class ExpenseController extends GetxController {
|
|||||||
selectedCreatedByEmployees.clear();
|
selectedCreatedByEmployees.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fetch master data: expense types, payment modes, and expense status
|
/// Fetch master data: Expense Categorys, payment modes, and expense status
|
||||||
Future<void> fetchMasterData() async {
|
Future<void> fetchMasterData() async {
|
||||||
try {
|
try {
|
||||||
final expenseTypesData = await ApiService.getMasterExpenseTypes();
|
final expenseTypesData = await ApiService.getMasterExpenseTypes();
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
import 'package:marco/helpers/widgets/my_text_utils.dart';
|
import 'package:on_field_work/helpers/widgets/my_text_utils.dart';
|
||||||
|
|
||||||
class FaqsController extends MyController {
|
class FaqsController extends MyController {
|
||||||
final List<bool> dataExpansionPanel = [true, false, false, false, false, false];
|
final List<bool> dataExpansionPanel = [true, false, false, false, false, false];
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
|
|
||||||
class PricingController extends MyController {
|
class PricingController extends MyController {
|
||||||
bool isMonth = false;
|
bool isMonth = false;
|
||||||
|
|||||||
@ -8,12 +8,12 @@ import 'package:image_picker/image_picker.dart';
|
|||||||
import 'package:mime/mime.dart';
|
import 'package:mime/mime.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:marco/helpers/widgets/time_stamp_image_helper.dart';
|
import 'package:on_field_work/helpers/widgets/time_stamp_image_helper.dart';
|
||||||
import 'package:marco/model/finance/expense_category_model.dart';
|
import 'package:on_field_work/model/finance/expense_category_model.dart';
|
||||||
import 'package:marco/model/finance/currency_list_model.dart';
|
import 'package:on_field_work/model/finance/currency_list_model.dart';
|
||||||
|
|
||||||
class AddPaymentRequestController extends GetxController {
|
class AddPaymentRequestController extends GetxController {
|
||||||
// Loading States
|
// Loading States
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/model/finance/advance_payment_model.dart';
|
import 'package:on_field_work/model/finance/advance_payment_model.dart';
|
||||||
import 'package:marco/model/finance/get_employee_model.dart';
|
import 'package:on_field_work/model/finance/get_employee_model.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
|
|
||||||
class AdvancePaymentController extends GetxController {
|
class AdvancePaymentController extends GetxController {
|
||||||
/// Advance payments list
|
/// Advance payments list
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/model/finance/payment_request_list_model.dart';
|
import 'package:on_field_work/model/finance/payment_request_list_model.dart';
|
||||||
import 'package:marco/model/finance/payment_request_filter.dart';
|
import 'package:on_field_work/model/finance/payment_request_filter.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
|
|
||||||
class PaymentRequestController extends GetxController {
|
class PaymentRequestController extends GetxController {
|
||||||
// ---------------- Observables ----------------
|
// ---------------- Observables ----------------
|
||||||
@ -32,13 +32,14 @@ class PaymentRequestController extends GetxController {
|
|||||||
Future<void> fetchPaymentRequestFilterOptions() async {
|
Future<void> fetchPaymentRequestFilterOptions() async {
|
||||||
try {
|
try {
|
||||||
final response = await ApiService.getExpensePaymentRequestFilterApi();
|
final response = await ApiService.getExpensePaymentRequestFilterApi();
|
||||||
if (response != null) {
|
|
||||||
projects.assignAll(response.data.projects);
|
if (response != null && response.data != null) {
|
||||||
payees.assignAll(response.data.payees);
|
projects.assignAll(response.data!.projects ?? []);
|
||||||
categories.assignAll(response.data.expenseCategory);
|
payees.assignAll(response.data!.payees ?? []);
|
||||||
currencies.assignAll(response.data.currency);
|
categories.assignAll(response.data!.expenseCategory ?? []);
|
||||||
statuses.assignAll(response.data.status);
|
currencies.assignAll(response.data!.currency ?? []);
|
||||||
createdBy.assignAll(response.data.createdBy);
|
statuses.assignAll(response.data!.status ?? []);
|
||||||
|
createdBy.assignAll(response.data!.createdBy ?? []);
|
||||||
} else {
|
} else {
|
||||||
logSafe("Payment request filter API returned null",
|
logSafe("Payment request filter API returned null",
|
||||||
level: LogLevel.warning);
|
level: LogLevel.warning);
|
||||||
@ -63,7 +64,7 @@ class PaymentRequestController extends GetxController {
|
|||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------- Load More ----------------
|
// ---------------- Load More ----------------
|
||||||
Future<void> loadMorePaymentRequests() async {
|
Future<void> loadMorePaymentRequests() async {
|
||||||
if (isLoading.value || !_hasMoreData) return;
|
if (isLoading.value || !_hasMoreData) return;
|
||||||
|
|
||||||
@ -74,7 +75,7 @@ class PaymentRequestController extends GetxController {
|
|||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------- Internal API Call ----------------
|
// ---------------- Internal API Call ----------------
|
||||||
Future<void> _fetchPaymentRequestsFromApi() async {
|
Future<void> _fetchPaymentRequestsFromApi() async {
|
||||||
try {
|
try {
|
||||||
final response = await ApiService.getExpensePaymentRequestListApi(
|
final response = await ApiService.getExpensePaymentRequestListApi(
|
||||||
@ -84,17 +85,17 @@ class PaymentRequestController extends GetxController {
|
|||||||
searchString: searchString.value,
|
searchString: searchString.value,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response != null && response.data.data.isNotEmpty) {
|
final data = response?.data;
|
||||||
|
final reqList = data?.data ?? [];
|
||||||
|
|
||||||
|
if (response != null && data != null && reqList.isNotEmpty) {
|
||||||
if (_pageNumber == 1) {
|
if (_pageNumber == 1) {
|
||||||
// First page, replace the list
|
paymentRequests.assignAll(reqList);
|
||||||
paymentRequests.assignAll(response.data.data);
|
|
||||||
} else {
|
} else {
|
||||||
// Append next page items at the end
|
paymentRequests.addAll(reqList);
|
||||||
paymentRequests.addAll(response.data.data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If returned data is less than page size, no more data
|
if (reqList.length < _pageSize) {
|
||||||
if (response.data.data.length < _pageSize) {
|
|
||||||
_hasMoreData = false;
|
_hasMoreData = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:marco/model/employees/employee_model.dart';
|
import 'package:on_field_work/model/employees/employee_model.dart';
|
||||||
import 'package:marco/model/finance/payment_request_details_model.dart';
|
import 'package:on_field_work/model/finance/payment_request_details_model.dart';
|
||||||
import 'package:marco/model/expense/payment_types_model.dart';
|
import 'package:on_field_work/model/expense/payment_types_model.dart';
|
||||||
import 'package:marco/helpers/widgets/time_stamp_image_helper.dart';
|
import 'package:on_field_work/helpers/widgets/time_stamp_image_helper.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
@ -13,6 +13,7 @@ import 'package:file_picker/file_picker.dart';
|
|||||||
import 'package:geocoding/geocoding.dart';
|
import 'package:geocoding/geocoding.dart';
|
||||||
import 'package:geolocator/geolocator.dart';
|
import 'package:geolocator/geolocator.dart';
|
||||||
import 'package:mime/mime.dart';
|
import 'package:mime/mime.dart';
|
||||||
|
import 'package:on_field_work/controller/finance/payment_request_controller.dart';
|
||||||
|
|
||||||
class PaymentRequestDetailController extends GetxController {
|
class PaymentRequestDetailController extends GetxController {
|
||||||
final Rx<PaymentRequestData?> paymentRequest = Rx<PaymentRequestData?>(null);
|
final Rx<PaymentRequestData?> paymentRequest = Rx<PaymentRequestData?>(null);
|
||||||
@ -26,6 +27,8 @@ class PaymentRequestDetailController extends GetxController {
|
|||||||
final RxList<EmployeeModel> employeeSearchResults = <EmployeeModel>[].obs;
|
final RxList<EmployeeModel> employeeSearchResults = <EmployeeModel>[].obs;
|
||||||
final TextEditingController employeeSearchController =
|
final TextEditingController employeeSearchController =
|
||||||
TextEditingController();
|
TextEditingController();
|
||||||
|
PaymentRequestController get paymentRequestController =>
|
||||||
|
Get.find<PaymentRequestController>();
|
||||||
final RxBool isSearchingEmployees = false.obs;
|
final RxBool isSearchingEmployees = false.obs;
|
||||||
|
|
||||||
// Attachments
|
// Attachments
|
||||||
@ -297,6 +300,7 @@ class PaymentRequestDetailController extends GetxController {
|
|||||||
message: 'Payment submitted successfully',
|
message: 'Payment submitted successfully',
|
||||||
type: SnackbarType.success);
|
type: SnackbarType.success);
|
||||||
await fetchPaymentRequestDetail();
|
await fetchPaymentRequestDetail();
|
||||||
|
paymentRequestController.fetchPaymentRequests();
|
||||||
} else {
|
} else {
|
||||||
showAppSnackbar(
|
showAppSnackbar(
|
||||||
title: 'Error',
|
title: 'Error',
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
|
|
||||||
class AuthLayout2Controller extends MyController {}
|
class AuthLayout2Controller extends MyController {}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
import 'package:marco/helpers/widgets/my_text_utils.dart';
|
import 'package:on_field_work/helpers/widgets/my_text_utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class AuthLayoutController extends MyController {
|
class AuthLayoutController extends MyController {
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/helpers/theme/theme_customizer.dart';
|
import 'package:on_field_work/helpers/theme/theme_customizer.dart';
|
||||||
import 'package:marco/model/project_model.dart';
|
import 'package:on_field_work/model/project_model.dart';
|
||||||
|
|
||||||
class LayoutController extends GetxController {
|
class LayoutController extends GetxController {
|
||||||
// Theme Customization
|
// Theme Customization
|
||||||
@ -55,7 +55,7 @@ class LayoutController extends GetxController {
|
|||||||
isLoadingProjects.value = true;
|
isLoadingProjects.value = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final response = await ApiService.getProjects();
|
final response = await ApiService.getGlobalProjects();
|
||||||
|
|
||||||
if (response != null && response.isNotEmpty) {
|
if (response != null && response.isNotEmpty) {
|
||||||
final fetchedProjects = response.map((json) => ProjectModel.fromJson(json)).toList();
|
final fetchedProjects = response.map((json) => ProjectModel.fromJson(json)).toList();
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import 'package:get/get_state_manager/get_state_manager.dart';
|
import 'package:get/get_state_manager/get_state_manager.dart';
|
||||||
import 'package:marco/helpers/theme/theme_customizer.dart';
|
import 'package:on_field_work/helpers/theme/theme_customizer.dart';
|
||||||
|
|
||||||
abstract class MyController extends GetxController {
|
abstract class MyController extends GetxController {
|
||||||
@override
|
@override
|
||||||
|
|||||||
@ -2,11 +2,11 @@ import 'dart:async';
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/services/permission_service.dart';
|
import 'package:on_field_work/helpers/services/permission_service.dart';
|
||||||
import 'package:marco/model/user_permission.dart';
|
import 'package:on_field_work/model/user_permission.dart';
|
||||||
import 'package:marco/model/employees/employee_info.dart';
|
import 'package:on_field_work/model/employees/employee_info.dart';
|
||||||
import 'package:marco/model/projects_model.dart';
|
import 'package:on_field_work/model/projects_model.dart';
|
||||||
|
|
||||||
class PermissionController extends GetxController {
|
class PermissionController extends GetxController {
|
||||||
var permissions = <UserPermission>[].obs;
|
var permissions = <UserPermission>[].obs;
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/model/global_project_model.dart';
|
import 'package:on_field_work/model/global_project_model.dart';
|
||||||
import 'package:marco/helpers/services/storage/local_storage.dart';
|
import 'package:on_field_work/helpers/services/storage/local_storage.dart';
|
||||||
|
|
||||||
class ProjectController extends GetxController {
|
class ProjectController extends GetxController {
|
||||||
RxList<GlobalProjectModel> projects = <GlobalProjectModel>[].obs;
|
RxList<GlobalProjectModel> projects = <GlobalProjectModel>[].obs;
|
||||||
|
|||||||
@ -1,56 +1,58 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/model/employees/employee_model.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/controller/service_project/service_project_details_screen_controller.dart';
|
||||||
import 'package:marco/controller/service_project/service_project_details_screen_controller.dart';
|
import 'package:on_field_work/model/employees/employee_model.dart';
|
||||||
|
import 'package:on_field_work/model/service_project/service_project_branches_model.dart';
|
||||||
|
|
||||||
class AddServiceProjectJobController extends GetxController {
|
class AddServiceProjectJobController extends GetxController {
|
||||||
// Form Controllers
|
// FORM CONTROLLERS
|
||||||
final titleCtrl = TextEditingController();
|
final titleCtrl = TextEditingController();
|
||||||
final descCtrl = TextEditingController();
|
final descCtrl = TextEditingController();
|
||||||
final tagCtrl = TextEditingController();
|
final tagCtrl = TextEditingController();
|
||||||
final FocusNode searchFocusNode = FocusNode();
|
final searchFocusNode = FocusNode();
|
||||||
final RxBool showEmployeePicker = true.obs;
|
|
||||||
|
|
||||||
// Observables
|
// OBSERVABLES
|
||||||
final startDate = Rx<DateTime?>(DateTime.now());
|
final startDate = Rx<DateTime?>(DateTime.now());
|
||||||
final dueDate = Rx<DateTime?>(DateTime.now().add(const Duration(days: 1)));
|
final dueDate = Rx<DateTime?>(DateTime.now().add(const Duration(days: 1)));
|
||||||
|
|
||||||
final enteredTags = <String>[].obs;
|
final enteredTags = <String>[].obs;
|
||||||
|
|
||||||
final employees = <EmployeeModel>[].obs;
|
|
||||||
final selectedAssignees = <EmployeeModel>[].obs;
|
final selectedAssignees = <EmployeeModel>[].obs;
|
||||||
final isSearchingEmployees = false.obs;
|
|
||||||
|
|
||||||
// Loading states
|
// Branches
|
||||||
|
final branches = <Branch>[].obs;
|
||||||
|
final selectedBranch = Rxn<Branch>();
|
||||||
|
final isBranchLoading = false.obs;
|
||||||
|
|
||||||
|
// Loading
|
||||||
final isLoading = false.obs;
|
final isLoading = false.obs;
|
||||||
final isAllEmployeeLoading = false.obs;
|
|
||||||
final allEmployees = <EmployeeModel>[].obs;
|
|
||||||
final employeeSearchResults = <EmployeeModel>[].obs;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onInit() {
|
|
||||||
super.onInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onClose() {
|
void onClose() {
|
||||||
titleCtrl.dispose();
|
titleCtrl.dispose();
|
||||||
descCtrl.dispose();
|
descCtrl.dispose();
|
||||||
tagCtrl.dispose();
|
tagCtrl.dispose();
|
||||||
|
searchFocusNode.dispose();
|
||||||
super.onClose();
|
super.onClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Toggle employee selection
|
// FETCH BRANCHES
|
||||||
void toggleAssignee(EmployeeModel employee) {
|
Future<void> fetchBranches(String projectId) async {
|
||||||
if (selectedAssignees.contains(employee)) {
|
isBranchLoading.value = true;
|
||||||
selectedAssignees.remove(employee);
|
|
||||||
} else {
|
final response = await ApiService.getServiceProjectBranchesFull(
|
||||||
selectedAssignees.add(employee);
|
projectId: projectId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response != null && response.success) {
|
||||||
|
branches.assignAll(response.data?.data ?? []);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isBranchLoading.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create Service Project Job API call
|
// CREATE JOB
|
||||||
Future<void> createJob(String projectId) async {
|
Future<void> createJob(String projectId) async {
|
||||||
if (titleCtrl.text.trim().isEmpty || descCtrl.text.trim().isEmpty) {
|
if (titleCtrl.text.trim().isEmpty || descCtrl.text.trim().isEmpty) {
|
||||||
showAppSnackbar(
|
showAppSnackbar(
|
||||||
@ -63,18 +65,22 @@ class AddServiceProjectJobController extends GetxController {
|
|||||||
|
|
||||||
final assigneeIds = selectedAssignees.map((e) => e.id).toList();
|
final assigneeIds = selectedAssignees.map((e) => e.id).toList();
|
||||||
|
|
||||||
|
isLoading.value = true;
|
||||||
|
|
||||||
final success = await ApiService.createServiceProjectJobApi(
|
final success = await ApiService.createServiceProjectJobApi(
|
||||||
title: titleCtrl.text.trim(),
|
title: titleCtrl.text.trim(),
|
||||||
description: descCtrl.text.trim(),
|
description: descCtrl.text.trim(),
|
||||||
projectId: projectId,
|
projectId: projectId,
|
||||||
|
branchId: selectedBranch.value?.id,
|
||||||
assignees: assigneeIds.map((id) => {"id": id}).toList(),
|
assignees: assigneeIds.map((id) => {"id": id}).toList(),
|
||||||
startDate: startDate.value!,
|
startDate: startDate.value!,
|
||||||
dueDate: dueDate.value!,
|
dueDate: dueDate.value!,
|
||||||
tags: enteredTags.map((tag) => {"name": tag}).toList(),
|
tags: enteredTags.map((tag) => {"name": tag}).toList(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
isLoading.value = false;
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
// 🔥 Auto-refresh job list in ServiceProjectDetailsController
|
|
||||||
if (Get.isRegistered<ServiceProjectDetailsController>()) {
|
if (Get.isRegistered<ServiceProjectDetailsController>()) {
|
||||||
Get.find<ServiceProjectDetailsController>().refreshJobsAfterAdd();
|
Get.find<ServiceProjectDetailsController>().refreshJobsAfterAdd();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/model/service_project/job_allocation_model.dart';
|
import 'package:on_field_work/model/service_project/job_allocation_model.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
|
|
||||||
class ServiceProjectAllocationController extends GetxController {
|
class ServiceProjectAllocationController extends GetxController {
|
||||||
final projectId = ''.obs;
|
final projectId = ''.obs;
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/model/service_project/service_projects_details_model.dart';
|
import 'package:on_field_work/model/service_project/service_projects_details_model.dart';
|
||||||
import 'package:marco/model/service_project/job_list_model.dart';
|
import 'package:on_field_work/model/service_project/job_list_model.dart';
|
||||||
import 'package:marco/model/service_project/service_project_job_detail_model.dart';
|
import 'package:on_field_work/model/service_project/service_project_job_detail_model.dart';
|
||||||
import 'package:geolocator/geolocator.dart';
|
import 'package:geolocator/geolocator.dart';
|
||||||
import 'package:marco/model/service_project/job_attendance_logs_model.dart';
|
import 'package:on_field_work/model/service_project/job_attendance_logs_model.dart';
|
||||||
import 'package:marco/model/service_project/job_allocation_model.dart';
|
import 'package:on_field_work/model/service_project/job_allocation_model.dart';
|
||||||
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
@ -17,6 +17,7 @@ class ServiceProjectDetailsController extends GetxController {
|
|||||||
var projectDetail = Rxn<ProjectDetail>();
|
var projectDetail = Rxn<ProjectDetail>();
|
||||||
var jobList = <JobEntity>[].obs;
|
var jobList = <JobEntity>[].obs;
|
||||||
var jobDetail = Rxn<JobDetailsResponse>();
|
var jobDetail = Rxn<JobDetailsResponse>();
|
||||||
|
var showArchivedJobs = false.obs; // true = archived, false = active
|
||||||
|
|
||||||
// Loading states
|
// Loading states
|
||||||
var isLoading = false.obs;
|
var isLoading = false.obs;
|
||||||
@ -39,21 +40,47 @@ class ServiceProjectDetailsController extends GetxController {
|
|||||||
var teamList = <ServiceProjectAllocation>[].obs;
|
var teamList = <ServiceProjectAllocation>[].obs;
|
||||||
var isTeamLoading = false.obs;
|
var isTeamLoading = false.obs;
|
||||||
var teamErrorMessage = ''.obs;
|
var teamErrorMessage = ''.obs;
|
||||||
|
var filteredJobList = <JobEntity>[].obs;
|
||||||
|
|
||||||
// -------------------- Lifecycle --------------------
|
// -------------------- Lifecycle --------------------
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
fetchProjectJobs(); // always load jobs even without projectId
|
fetchProjectJobs();
|
||||||
|
filteredJobList.value = jobList;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------- Project --------------------
|
// -------------------- Project --------------------
|
||||||
void setProjectId(String id) {
|
void setProjectId(String id) {
|
||||||
|
if (projectId.value == id) return;
|
||||||
projectId.value = id;
|
projectId.value = id;
|
||||||
fetchProjectDetail();
|
|
||||||
|
// Reset pagination and list
|
||||||
pageNumber = 1;
|
pageNumber = 1;
|
||||||
hasMoreJobs.value = true;
|
hasMoreJobs.value = true;
|
||||||
fetchProjectJobs(); // no initialLoad
|
jobList.clear();
|
||||||
|
filteredJobList.clear();
|
||||||
|
|
||||||
|
// Fetch project detail
|
||||||
|
fetchProjectDetail();
|
||||||
|
|
||||||
|
// Always fetch jobs for this project
|
||||||
|
fetchProjectJobs(refresh: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateJobSearch(String searchText) {
|
||||||
|
if (searchText.isEmpty) {
|
||||||
|
filteredJobList.value = jobList;
|
||||||
|
} else {
|
||||||
|
filteredJobList.value = jobList.where((job) {
|
||||||
|
final lowerSearch = searchText.toLowerCase();
|
||||||
|
return job.title.toLowerCase().contains(lowerSearch) ||
|
||||||
|
(job.description.toLowerCase().contains(lowerSearch)) ||
|
||||||
|
(job.tags?.any(
|
||||||
|
(tag) => tag.name.toLowerCase().contains(lowerSearch)) ??
|
||||||
|
false);
|
||||||
|
}).toList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> fetchProjectTeams() async {
|
Future<void> fetchProjectTeams() async {
|
||||||
@ -135,33 +162,39 @@ class ServiceProjectDetailsController extends GetxController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// -------------------- Job List (modified to always load) --------------------
|
// -------------------- Job List (modified to always load) --------------------
|
||||||
Future<void> fetchProjectJobs() async {
|
Future<void> fetchProjectJobs({bool refresh = false}) async {
|
||||||
if (!hasMoreJobs.value) return;
|
if (projectId.value.isEmpty) return;
|
||||||
|
|
||||||
|
if (refresh) pageNumber = 1;
|
||||||
|
if (!hasMoreJobs.value && !refresh) return;
|
||||||
|
|
||||||
isJobLoading.value = true;
|
isJobLoading.value = true;
|
||||||
jobErrorMessage.value = '';
|
jobErrorMessage.value = '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final result = await ApiService.getServiceProjectJobListApi(
|
final result = await ApiService.getServiceProjectJobListApi(
|
||||||
projectId: projectId.value, // allows empty projectId
|
projectId: projectId.value,
|
||||||
pageNumber: pageNumber,
|
pageNumber: pageNumber,
|
||||||
pageSize: pageSize,
|
pageSize: pageSize,
|
||||||
isActive: true,
|
isActive: true,
|
||||||
|
isArchive: showArchivedJobs.value,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result != null && result.data != null) {
|
if (result != null && result.data != null) {
|
||||||
final newJobs = result.data?.data ?? [];
|
final newJobs = result.data?.data ?? [];
|
||||||
|
|
||||||
if (pageNumber == 1) {
|
if (refresh || pageNumber == 1) {
|
||||||
jobList.value = newJobs;
|
jobList.value = newJobs;
|
||||||
} else {
|
} else {
|
||||||
jobList.addAll(newJobs);
|
jobList.addAll(newJobs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filteredJobList.value = jobList;
|
||||||
|
|
||||||
hasMoreJobs.value = newJobs.length == pageSize;
|
hasMoreJobs.value = newJobs.length == pageSize;
|
||||||
if (hasMoreJobs.value) pageNumber++;
|
if (hasMoreJobs.value) pageNumber++;
|
||||||
} else {
|
} else {
|
||||||
jobErrorMessage.value = result?.message ?? "Failed to fetch job list";
|
jobErrorMessage.value = result?.message ?? "Failed to fetch jobs";
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
jobErrorMessage.value = "Error fetching jobs: $e";
|
jobErrorMessage.value = "Error fetching jobs: $e";
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/model/service_project/service_projects_list_model.dart';
|
import 'package:on_field_work/model/service_project/service_projects_list_model.dart';
|
||||||
|
|
||||||
class ServiceProjectController extends GetxController {
|
class ServiceProjectController extends GetxController {
|
||||||
final projects = <ProjectItem>[].obs;
|
final projects = <ProjectItem>[].obs;
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/helpers/widgets/my_form_validator.dart';
|
import 'package:on_field_work/helpers/widgets/my_form_validator.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:marco/model/dailyTaskPlanning/master_work_category_model.dart';
|
import 'package:on_field_work/model/dailyTaskPlanning/master_work_category_model.dart';
|
||||||
|
|
||||||
class AddTaskController extends GetxController {
|
class AddTaskController extends GetxController {
|
||||||
RxMap<String, RxBool> uploadingStates = <String, RxBool>{}.obs;
|
RxMap<String, RxBool> uploadingStates = <String, RxBool>{}.obs;
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/model/project_model.dart';
|
import 'package:on_field_work/model/project_model.dart';
|
||||||
import 'package:marco/model/dailyTaskPlanning/daily_task_model.dart';
|
import 'package:on_field_work/model/dailyTaskPlanning/daily_task_model.dart';
|
||||||
import 'package:marco/model/dailyTaskPlanning/daily_progress_report_filter_response_model.dart';
|
import 'package:on_field_work/model/dailyTaskPlanning/daily_progress_report_filter_response_model.dart';
|
||||||
|
|
||||||
class DailyTaskController extends GetxController {
|
class DailyTaskController extends GetxController {
|
||||||
List<ProjectModel> projects = [];
|
List<ProjectModel> projects = [];
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/helpers/widgets/my_form_validator.dart';
|
import 'package:on_field_work/helpers/widgets/my_form_validator.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:marco/model/project_model.dart';
|
import 'package:on_field_work/model/project_model.dart';
|
||||||
import 'package:marco/model/dailyTaskPlanning/daily_task_planning_model.dart';
|
import 'package:on_field_work/model/dailyTaskPlanning/daily_task_planning_model.dart';
|
||||||
import 'package:marco/model/employees/employee_model.dart';
|
import 'package:on_field_work/model/employees/employee_model.dart';
|
||||||
|
|
||||||
class DailyTaskPlanningController extends GetxController {
|
class DailyTaskPlanningController extends GetxController {
|
||||||
List<ProjectModel> projects = [];
|
List<ProjectModel> projects = [];
|
||||||
|
|||||||
@ -4,16 +4,16 @@ import 'dart:io';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
|
|
||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
import 'package:marco/controller/task_Planning/daily_task_Planning_controller.dart';
|
import 'package:on_field_work/controller/task_Planning/daily_task_Planning_controller.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/helpers/widgets/my_form_validator.dart';
|
import 'package:on_field_work/helpers/widgets/my_form_validator.dart';
|
||||||
import 'package:marco/helpers/widgets/my_image_compressor.dart';
|
import 'package:on_field_work/helpers/widgets/my_image_compressor.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:marco/model/dailyTaskPlanning/work_status_model.dart';
|
import 'package:on_field_work/model/dailyTaskPlanning/work_status_model.dart';
|
||||||
import 'package:marco/helpers/widgets/time_stamp_image_helper.dart';
|
import 'package:on_field_work/helpers/widgets/time_stamp_image_helper.dart';
|
||||||
|
|
||||||
enum ApiStatus { idle, loading, success, failure }
|
enum ApiStatus { idle, loading, success, failure }
|
||||||
|
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
import 'package:file_picker/file_picker.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
import 'package:marco/helpers/widgets/my_form_validator.dart';
|
import 'package:on_field_work/helpers/widgets/my_form_validator.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:marco/controller/task_Planning/daily_task_Planning_controller.dart';
|
import 'package:on_field_work/controller/task_Planning/daily_task_Planning_controller.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:marco/helpers/widgets/my_image_compressor.dart';
|
import 'package:on_field_work/helpers/widgets/my_image_compressor.dart';
|
||||||
import 'package:marco/helpers/widgets/time_stamp_image_helper.dart';
|
import 'package:on_field_work/helpers/widgets/time_stamp_image_helper.dart';
|
||||||
|
|
||||||
enum ApiStatus { idle, loading, success, failure }
|
enum ApiStatus { idle, loading, success, failure }
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/model/all_organization_model.dart';
|
import 'package:on_field_work/model/all_organization_model.dart';
|
||||||
|
|
||||||
class AllOrganizationController extends GetxController {
|
class AllOrganizationController extends GetxController {
|
||||||
RxList<AllOrganization> organizations = <AllOrganization>[].obs;
|
RxList<AllOrganization> organizations = <AllOrganization>[].obs;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/model/attendance/organization_per_project_list_model.dart';
|
import 'package:on_field_work/model/attendance/organization_per_project_list_model.dart';
|
||||||
|
|
||||||
class OrganizationController extends GetxController {
|
class OrganizationController extends GetxController {
|
||||||
/// List of organizations assigned to the selected project
|
/// List of organizations assigned to the selected project
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/model/tenant/tenant_services_model.dart';
|
import 'package:on_field_work/model/tenant/tenant_services_model.dart';
|
||||||
|
|
||||||
class ServiceController extends GetxController {
|
class ServiceController extends GetxController {
|
||||||
List<Service> services = [];
|
List<Service> services = [];
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/services/tenant_service.dart';
|
import 'package:on_field_work/helpers/services/tenant_service.dart';
|
||||||
import 'package:marco/model/tenant/tenant_list_model.dart';
|
import 'package:on_field_work/model/tenant/tenant_list_model.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:marco/helpers/services/storage/local_storage.dart';
|
import 'package:on_field_work/helpers/services/storage/local_storage.dart';
|
||||||
import 'package:marco/controller/permission_controller.dart';
|
import 'package:on_field_work/controller/permission_controller.dart';
|
||||||
|
|
||||||
class TenantSelectionController extends GetxController {
|
class TenantSelectionController extends GetxController {
|
||||||
final TenantService _tenantService = TenantService();
|
final TenantService _tenantService = TenantService();
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/services/tenant_service.dart';
|
import 'package:on_field_work/helpers/services/tenant_service.dart';
|
||||||
import 'package:marco/model/tenant/tenant_list_model.dart';
|
import 'package:on_field_work/model/tenant/tenant_list_model.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:marco/helpers/services/storage/local_storage.dart';
|
import 'package:on_field_work/helpers/services/storage/local_storage.dart';
|
||||||
import 'package:marco/controller/permission_controller.dart';
|
import 'package:on_field_work/controller/permission_controller.dart';
|
||||||
|
|
||||||
class TenantSwitchController extends GetxController {
|
class TenantSwitchController extends GetxController {
|
||||||
final TenantService _tenantService = TenantService();
|
final TenantService _tenantService = TenantService();
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
|
|
||||||
class ButtonsController extends MyController {
|
class ButtonsController extends MyController {
|
||||||
List<bool> selected = List.filled(3, false);
|
List<bool> selected = List.filled(3, false);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:carousel_slider/carousel_controller.dart';
|
import 'package:carousel_slider/carousel_controller.dart';
|
||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class CarouselsController extends MyController {
|
class CarouselsController extends MyController {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
import 'package:marco/helpers/widgets/my_text_utils.dart';
|
import 'package:on_field_work/helpers/widgets/my_text_utils.dart';
|
||||||
|
|
||||||
class DialogsController extends MyController {
|
class DialogsController extends MyController {
|
||||||
List<String> dummyTexts =
|
List<String> dummyTexts =
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
|
|
||||||
class LoadersController extends MyController {}
|
class LoadersController extends MyController {}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
import 'package:marco/helpers/widgets/my_text_utils.dart';
|
import 'package:on_field_work/helpers/widgets/my_text_utils.dart';
|
||||||
import 'package:flutter/animation.dart';
|
import 'package:flutter/animation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
import 'package:marco/helpers/extensions/string.dart';
|
import 'package:on_field_work/helpers/extensions/string.dart';
|
||||||
import 'package:marco/helpers/theme/admin_theme.dart';
|
import 'package:on_field_work/helpers/theme/admin_theme.dart';
|
||||||
import 'package:marco/helpers/widgets/my_button.dart';
|
import 'package:on_field_work/helpers/widgets/my_button.dart';
|
||||||
import 'package:marco/helpers/widgets/my_spacing.dart';
|
import 'package:on_field_work/helpers/widgets/my_spacing.dart';
|
||||||
import 'package:marco/helpers/widgets/my_text.dart';
|
import 'package:on_field_work/helpers/widgets/my_text.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:flutter_lucide/flutter_lucide.dart';
|
import 'package:flutter_lucide/flutter_lucide.dart';
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
import 'package:marco/helpers/widgets/my_text_utils.dart';
|
import 'package:on_field_work/helpers/widgets/my_text_utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class TabsController extends MyController {
|
class TabsController extends MyController {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import 'package:marco/controller/my_controller.dart';
|
import 'package:on_field_work/controller/my_controller.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class ToastMessageController extends MyController {
|
class ToastMessageController extends MyController {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import 'package:marco/helpers/services/localizations/language.dart';
|
import 'package:on_field_work/helpers/services/localizations/language.dart';
|
||||||
import 'package:marco/helpers/theme/app_notifier.dart';
|
import 'package:on_field_work/helpers/theme/app_notifier.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
import 'package:marco/helpers/services/localizations/translator.dart';
|
import 'package:on_field_work/helpers/services/localizations/translator.dart';
|
||||||
|
|
||||||
extension StringUtil on String {
|
extension StringUtil on String {
|
||||||
Color get toColor {
|
Color get toColor {
|
||||||
|
|||||||
@ -3,6 +3,8 @@ class ApiEndpoints {
|
|||||||
// static const String baseUrl = "https://api.marcoaiot.com/api";
|
// static const String baseUrl = "https://api.marcoaiot.com/api";
|
||||||
// static const String baseUrl = "https://devapi.marcoaiot.com/api";
|
// static const String baseUrl = "https://devapi.marcoaiot.com/api";
|
||||||
// static const String baseUrl = "https://mapi.marcoaiot.com/api";
|
// static const String baseUrl = "https://mapi.marcoaiot.com/api";
|
||||||
|
// static const String baseUrl = "https://api.onfieldwork.com/api";
|
||||||
|
|
||||||
|
|
||||||
static const String getMasterCurrencies = "/Master/currencies/list";
|
static const String getMasterCurrencies = "/Master/currencies/list";
|
||||||
static const String getMasterExpensesCategories =
|
static const String getMasterExpensesCategories =
|
||||||
@ -145,8 +147,9 @@ class ApiEndpoints {
|
|||||||
static const String editServiceProjectJob = "/serviceproject/job/edit";
|
static const String editServiceProjectJob = "/serviceproject/job/edit";
|
||||||
static const String createServiceProjectJob = "/serviceproject/job/create";
|
static const String createServiceProjectJob = "/serviceproject/job/create";
|
||||||
static const String serviceProjectUpateJobAttendance = "/serviceproject/job/attendance";
|
static const String serviceProjectUpateJobAttendance = "/serviceproject/job/attendance";
|
||||||
static const String serviceProjectUpateJobAttendanceLog = "/job/attendance/log";
|
static const String serviceProjectUpateJobAttendanceLog = "/serviceproject/job/attendance/log";
|
||||||
static const String getServiceProjectUpateJobAllocationList = "/serviceproject/get/allocation/list";
|
static const String getServiceProjectUpateJobAllocationList = "/serviceproject/get/allocation/list";
|
||||||
static const String manageServiceProjectUpateJobAllocation = "/serviceproject/manage/allocation";
|
static const String manageServiceProjectUpateJobAllocation = "/serviceproject/manage/allocation";
|
||||||
static const String getTeamRoles = "/master/team-roles/list";
|
static const String getTeamRoles = "/master/team-roles/list";
|
||||||
|
static const String getServiceProjectBranches = "/serviceproject/branch/list";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,41 +4,42 @@ import 'package:http/http.dart' as http;
|
|||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
import 'package:marco/helpers/services/auth_service.dart';
|
import 'package:on_field_work/helpers/services/auth_service.dart';
|
||||||
import 'package:marco/helpers/services/api_endpoints.dart';
|
import 'package:on_field_work/helpers/services/api_endpoints.dart';
|
||||||
import 'package:marco/helpers/services/storage/local_storage.dart';
|
import 'package:on_field_work/helpers/services/storage/local_storage.dart';
|
||||||
import 'package:jwt_decoder/jwt_decoder.dart';
|
import 'package:jwt_decoder/jwt_decoder.dart';
|
||||||
import 'package:marco/model/dashboard/project_progress_model.dart';
|
import 'package:on_field_work/model/dashboard/project_progress_model.dart';
|
||||||
import 'package:marco/model/dashboard/dashboard_tasks_model.dart';
|
import 'package:on_field_work/model/dashboard/dashboard_tasks_model.dart';
|
||||||
import 'package:marco/model/dashboard/dashboard_teams_model.dart';
|
import 'package:on_field_work/model/dashboard/dashboard_teams_model.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/model/document/document_filter_model.dart';
|
import 'package:on_field_work/model/document/document_filter_model.dart';
|
||||||
import 'package:marco/model/document/documents_list_model.dart';
|
import 'package:on_field_work/model/document/documents_list_model.dart';
|
||||||
import 'package:marco/model/document/master_document_tags.dart';
|
import 'package:on_field_work/model/document/master_document_tags.dart';
|
||||||
import 'package:marco/model/document/master_document_type_model.dart';
|
import 'package:on_field_work/model/document/master_document_type_model.dart';
|
||||||
import 'package:marco/model/document/document_details_model.dart';
|
import 'package:on_field_work/model/document/document_details_model.dart';
|
||||||
import 'package:marco/model/document/document_version_model.dart';
|
import 'package:on_field_work/model/document/document_version_model.dart';
|
||||||
import 'package:marco/model/attendance/organization_per_project_list_model.dart';
|
import 'package:on_field_work/model/attendance/organization_per_project_list_model.dart';
|
||||||
import 'package:marco/model/tenant/tenant_services_model.dart';
|
import 'package:on_field_work/model/tenant/tenant_services_model.dart';
|
||||||
import 'package:marco/model/dailyTaskPlanning/daily_task_model.dart';
|
import 'package:on_field_work/model/dailyTaskPlanning/daily_task_model.dart';
|
||||||
import 'package:marco/model/dailyTaskPlanning/daily_progress_report_filter_response_model.dart';
|
import 'package:on_field_work/model/dailyTaskPlanning/daily_progress_report_filter_response_model.dart';
|
||||||
import 'package:marco/model/all_organization_model.dart';
|
import 'package:on_field_work/model/all_organization_model.dart';
|
||||||
import 'package:marco/model/dashboard/pending_expenses_model.dart';
|
import 'package:on_field_work/model/dashboard/pending_expenses_model.dart';
|
||||||
import 'package:marco/model/dashboard/expense_type_report_model.dart';
|
import 'package:on_field_work/model/dashboard/expense_type_report_model.dart';
|
||||||
import 'package:marco/model/dashboard/monthly_expence_model.dart';
|
import 'package:on_field_work/model/dashboard/monthly_expence_model.dart';
|
||||||
import 'package:marco/model/finance/expense_category_model.dart';
|
import 'package:on_field_work/model/finance/expense_category_model.dart';
|
||||||
import 'package:marco/model/finance/currency_list_model.dart';
|
import 'package:on_field_work/model/finance/currency_list_model.dart';
|
||||||
import 'package:marco/model/finance/payment_payee_request_model.dart';
|
import 'package:on_field_work/model/finance/payment_payee_request_model.dart';
|
||||||
import 'package:marco/model/finance/payment_request_list_model.dart';
|
import 'package:on_field_work/model/finance/payment_request_list_model.dart';
|
||||||
import 'package:marco/model/finance/payment_request_filter.dart';
|
import 'package:on_field_work/model/finance/payment_request_filter.dart';
|
||||||
import 'package:marco/model/finance/payment_request_details_model.dart';
|
import 'package:on_field_work/model/finance/payment_request_details_model.dart';
|
||||||
import 'package:marco/model/finance/advance_payment_model.dart';
|
import 'package:on_field_work/model/finance/advance_payment_model.dart';
|
||||||
import 'package:marco/model/service_project/service_projects_list_model.dart';
|
import 'package:on_field_work/model/service_project/service_projects_list_model.dart';
|
||||||
import 'package:marco/model/service_project/service_projects_details_model.dart';
|
import 'package:on_field_work/model/service_project/service_projects_details_model.dart';
|
||||||
import 'package:marco/model/service_project/job_list_model.dart';
|
import 'package:on_field_work/model/service_project/job_list_model.dart';
|
||||||
import 'package:marco/model/service_project/service_project_job_detail_model.dart';
|
import 'package:on_field_work/model/service_project/service_project_job_detail_model.dart';
|
||||||
import 'package:marco/model/service_project/job_attendance_logs_model.dart';
|
import 'package:on_field_work/model/service_project/job_attendance_logs_model.dart';
|
||||||
import 'package:marco/model/service_project/job_allocation_model.dart';
|
import 'package:on_field_work/model/service_project/job_allocation_model.dart';
|
||||||
|
import 'package:on_field_work/model/service_project/service_project_branches_model.dart';
|
||||||
|
|
||||||
class ApiService {
|
class ApiService {
|
||||||
static const bool enableLogs = true;
|
static const bool enableLogs = true;
|
||||||
@ -310,6 +311,51 @@ class ApiService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fetch Service Project Branches with full response
|
||||||
|
static Future<ServiceProjectBranchesResponse?> getServiceProjectBranchesFull({
|
||||||
|
required String projectId,
|
||||||
|
int pageNumber = 1,
|
||||||
|
int pageSize = 20,
|
||||||
|
String searchString = '',
|
||||||
|
bool isActive = true,
|
||||||
|
}) async {
|
||||||
|
final queryParams = {
|
||||||
|
'pageNumber': pageNumber.toString(),
|
||||||
|
'pageSize': pageSize.toString(),
|
||||||
|
'searchString': searchString,
|
||||||
|
'isActive': isActive.toString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
final endpoint = "${ApiEndpoints.getServiceProjectBranches}/$projectId";
|
||||||
|
|
||||||
|
try {
|
||||||
|
final response = await _getRequest(
|
||||||
|
endpoint,
|
||||||
|
queryParams: queryParams,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response == null) {
|
||||||
|
_log("getServiceProjectBranchesFull: No response received.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final parsedJson = _parseResponseForAllData(
|
||||||
|
response,
|
||||||
|
label: "ServiceProjectBranchesFull",
|
||||||
|
);
|
||||||
|
|
||||||
|
if (parsedJson == null) return null;
|
||||||
|
|
||||||
|
return ServiceProjectBranchesResponse.fromJson(parsedJson);
|
||||||
|
} catch (e, stack) {
|
||||||
|
_log(
|
||||||
|
"Exception in getServiceProjectBranchesFull: $e\n$stack",
|
||||||
|
level: LogLevel.error,
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Service Project Module APIs
|
// Service Project Module APIs
|
||||||
static Future<List<TeamRole>?> getTeamRoles() async {
|
static Future<List<TeamRole>?> getTeamRoles() async {
|
||||||
try {
|
try {
|
||||||
@ -558,6 +604,7 @@ class ApiService {
|
|||||||
required DateTime startDate,
|
required DateTime startDate,
|
||||||
required DateTime dueDate,
|
required DateTime dueDate,
|
||||||
required List<Map<String, dynamic>> tags,
|
required List<Map<String, dynamic>> tags,
|
||||||
|
required String? branchId,
|
||||||
}) async {
|
}) async {
|
||||||
const endpoint = ApiEndpoints.createServiceProjectJob;
|
const endpoint = ApiEndpoints.createServiceProjectJob;
|
||||||
logSafe("Creating Service Project Job for projectId: $projectId");
|
logSafe("Creating Service Project Job for projectId: $projectId");
|
||||||
@ -570,6 +617,7 @@ class ApiService {
|
|||||||
"startDate": startDate.toIso8601String(),
|
"startDate": startDate.toIso8601String(),
|
||||||
"dueDate": dueDate.toIso8601String(),
|
"dueDate": dueDate.toIso8601String(),
|
||||||
"tags": tags,
|
"tags": tags,
|
||||||
|
"projectBranchId": branchId,
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -604,15 +652,18 @@ class ApiService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get Service Project Job List
|
/// Get Service Project Job List (Active or Archived)
|
||||||
static Future<JobResponse?> getServiceProjectJobListApi({
|
static Future<JobResponse?> getServiceProjectJobListApi({
|
||||||
required String projectId,
|
required String projectId,
|
||||||
int pageNumber = 1,
|
int pageNumber = 1,
|
||||||
int pageSize = 20,
|
int pageSize = 20,
|
||||||
bool isActive = true,
|
bool isActive = true,
|
||||||
|
bool isArchive = false, // new parameter to fetch archived jobs
|
||||||
}) async {
|
}) async {
|
||||||
const endpoint = ApiEndpoints.getServiceProjectJobList;
|
const endpoint = ApiEndpoints.getServiceProjectJobList;
|
||||||
logSafe("Fetching Job List for Service Project: $projectId");
|
logSafe(
|
||||||
|
"Fetching Job List for Service Project: $projectId | isActive: $isActive | isArchive: $isArchive",
|
||||||
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final queryParams = {
|
final queryParams = {
|
||||||
@ -620,27 +671,35 @@ class ApiService {
|
|||||||
'pageNumber': pageNumber.toString(),
|
'pageNumber': pageNumber.toString(),
|
||||||
'pageSize': pageSize.toString(),
|
'pageSize': pageSize.toString(),
|
||||||
'isActive': isActive.toString(),
|
'isActive': isActive.toString(),
|
||||||
|
if (isArchive)
|
||||||
|
'isArchive': 'true',
|
||||||
};
|
};
|
||||||
|
|
||||||
final response = await _getRequest(endpoint, queryParams: queryParams);
|
final response = await _getRequest(endpoint, queryParams: queryParams);
|
||||||
|
|
||||||
if (response == null) {
|
if (response == null) {
|
||||||
logSafe("Service Project Job List request failed: null response",
|
logSafe(
|
||||||
level: LogLevel.error);
|
"Service Project Job List request failed: null response",
|
||||||
|
level: LogLevel.error,
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final jsonResponse = _parseResponseForAllData(
|
final jsonResponse = _parseResponseForAllData(
|
||||||
response,
|
response,
|
||||||
label: "Service Project Job List",
|
label: isArchive
|
||||||
|
? "Archived Service Project Job List"
|
||||||
|
: "Active Service Project Job List",
|
||||||
);
|
);
|
||||||
|
|
||||||
if (jsonResponse != null) {
|
if (jsonResponse != null) {
|
||||||
return JobResponse.fromJson(jsonResponse);
|
return JobResponse.fromJson(jsonResponse);
|
||||||
}
|
}
|
||||||
} catch (e, stack) {
|
} catch (e, stack) {
|
||||||
logSafe("Exception during getServiceProjectJobListApi: $e",
|
logSafe(
|
||||||
level: LogLevel.error);
|
"Exception during getServiceProjectJobListApi: $e",
|
||||||
|
level: LogLevel.error,
|
||||||
|
);
|
||||||
logSafe("StackTrace: $stack", level: LogLevel.debug);
|
logSafe("StackTrace: $stack", level: LogLevel.debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1281,14 +1340,14 @@ class ApiService {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get Expense Type Report
|
/// Get Expense Category Report
|
||||||
static Future<ExpenseTypeReportResponse?> getExpenseTypeReportApi({
|
static Future<ExpenseTypeReportResponse?> getExpenseTypeReportApi({
|
||||||
required String projectId,
|
required String projectId,
|
||||||
required DateTime startDate,
|
required DateTime startDate,
|
||||||
required DateTime endDate,
|
required DateTime endDate,
|
||||||
}) async {
|
}) async {
|
||||||
const endpoint = ApiEndpoints.getExpenseTypeReport;
|
const endpoint = ApiEndpoints.getExpenseTypeReport;
|
||||||
logSafe("Fetching Expense Type Report for projectId: $projectId");
|
logSafe("Fetching Expense Category Report for projectId: $projectId");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final response = await _getRequest(
|
final response = await _getRequest(
|
||||||
@ -1301,13 +1360,13 @@ class ApiService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (response == null) {
|
if (response == null) {
|
||||||
logSafe("Expense Type Report request failed: null response",
|
logSafe("Expense Category Report request failed: null response",
|
||||||
level: LogLevel.error);
|
level: LogLevel.error);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final jsonResponse =
|
final jsonResponse =
|
||||||
_parseResponseForAllData(response, label: "Expense Type Report");
|
_parseResponseForAllData(response, label: "Expense Category Report");
|
||||||
|
|
||||||
if (jsonResponse != null) {
|
if (jsonResponse != null) {
|
||||||
return ExpenseTypeReportResponse.fromJson(jsonResponse);
|
return ExpenseTypeReportResponse.fromJson(jsonResponse);
|
||||||
@ -2380,11 +2439,11 @@ class ApiService {
|
|||||||
: null);
|
: null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fetch Master Expense Types
|
/// Fetch Master Expense Categorys
|
||||||
static Future<List<dynamic>?> getMasterExpenseTypes() async {
|
static Future<List<dynamic>?> getMasterExpenseTypes() async {
|
||||||
const endpoint = ApiEndpoints.getMasterExpenseCategory;
|
const endpoint = ApiEndpoints.getMasterExpenseCategory;
|
||||||
return _getRequest(endpoint).then((res) => res != null
|
return _getRequest(endpoint).then((res) => res != null
|
||||||
? _parseResponse(res, label: 'Master Expense Types')
|
? _parseResponse(res, label: 'Master Expense Categorys')
|
||||||
: null);
|
: null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:url_strategy/url_strategy.dart';
|
import 'package:url_strategy/url_strategy.dart';
|
||||||
import 'package:firebase_core/firebase_core.dart';
|
import 'package:firebase_core/firebase_core.dart';
|
||||||
import 'package:marco/helpers/services/storage/local_storage.dart';
|
import 'package:on_field_work/helpers/services/storage/local_storage.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/services/auth_service.dart';
|
import 'package:on_field_work/helpers/services/auth_service.dart';
|
||||||
import 'package:marco/helpers/services/firebase/firebase_messaging_service.dart';
|
import 'package:on_field_work/helpers/services/firebase/firebase_messaging_service.dart';
|
||||||
import 'package:marco/helpers/services/device_info_service.dart';
|
import 'package:on_field_work/helpers/services/device_info_service.dart';
|
||||||
import 'package:marco/helpers/theme/theme_customizer.dart';
|
import 'package:on_field_work/helpers/theme/theme_customizer.dart';
|
||||||
import 'package:marco/helpers/theme/app_theme.dart';
|
import 'package:on_field_work/helpers/theme/app_theme.dart';
|
||||||
|
|
||||||
Future<void> initializeApp() async {
|
Future<void> initializeApp() async {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import 'dart:io';
|
|||||||
import 'package:logger/logger.dart';
|
import 'package:logger/logger.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:marco/helpers/services/api_service.dart';
|
import 'package:on_field_work/helpers/services/api_service.dart';
|
||||||
|
|
||||||
/// Global logger instance
|
/// Global logger instance
|
||||||
Logger? _appLogger;
|
Logger? _appLogger;
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:marco/helpers/services/api_endpoints.dart';
|
import 'package:on_field_work/helpers/services/api_endpoints.dart';
|
||||||
import 'package:marco/helpers/services/storage/local_storage.dart';
|
import 'package:on_field_work/helpers/services/storage/local_storage.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
|
|
||||||
class AuthService {
|
class AuthService {
|
||||||
static const String _baseUrl = ApiEndpoints.baseUrl;
|
static const String _baseUrl = ApiEndpoints.baseUrl;
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||||
import 'package:logger/logger.dart';
|
import 'package:logger/logger.dart';
|
||||||
|
|
||||||
import 'package:marco/helpers/services/local_notification_service.dart';
|
import 'package:on_field_work/helpers/services/local_notification_service.dart';
|
||||||
import 'package:marco/helpers/services/storage/local_storage.dart';
|
import 'package:on_field_work/helpers/services/storage/local_storage.dart';
|
||||||
import 'package:marco/helpers/services/auth_service.dart';
|
import 'package:on_field_work/helpers/services/auth_service.dart';
|
||||||
import 'package:marco/helpers/services/notification_action_handler.dart';
|
import 'package:on_field_work/helpers/services/notification_action_handler.dart';
|
||||||
|
|
||||||
/// Firebase Notification Service
|
/// Firebase Notification Service
|
||||||
class FirebaseNotificationService {
|
class FirebaseNotificationService {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import 'package:marco/helpers/services/storage/local_storage.dart';
|
import 'package:on_field_work/helpers/services/storage/local_storage.dart';
|
||||||
import 'package:marco/helpers/theme/theme_customizer.dart';
|
import 'package:on_field_work/helpers/theme/theme_customizer.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class Language {
|
class Language {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:marco/helpers/services/localizations/language.dart';
|
import 'package:on_field_work/helpers/services/localizations/language.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:get/get_utils/src/extensions/string_extensions.dart';
|
import 'package:get/get_utils/src/extensions/string_extensions.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:logger/logger.dart';
|
import 'package:logger/logger.dart';
|
||||||
|
|
||||||
import 'package:marco/controller/attendance/attendance_screen_controller.dart';
|
import 'package:on_field_work/controller/attendance/attendance_screen_controller.dart';
|
||||||
import 'package:marco/controller/task_planning/daily_task_controller.dart';
|
import 'package:on_field_work/controller/task_planning/daily_task_controller.dart';
|
||||||
import 'package:marco/controller/task_Planning/daily_task_Planning_controller.dart';
|
import 'package:on_field_work/controller/task_Planning/daily_task_Planning_controller.dart';
|
||||||
import 'package:marco/controller/expense/expense_screen_controller.dart';
|
import 'package:on_field_work/controller/expense/expense_screen_controller.dart';
|
||||||
import 'package:marco/controller/expense/expense_detail_controller.dart';
|
import 'package:on_field_work/controller/expense/expense_detail_controller.dart';
|
||||||
import 'package:marco/controller/directory/directory_controller.dart';
|
import 'package:on_field_work/controller/directory/directory_controller.dart';
|
||||||
import 'package:marco/controller/directory/notes_controller.dart';
|
import 'package:on_field_work/controller/directory/notes_controller.dart';
|
||||||
import 'package:marco/controller/document/user_document_controller.dart';
|
import 'package:on_field_work/controller/document/user_document_controller.dart';
|
||||||
import 'package:marco/controller/document/document_details_controller.dart';
|
import 'package:on_field_work/controller/document/document_details_controller.dart';
|
||||||
import 'package:marco/controller/dashboard/dashboard_controller.dart';
|
import 'package:on_field_work/controller/dashboard/dashboard_controller.dart';
|
||||||
import 'package:marco/helpers/utils/permission_constants.dart';
|
import 'package:on_field_work/helpers/utils/permission_constants.dart';
|
||||||
|
|
||||||
/// Handles incoming FCM notification actions and updates UI/controllers.
|
/// Handles incoming FCM notification actions and updates UI/controllers.
|
||||||
class NotificationActionHandler {
|
class NotificationActionHandler {
|
||||||
@ -414,12 +414,17 @@ class NotificationActionHandler {
|
|||||||
required String notFoundMessage,
|
required String notFoundMessage,
|
||||||
required String successMessage,
|
required String successMessage,
|
||||||
}) {
|
}) {
|
||||||
|
if (!Get.isRegistered<T>()) {
|
||||||
|
_logger.w(notFoundMessage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final controller = Get.find<T>();
|
final controller = Get.find<T>();
|
||||||
onFound(controller);
|
onFound(controller);
|
||||||
_logger.i(successMessage);
|
_logger.i(successMessage);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
_logger.w(notFoundMessage);
|
_logger.w('⚠️ Error updating controller: $e');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,13 +2,13 @@ import 'dart:convert';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/model/user_permission.dart';
|
import 'package:on_field_work/model/user_permission.dart';
|
||||||
import 'package:marco/model/employees/employee_info.dart';
|
import 'package:on_field_work/model/employees/employee_info.dart';
|
||||||
import 'package:marco/model/projects_model.dart';
|
import 'package:on_field_work/model/projects_model.dart';
|
||||||
import 'package:marco/helpers/services/storage/local_storage.dart';
|
import 'package:on_field_work/helpers/services/storage/local_storage.dart';
|
||||||
import 'package:marco/helpers/services/auth_service.dart';
|
import 'package:on_field_work/helpers/services/auth_service.dart';
|
||||||
import 'package:marco/helpers/services/api_endpoints.dart';
|
import 'package:on_field_work/helpers/services/api_endpoints.dart';
|
||||||
|
|
||||||
class PermissionService {
|
class PermissionService {
|
||||||
// In-memory cache keyed by user token
|
// In-memory cache keyed by user token
|
||||||
|
|||||||
@ -2,13 +2,13 @@ import 'dart:convert';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
import 'package:marco/controller/project_controller.dart';
|
import 'package:on_field_work/controller/project_controller.dart';
|
||||||
import 'package:marco/helpers/services/auth_service.dart';
|
import 'package:on_field_work/helpers/services/auth_service.dart';
|
||||||
import 'package:marco/helpers/services/localizations/language.dart';
|
import 'package:on_field_work/helpers/services/localizations/language.dart';
|
||||||
import 'package:marco/helpers/theme/theme_customizer.dart';
|
import 'package:on_field_work/helpers/theme/theme_customizer.dart';
|
||||||
import 'package:marco/model/employees/employee_info.dart';
|
import 'package:on_field_work/model/employees/employee_info.dart';
|
||||||
import 'package:marco/model/user_permission.dart';
|
import 'package:on_field_work/model/user_permission.dart';
|
||||||
import 'package:marco/model/dynamicMenu/dynamic_menu_model.dart';
|
import 'package:on_field_work/model/dynamicMenu/dynamic_menu_model.dart';
|
||||||
|
|
||||||
class LocalStorage {
|
class LocalStorage {
|
||||||
static const String _loggedInUserKey = "user";
|
static const String _loggedInUserKey = "user";
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/controller/project_controller.dart';
|
import 'package:on_field_work/controller/project_controller.dart';
|
||||||
|
|
||||||
import 'package:marco/helpers/services/api_endpoints.dart';
|
import 'package:on_field_work/helpers/services/api_endpoints.dart';
|
||||||
import 'package:marco/helpers/services/storage/local_storage.dart';
|
import 'package:on_field_work/helpers/services/storage/local_storage.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
import 'package:marco/helpers/services/auth_service.dart';
|
import 'package:on_field_work/helpers/services/auth_service.dart';
|
||||||
import 'package:marco/model/tenant/tenant_list_model.dart';
|
import 'package:on_field_work/model/tenant/tenant_list_model.dart';
|
||||||
|
|
||||||
/// Abstract interface for tenant service functionality
|
/// Abstract interface for tenant service functionality
|
||||||
abstract class ITenantService {
|
abstract class ITenantService {
|
||||||
@ -63,29 +63,39 @@ class TenantService implements ITenantService {
|
|||||||
{bool hasRetried = false}) async {
|
{bool hasRetried = false}) async {
|
||||||
try {
|
try {
|
||||||
final headers = await _authorizedHeaders();
|
final headers = await _authorizedHeaders();
|
||||||
logSafe("➡️ GET $_baseUrl/auth/get/user/tenants\nHeaders: $headers",
|
|
||||||
level: LogLevel.info);
|
|
||||||
|
|
||||||
final response = await http
|
final response = await http.get(
|
||||||
.get(Uri.parse("$_baseUrl/auth/get/user/tenants"), headers: headers);
|
Uri.parse("$_baseUrl/auth/get/user/tenants"),
|
||||||
final data = jsonDecode(response.body);
|
headers: headers,
|
||||||
|
);
|
||||||
|
|
||||||
logSafe(
|
// ✅ Handle empty response BEFORE decoding
|
||||||
"⬅️ Response: ${jsonEncode(data)} [Status: ${response.statusCode}]",
|
if (response.body.isEmpty || response.body.trim().isEmpty) {
|
||||||
level: LogLevel.info);
|
logSafe("❌ Empty tenant response — auto logout");
|
||||||
|
await LocalStorage.logout();
|
||||||
if (response.statusCode == 200 && data['success'] == true) {
|
return null;
|
||||||
logSafe("✅ Tenants fetched successfully.");
|
|
||||||
return List<Map<String, dynamic>>.from(data['data']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> data;
|
||||||
|
try {
|
||||||
|
data = jsonDecode(response.body);
|
||||||
|
} catch (e) {
|
||||||
|
logSafe("❌ Invalid JSON in tenant response — auto logout");
|
||||||
|
await LocalStorage.logout();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SUCCESS CASE
|
||||||
|
if (response.statusCode == 200 && data['success'] == true) {
|
||||||
|
final list = data['data'];
|
||||||
|
if (list is! List) return null;
|
||||||
|
return List<Map<String, dynamic>>.from(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TOKEN EXPIRED
|
||||||
if (response.statusCode == 401 && !hasRetried) {
|
if (response.statusCode == 401 && !hasRetried) {
|
||||||
logSafe("⚠️ Unauthorized while fetching tenants. Refreshing token...",
|
|
||||||
level: LogLevel.warning);
|
|
||||||
final refreshed = await AuthService.refreshToken();
|
final refreshed = await AuthService.refreshToken();
|
||||||
if (refreshed) return getTenants(hasRetried: true);
|
if (refreshed) return getTenants(hasRetried: true);
|
||||||
logSafe("❌ Token refresh failed while fetching tenants.",
|
|
||||||
level: LogLevel.error);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +140,7 @@ class TenantService implements ITenantService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 🔹 Register FCM token after tenant selection
|
// 🔹 Register FCM token after tenant selection
|
||||||
final fcmToken = LocalStorage.getFcmToken();
|
final fcmToken = LocalStorage.getFcmToken();
|
||||||
if (fcmToken?.isNotEmpty ?? false) {
|
if (fcmToken?.isNotEmpty ?? false) {
|
||||||
final success = await AuthService.registerDeviceToken(fcmToken!);
|
final success = await AuthService.registerDeviceToken(fcmToken!);
|
||||||
logSafe(
|
logSafe(
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:marco/helpers/theme/theme_customizer.dart';
|
import 'package:on_field_work/helpers/theme/theme_customizer.dart';
|
||||||
|
|
||||||
enum LeftBarThemeType { light, dark }
|
enum LeftBarThemeType { light, dark }
|
||||||
enum ContentThemeType { light, dark }
|
enum ContentThemeType { light, dark }
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import 'package:marco/helpers/services/localizations/language.dart';
|
import 'package:on_field_work/helpers/services/localizations/language.dart';
|
||||||
import 'package:marco/helpers/services/storage/local_storage.dart';
|
import 'package:on_field_work/helpers/services/storage/local_storage.dart';
|
||||||
import 'package:marco/helpers/theme/app_theme.dart';
|
import 'package:on_field_work/helpers/theme/app_theme.dart';
|
||||||
import 'package:marco/helpers/theme/theme_customizer.dart';
|
import 'package:on_field_work/helpers/theme/theme_customizer.dart';
|
||||||
import 'package:marco/helpers/widgets/my.dart';
|
import 'package:on_field_work/helpers/widgets/my.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
|||||||
@ -6,13 +6,13 @@
|
|||||||
* */
|
* */
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'package:marco/helpers/theme/admin_theme.dart';
|
import 'package:on_field_work/helpers/theme/admin_theme.dart';
|
||||||
import 'package:marco/helpers/theme/theme_customizer.dart';
|
import 'package:on_field_work/helpers/theme/theme_customizer.dart';
|
||||||
import 'package:marco/helpers/widgets/my.dart';
|
import 'package:on_field_work/helpers/widgets/my.dart';
|
||||||
import 'package:marco/helpers/widgets/my_breadcrumb_item.dart';
|
import 'package:on_field_work/helpers/widgets/my_breadcrumb_item.dart';
|
||||||
import 'package:marco/helpers/widgets/my_constant.dart';
|
import 'package:on_field_work/helpers/widgets/my_constant.dart';
|
||||||
import 'package:marco/helpers/widgets/my_screen_media.dart';
|
import 'package:on_field_work/helpers/widgets/my_screen_media.dart';
|
||||||
import 'package:marco/helpers/widgets/my_text_style.dart';
|
import 'package:on_field_work/helpers/widgets/my_text_style.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
|
||||||
@ -230,7 +230,7 @@ class AppStyle {
|
|||||||
containerRadius: AppStyle.containerRadius.medium,
|
containerRadius: AppStyle.containerRadius.medium,
|
||||||
cardRadius: AppStyle.cardRadius.medium,
|
cardRadius: AppStyle.cardRadius.medium,
|
||||||
buttonRadius: AppStyle.buttonRadius.medium,
|
buttonRadius: AppStyle.buttonRadius.medium,
|
||||||
defaultBreadCrumbItem: MyBreadcrumbItem(name: 'Marco', route: '/client/dashboard'),
|
defaultBreadCrumbItem: MyBreadcrumbItem(name: 'On Field Work', route: '/client/dashboard'),
|
||||||
));
|
));
|
||||||
bool isMobile = true;
|
bool isMobile = true;
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:marco/helpers/services/json_decoder.dart';
|
import 'package:on_field_work/helpers/services/json_decoder.dart';
|
||||||
import 'package:marco/helpers/services/localizations/language.dart';
|
import 'package:on_field_work/helpers/services/localizations/language.dart';
|
||||||
import 'package:marco/helpers/services/localizations/translator.dart';
|
import 'package:on_field_work/helpers/services/localizations/translator.dart';
|
||||||
import 'package:marco/helpers/services/navigation_services.dart';
|
import 'package:on_field_work/helpers/services/navigation_services.dart';
|
||||||
import 'package:marco/helpers/theme/admin_theme.dart';
|
import 'package:on_field_work/helpers/theme/admin_theme.dart';
|
||||||
import 'package:marco/helpers/theme/app_notifier.dart';
|
import 'package:on_field_work/helpers/theme/app_notifier.dart';
|
||||||
import 'package:marco/helpers/theme/app_theme.dart';
|
import 'package:on_field_work/helpers/theme/app_theme.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/widgets/my_text.dart';
|
import 'package:on_field_work/helpers/widgets/my_text.dart';
|
||||||
import 'package:marco/helpers/widgets/wave_background.dart';
|
import 'package:on_field_work/helpers/widgets/wave_background.dart';
|
||||||
import 'package:marco/helpers/theme/admin_theme.dart';
|
import 'package:on_field_work/helpers/theme/admin_theme.dart';
|
||||||
import 'package:marco/helpers/theme/theme_customizer.dart';
|
import 'package:on_field_work/helpers/theme/theme_customizer.dart';
|
||||||
|
|
||||||
class ThemeOption {
|
class ThemeOption {
|
||||||
final String label;
|
final String label;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:marco/helpers/widgets/my_spacing.dart';
|
import 'package:on_field_work/helpers/widgets/my_spacing.dart';
|
||||||
import 'package:marco/helpers/widgets/my_text.dart';
|
import 'package:on_field_work/helpers/widgets/my_text.dart';
|
||||||
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
|
import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart';
|
||||||
|
|
||||||
class BaseBottomSheet extends StatefulWidget {
|
class BaseBottomSheet extends StatefulWidget {
|
||||||
final String title;
|
final String title;
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_contacts/flutter_contacts.dart';
|
import 'package:flutter_contacts/flutter_contacts.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
|
|
||||||
class ContactPickerHelper {
|
class ContactPickerHelper {
|
||||||
static Future<String?> pickIndianPhoneNumber(BuildContext context) async {
|
static Future<String?> pickIndianPhoneNumber(BuildContext context) async {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'package:marco/helpers/widgets/my_snackbar.dart';
|
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
|
||||||
import 'package:marco/helpers/services/app_logger.dart';
|
import 'package:on_field_work/helpers/services/app_logger.dart';
|
||||||
|
|
||||||
class LauncherUtils {
|
class LauncherUtils {
|
||||||
/// Launches the phone dialer with the provided phone number
|
/// Launches the phone dialer with the provided phone number
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import 'package:marco/helpers/theme/admin_theme.dart';
|
import 'package:on_field_work/helpers/theme/admin_theme.dart';
|
||||||
import 'package:marco/helpers/theme/app_theme.dart';
|
import 'package:on_field_work/helpers/theme/app_theme.dart';
|
||||||
import 'package:marco/helpers/widgets/my_dashed_divider.dart';
|
import 'package:on_field_work/helpers/widgets/my_dashed_divider.dart';
|
||||||
import 'package:marco/helpers/widgets/my_navigation_mixin.dart';
|
import 'package:on_field_work/helpers/widgets/my_navigation_mixin.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
mixin UIMixin {
|
mixin UIMixin {
|
||||||
|
|||||||
@ -164,3 +164,27 @@ class MenuItems {
|
|||||||
/// Service Projects
|
/// Service Projects
|
||||||
static const String serviceProjects = "7faddfe7-994b-4712-91c2-32ba44129d9b";
|
static const String serviceProjects = "7faddfe7-994b-4712-91c2-32ba44129d9b";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Contains all job status IDs used across the application.
|
||||||
|
class JobStatus {
|
||||||
|
/// Level 1 - New
|
||||||
|
static const String newStatus = "32d76a02-8f44-4aa0-9b66-c3716c45a918";
|
||||||
|
|
||||||
|
/// Level 2 - Assigned
|
||||||
|
static const String assigned = "cfa1886d-055f-4ded-84c6-42a2a8a14a66";
|
||||||
|
|
||||||
|
/// Level 3 - In Progress
|
||||||
|
static const String inProgress = "5a6873a5-fed7-4745-a52f-8f61bf3bd72d";
|
||||||
|
|
||||||
|
/// Level 4 - Work Done
|
||||||
|
static const String workDone = "aab71020-2fb8-44d9-9430-c9a7e9bf33b0";
|
||||||
|
|
||||||
|
/// Level 5 - Review Done
|
||||||
|
static const String reviewDone = "ed10ab57-dbaa-4ca5-8ecd-56745dcbdbd7";
|
||||||
|
|
||||||
|
/// Level 6 - Closed
|
||||||
|
static const String closed = "3ddeefb5-ae3c-4e10-a922-35e0a452bb69";
|
||||||
|
|
||||||
|
/// Level 7 - On Hold
|
||||||
|
static const String onHold = "75a0c8b8-9c6a-41af-80bf-b35bab722eb2";
|
||||||
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:marco/helpers/extensions/date_time_extension.dart';
|
import 'package:on_field_work/helpers/extensions/date_time_extension.dart';
|
||||||
|
|
||||||
class Utils {
|
class Utils {
|
||||||
static getDateStringFromDateTime(DateTime dateTime,
|
static getDateStringFromDateTime(DateTime dateTime,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:marco/helpers/widgets/my_container.dart';
|
import 'package:on_field_work/helpers/widgets/my_container.dart';
|
||||||
import 'package:marco/helpers/widgets/my_text.dart';
|
import 'package:on_field_work/helpers/widgets/my_text.dart';
|
||||||
|
|
||||||
class Avatar extends StatelessWidget {
|
class Avatar extends StatelessWidget {
|
||||||
final String firstName;
|
final String firstName;
|
||||||
|
|||||||
@ -1,16 +1,18 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/controller/project_controller.dart';
|
import 'package:on_field_work/controller/project_controller.dart';
|
||||||
import 'package:marco/helpers/widgets/my_spacing.dart';
|
import 'package:on_field_work/helpers/widgets/my_spacing.dart';
|
||||||
import 'package:marco/helpers/widgets/my_text.dart';
|
import 'package:on_field_work/helpers/widgets/my_text.dart';
|
||||||
|
|
||||||
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
|
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||||
final String title;
|
final String title;
|
||||||
|
final String? projectName;
|
||||||
final VoidCallback? onBackPressed;
|
final VoidCallback? onBackPressed;
|
||||||
|
|
||||||
const CustomAppBar({
|
const CustomAppBar({
|
||||||
super.key,
|
super.key,
|
||||||
required this.title,
|
required this.title,
|
||||||
|
this.projectName,
|
||||||
this.onBackPressed,
|
this.onBackPressed,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -51,21 +53,26 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
|
|
||||||
MySpacing.height(2),
|
MySpacing.height(2),
|
||||||
|
|
||||||
// PROJECT NAME ROW (copied exactly)
|
// PROJECT NAME ROW
|
||||||
GetBuilder<ProjectController>(
|
GetBuilder<ProjectController>(
|
||||||
builder: (projectController) {
|
builder: (projectController) {
|
||||||
final projectName =
|
// NEW LOGIC — simple and safe
|
||||||
|
final displayProjectName =
|
||||||
|
projectName ??
|
||||||
projectController.selectedProject?.name ??
|
projectController.selectedProject?.name ??
|
||||||
'Select Project';
|
'Select Project';
|
||||||
|
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
const Icon(Icons.work_outline,
|
const Icon(
|
||||||
size: 14, color: Colors.grey),
|
Icons.work_outline,
|
||||||
|
size: 14,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
MySpacing.width(4),
|
MySpacing.width(4),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: MyText.bodySmall(
|
child: MyText.bodySmall(
|
||||||
projectName,
|
displayProjectName,
|
||||||
fontWeight: 600,
|
fontWeight: 600,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
color: Colors.grey[700],
|
color: Colors.grey[700],
|
||||||
|
|||||||
@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:syncfusion_flutter_charts/charts.dart';
|
import 'package:syncfusion_flutter_charts/charts.dart';
|
||||||
import 'package:marco/controller/dashboard/dashboard_controller.dart';
|
import 'package:on_field_work/controller/dashboard/dashboard_controller.dart';
|
||||||
import 'package:marco/helpers/widgets/my_text.dart';
|
import 'package:on_field_work/helpers/widgets/my_text.dart';
|
||||||
|
|
||||||
class AttendanceDashboardChart extends StatelessWidget {
|
class AttendanceDashboardChart extends StatelessWidget {
|
||||||
AttendanceDashboardChart({Key? key}) : super(key: key);
|
AttendanceDashboardChart({Key? key}) : super(key: key);
|
||||||
|
|||||||
@ -4,10 +4,10 @@ import 'package:intl/intl.dart';
|
|||||||
import 'package:syncfusion_flutter_charts/charts.dart';
|
import 'package:syncfusion_flutter_charts/charts.dart';
|
||||||
|
|
||||||
// Assuming these exist in the project
|
// Assuming these exist in the project
|
||||||
import 'package:marco/controller/dashboard/dashboard_controller.dart';
|
import 'package:on_field_work/controller/dashboard/dashboard_controller.dart';
|
||||||
import 'package:marco/helpers/widgets/my_card.dart';
|
import 'package:on_field_work/helpers/widgets/my_card.dart';
|
||||||
import 'package:marco/helpers/widgets/my_spacing.dart';
|
import 'package:on_field_work/helpers/widgets/my_spacing.dart';
|
||||||
import 'package:marco/helpers/widgets/my_text.dart';
|
import 'package:on_field_work/helpers/widgets/my_text.dart';
|
||||||
|
|
||||||
class DashboardOverviewWidgets {
|
class DashboardOverviewWidgets {
|
||||||
static final DashboardController dashboardController =
|
static final DashboardController dashboardController =
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:syncfusion_flutter_charts/charts.dart';
|
import 'package:syncfusion_flutter_charts/charts.dart';
|
||||||
import 'package:marco/controller/dashboard/dashboard_controller.dart';
|
import 'package:on_field_work/controller/dashboard/dashboard_controller.dart';
|
||||||
import 'package:marco/helpers/widgets/my_text.dart';
|
import 'package:on_field_work/helpers/widgets/my_text.dart';
|
||||||
import 'package:marco/model/dashboard/expense_type_report_model.dart';
|
import 'package:on_field_work/model/dashboard/expense_type_report_model.dart';
|
||||||
import 'package:marco/helpers/utils/utils.dart';
|
import 'package:on_field_work/helpers/utils/utils.dart';
|
||||||
import 'package:marco/helpers/widgets/my_custom_skeleton.dart';
|
import 'package:on_field_work/helpers/widgets/my_custom_skeleton.dart';
|
||||||
|
|
||||||
class ExpenseTypeReportChart extends StatelessWidget {
|
class ExpenseTypeReportChart extends StatelessWidget {
|
||||||
ExpenseTypeReportChart({Key? key}) : super(key: key);
|
ExpenseTypeReportChart({Key? key}) : super(key: key);
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/controller/dashboard/dashboard_controller.dart';
|
import 'package:on_field_work/controller/dashboard/dashboard_controller.dart';
|
||||||
import 'package:marco/helpers/widgets/my_text.dart';
|
import 'package:on_field_work/helpers/widgets/my_text.dart';
|
||||||
import 'package:marco/helpers/utils/utils.dart';
|
import 'package:on_field_work/helpers/utils/utils.dart';
|
||||||
import 'package:marco/helpers/widgets/my_custom_skeleton.dart';
|
import 'package:on_field_work/helpers/widgets/my_custom_skeleton.dart';
|
||||||
import 'package:marco/controller/expense/expense_screen_controller.dart';
|
import 'package:on_field_work/controller/expense/expense_screen_controller.dart';
|
||||||
import 'package:marco/view/expense/expense_screen.dart';
|
import 'package:on_field_work/view/expense/expense_screen.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
|
|
||||||
class ExpenseByStatusWidget extends StatelessWidget {
|
class ExpenseByStatusWidget extends StatelessWidget {
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:syncfusion_flutter_charts/charts.dart';
|
import 'package:syncfusion_flutter_charts/charts.dart';
|
||||||
import 'package:marco/controller/dashboard/dashboard_controller.dart';
|
import 'package:on_field_work/controller/dashboard/dashboard_controller.dart';
|
||||||
import 'package:marco/helpers/widgets/my_text.dart';
|
import 'package:on_field_work/helpers/widgets/my_text.dart';
|
||||||
import 'package:marco/helpers/utils/utils.dart';
|
import 'package:on_field_work/helpers/utils/utils.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
// =========================
|
// =========================
|
||||||
@ -203,7 +203,7 @@ class _ChartHeader extends StatelessWidget {
|
|||||||
final selectedType = controller.selectedExpenseType.value;
|
final selectedType = controller.selectedExpenseType.value;
|
||||||
|
|
||||||
return PopupMenuButton<String>(
|
return PopupMenuButton<String>(
|
||||||
tooltip: 'Filter by Expense Type',
|
tooltip: 'Filter by Expense Category',
|
||||||
onSelected: (String value) {
|
onSelected: (String value) {
|
||||||
if (value == 'all') {
|
if (value == 'all') {
|
||||||
controller.updateSelectedExpenseType(null);
|
controller.updateSelectedExpenseType(null);
|
||||||
|
|||||||
@ -2,10 +2,10 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:syncfusion_flutter_charts/charts.dart';
|
import 'package:syncfusion_flutter_charts/charts.dart';
|
||||||
import 'package:marco/model/dashboard/project_progress_model.dart';
|
import 'package:on_field_work/model/dashboard/project_progress_model.dart';
|
||||||
import 'package:marco/controller/dashboard/dashboard_controller.dart';
|
import 'package:on_field_work/controller/dashboard/dashboard_controller.dart';
|
||||||
import 'package:marco/helpers/widgets/my_text.dart';
|
import 'package:on_field_work/helpers/widgets/my_text.dart';
|
||||||
import 'package:marco/helpers/utils/utils.dart';
|
import 'package:on_field_work/helpers/utils/utils.dart';
|
||||||
|
|
||||||
class ProjectProgressChart extends StatelessWidget {
|
class ProjectProgressChart extends StatelessWidget {
|
||||||
final List<ChartTaskData> data;
|
final List<ChartTaskData> data;
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:marco/helpers/utils/mixins/ui_mixin.dart';
|
import 'package:on_field_work/helpers/utils/mixins/ui_mixin.dart';
|
||||||
import 'package:marco/helpers/utils/utils.dart';
|
import 'package:on_field_work/helpers/utils/utils.dart';
|
||||||
import 'package:marco/helpers/widgets/my_text.dart';
|
import 'package:on_field_work/helpers/widgets/my_text.dart';
|
||||||
|
|
||||||
typedef OnDateRangeSelected = void Function(DateTime? start, DateTime? end);
|
typedef OnDateRangeSelected = void Function(DateTime? start, DateTime? end);
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user