diff --git a/assets/images/support.png b/assets/images/support.png new file mode 100644 index 0000000..601ffcb Binary files /dev/null and b/assets/images/support.png differ diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 54d4934..ee021ee 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -525,5 +525,18 @@ "fakeLocation": ".لقد تتبعنا أنك تحاول استخدام موقع مزيف! يعتبر هذا مخالفة وقد تم إخطار الموارد البشرية", "noWinner": "حزين! لم يفز أحد اليوم.", "myTeam" : "فريقي", - "youCanPlayDemo": "لكن يمكنك لعب العرض" + "youCanPlayDemo": "لكن يمكنك لعب العرض", + "qualification": "مؤهلات", + "esteblishmentName": "اسم المؤسسة", + "gradeDescription": "وصف الصف", + "type": "يكتب", + "status": "حالة", + "leaveType": "نوع الإجازة", + "attendanceType": "نوع الحضور", + "help": "يساعد", + "dear": "عزيزي", + "assistant": "للحصول على المساعدة ، يمكنك تقديم الطلب على نظام سعيد أو الاتصال بمركز الاتصال الموحد على 8310200", + "employee_leaves_calender": "تقويم أوراق الموظفين", + "view_your_leave_information": "عرض معلومات إجازتك", + "view_details": "عرض التفاصيل" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 01572f1..7b01275 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -425,7 +425,7 @@ "typeCurrentPasswordBelow": "Type Your Current password below", "currentPassword": "Current password", "concurrentReports": "Concurrent Reports", - "EnterNewAddressMoved" : "Enter a new address if you have moved", + "EnterNewAddressMoved": "Enter a new address if you have moved", "CorrectAddress": "Correct or amend this address", "SelectChangeWantToMake": "Select the type of change you want to make", "profile": { @@ -470,7 +470,7 @@ "gameTime": "Game Time:", "joinMarathon": "Join Marathon", "joinDemoMarathon": "Join Demo Marathon", - "demo":"Demo", + "demo": "Demo", "minutes": "Minutes", "seconds": "Seconds", "note": "Note:", @@ -518,12 +518,26 @@ "startingIn": "Starting in", "youAreOutOfContest": "You are out of the contest.", "winners": "WINNERS!!!", - "expireAfter":"Expires After", - "oneWeek":"1 Week", - "twoWeek":"2 Week", + "expireAfter": "Expires After", + "oneWeek": "1 Week", + "twoWeek": "2 Week", "noUpcoming": "There is no upcoming", "fakeLocation": "We traced out that you try to use a fake location! This is considered a violation, and HR has been notified.", "noWinner": "Sad! No one won today.", - "myTeam" : "My Team", - "youCanPlayDemo": "But you can play demo" + "myTeam": "My Team", + "youCanPlayDemo": "But you can play demo", + "qualification": "Qualifications", + "esteblishmentName": "Establishment Name", + "gradeDescription": "Grade Description", + "type": "Type", + "status": "Status", + "leaveType": "Leave Type", + "attendanceType": "Attendance Type", + "help": "Help", + "dear": "Dear", + "assistant": "For assistance, you can submit the request on the Saeed system or call the unified call center on 8310200", + "employee_leaves_calender": "Employee Leaves Calender", + "view_your_leave_information": "View Your Leave Information", + "view_details": "View Details" + } \ No newline at end of file diff --git a/lib/api/login_api_client.dart b/lib/api/login_api_client.dart index 0d12d72..e655906 100644 --- a/lib/api/login_api_client.dart +++ b/lib/api/login_api_client.dart @@ -90,7 +90,8 @@ class LoginApiClient { AppState().postParamsObject?.pUserName = AppState().getUserName; //TODO: employee id changed in SRCA instead of username // AppState().postParamsObject?.pSelectedEmployeeNumber = AppState().getUserName; - AppState().postParamsObject?.pSelectedEmployeeNumber = responseData.memberInformationList!.first.aSSIGNMENTNUMBER; + //TODO: need to fix emp number + AppState().postParamsObject?.pSelectedEmployeeNumber = responseData.memberInformationList!.first.eMPLOYEENUMBER; AppState().postParamsObject?.setPLegislationCode = responseData.basicMemberInformation!.pLEGISLATIONCODE; AppState().postParamsObject?.setPayrollCodeStr = responseData.memberInformationList!.first.pAYROLLCODE; AppState().setBusinessCardPrivilege = responseData.businessCardPrivilege ?? false; diff --git a/lib/api/monthly_attendance_api_client.dart b/lib/api/monthly_attendance_api_client.dart index e462373..ed01ba9 100644 --- a/lib/api/monthly_attendance_api_client.dart +++ b/lib/api/monthly_attendance_api_client.dart @@ -1,14 +1,13 @@ - import 'dart:async'; +import 'package:mohem_flutter_app/api/api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/consts.dart'; +import 'package:mohem_flutter_app/models/employee_leaves_list.dart'; import 'package:mohem_flutter_app/models/generic_response_model.dart'; import 'package:mohem_flutter_app/models/get_day_hours_type_details_list_model.dart'; -import 'package:mohem_flutter_app/models/get_mobile_login_info_list_model.dart'; import 'package:mohem_flutter_app/models/get_schedule_shifts_details_list_model.dart'; import 'package:mohem_flutter_app/models/get_time_card_summary_list_model.dart'; -import 'package:mohem_flutter_app/api/api_client.dart'; class MonthlyAttendanceApiClient { static final MonthlyAttendanceApiClient _instance = MonthlyAttendanceApiClient._internal(); @@ -52,6 +51,24 @@ class MonthlyAttendanceApiClient { }, url, postParams); } + Future> getEmployeeLeaves(String startDate, String endDate) async { + // String url = "${ApiConsts.erpRest}GET_TIME_CARD_SUMMARY"; + String url = "${ApiConsts.erpRest}GET_EMPLOYEE_LEAVES"; + Map postParams = { + "P_MENU_TYPE": "E", + "P_SELECTED_RESP_ID": -999, + // "SearchMonth": month, + // "SearchYear": year, + "P_DATE_FROM_STR": startDate, + "P_DATE_TO_STR": endDate + }; + + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel? responseData = GenericResponseModel.fromJson(json); + return responseData.getEmployeeLeavesList ?? []; + }, url, postParams); + } Future getScheduleShiftsDetails(int pRTPID) async { String url = "${ApiConsts.erpRest}GET_SCHEDULE_SHIFTS_DETAILS"; @@ -66,5 +83,4 @@ class MonthlyAttendanceApiClient { return (responseData.getScheduleShiftsDetailsList?.length ?? 0) > 0 ? responseData.getScheduleShiftsDetailsList!.first : null; }, url, postParams); } - -} \ No newline at end of file +} diff --git a/lib/api/profile_api_client.dart b/lib/api/profile_api_client.dart index 6a8cfb0..4620376 100644 --- a/lib/api/profile_api_client.dart +++ b/lib/api/profile_api_client.dart @@ -12,8 +12,10 @@ import 'package:mohem_flutter_app/models/get_employee_address_model.dart'; import 'package:mohem_flutter_app/models/get_employee_basic_details.model.dart'; import 'package:mohem_flutter_app/models/get_employee_contacts.model.dart'; import 'package:mohem_flutter_app/models/get_employee_phones_model.dart'; +import 'package:mohem_flutter_app/models/hierarchy_lists.dart'; import 'package:mohem_flutter_app/models/performance.dart'; import 'package:mohem_flutter_app/models/profile/basic_details_dff_structure.dart'; +import 'package:mohem_flutter_app/models/profile/employee_qualifications_list.dart'; import 'package:mohem_flutter_app/models/profile/get_contact_clos_structure_list.dart'; import 'package:mohem_flutter_app/models/profile/get_contact_details_list.dart'; import 'package:mohem_flutter_app/models/profile/get_countries_list_model.dart'; @@ -58,6 +60,19 @@ class ProfileApiClient { }, url, postParams); } + Future> getEmployeeQualifications() async { + String url = "${ApiConsts.erpRest}GET_EMPLOYEE_QUALIFICATIONS"; + Map postParams = { + "P_MENU_TYPE": "E", + "P_SELECTED_RESP_ID": -999, + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel? responseData = GenericResponseModel.fromJson(json); + return responseData.getEmployeeQualificationsList ?? []; + }, url, postParams); + } + Future> getEmployeePhones() async { String url = "${ApiConsts.erpRest}GET_EMPLOYEE_PHONES"; Map postParams = { @@ -403,4 +418,19 @@ class ProfileApiClient { return responseData.getPerformanceAppraisalList ?? []; }, url, postParams); } + + Future getHierarchy(String empNum) async { + String url = "${ApiConsts.erpRest}GET_SUPERVISOR_HIERARCHY"; + Map postParams = { + "P_MENU_TYPE": "E", + "P_SELECTED_RESP_ID": -999 + }; + + postParams.addAll(AppState().postParamsJson); + postParams["P_SELECTED_EMPLOYEE_NUMBER"] = empNum; + return await ApiClient().postJsonForObject((json) { + GenericResponseModel? responseData = GenericResponseModel.fromJson(json); + return responseData.supervisorHierarchyLists; + }, url, postParams); + } } diff --git a/lib/config/env.dart b/lib/config/env.dart index 38fa108..26a0ce6 100644 --- a/lib/config/env.dart +++ b/lib/config/env.dart @@ -30,7 +30,7 @@ Map _env = { "myProfile": false, "itemsForSale": false, "chat": false, - "monthlyAttendance": false, + "monthlyAttendance": true, "vocationRules": false, "canEdit": false, }; diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 947bbcd..9669515 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/ui/app_update_screen.dart'; import 'package:mohem_flutter_app/ui/attendance/add_vacation_rule_screen.dart'; +import 'package:mohem_flutter_app/ui/attendance/moe_monthly_attendance_screen.dart'; import 'package:mohem_flutter_app/ui/attendance/monthly_attendance_screen.dart'; import 'package:mohem_flutter_app/ui/attendance/vacation_rule_screen.dart'; import 'package:mohem_flutter_app/ui/bottom_sheets/attendence_details_bottom_sheet.dart'; @@ -45,6 +46,8 @@ import 'package:mohem_flutter_app/ui/profile/delete_family_member.dart'; import 'package:mohem_flutter_app/ui/profile/dynamic_screens/dynamic_input_address_screen.dart'; import 'package:mohem_flutter_app/ui/profile/dynamic_screens/dynamic_input_basic_details_screen.dart'; import 'package:mohem_flutter_app/ui/profile/family_members.dart'; +import 'package:mohem_flutter_app/ui/profile/help_screen.dart'; +import 'package:mohem_flutter_app/ui/profile/hierarchy_screen.dart'; import 'package:mohem_flutter_app/ui/profile/personal_info.dart'; import 'package:mohem_flutter_app/ui/profile/profile_screen.dart'; import 'package:mohem_flutter_app/ui/screens/announcements/announcement_details.dart'; @@ -192,6 +195,8 @@ class AppRoutes { static const String unsafeDeviceScreen = "/unsafeDeviceScreen"; static const String appUpdateScreen = "/appUpdateScreen"; + static const String help = "/help"; + static const String hierarchy = "/hierarchy"; static final Map routes = { login: (BuildContext context) => LoginScreen(), @@ -226,7 +231,8 @@ class AppRoutes { // addWorkFromHome: (BuildContext context) => AddWorkFromHomeScreen(), profile: (BuildContext context) => ProfileScreen(), //Attendance - monthlyAttendance: (BuildContext context) => MonthlyAttendanceScreen(), + // monthlyAttendance: (BuildContext context) => MonthlyAttendanceScreen(), + monthlyAttendance: (BuildContext context) => MoeMonthlyAttendanceScreen(), vacationRule: (BuildContext context) => VacationRuleScreen(), addVacationRule: (BuildContext context) => AddVacationRuleScreen(), @@ -303,5 +309,7 @@ class AppRoutes { unsafeDeviceScreen: (BuildContext context) => const UnsafeDeviceScreen(), appUpdateScreen: (BuildContext context) => const AppUpdateScreen(), + help: (BuildContext context) => HelpScreen(), + hierarchy: (BuildContext context) => HierarchyScreen(), }; } diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index 54ffe20..91c75e4 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -114,6 +114,7 @@ extension EmailValidator on String { Widget toText16({Color? color, bool isUnderLine = false, bool isBold = false, int? maxlines, double? height}) => Text( this, maxLines: maxlines, + overflow: TextOverflow.ellipsis, style: TextStyle( color: color ?? MyColors.darkTextColor, fontSize: 16, diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index 5ec13c6..a800ab5 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -541,7 +541,17 @@ class CodegenLoader extends AssetLoader{ "fakeLocation": ".لقد تتبعنا أنك تحاول استخدام موقع مزيف! يعتبر هذا مخالفة وقد تم إخطار الموارد البشرية", "noWinner": "حزين! لم يفز أحد اليوم.", "myTeam": "فريقي", - "youCanPlayDemo": "لكن يمكنك لعب العرض" + "youCanPlayDemo": "لكن يمكنك لعب العرض", + "qualification": "مؤهلات", + "esteblishmentName": "اسم المؤسسة", + "gradeDescription": "وصف الصف", + "type": "يكتب", + "status": "حالة", + "leaveType": "نوع الإجازة", + "attendanceType": "نوع الحضور", + "help": "يساعد", + "dear": "عزيزي", + "assistant": "للحصول على المساعدة ، يمكنك تقديم الطلب على نظام سعيد أو الاتصال بمركز الاتصال الموحد على 8310200" }; static const Map en_US = { "mohemm": "Mohemm", @@ -1070,7 +1080,17 @@ static const Map en_US = { "fakeLocation": "We traced out that you try to use a fake location! This is considered a violation, and HR has been notified.", "noWinner": "Sad! No one won today.", "myTeam": "My Team", - "youCanPlayDemo": "But you can play demo" + "youCanPlayDemo": "But you can play demo", + "qualification": "Qualifications", + "esteblishmentName": "Establishment Name", + "gradeDescription": "Grade Description", + "type": "Type", + "status": "Status", + "leaveType": "Leave Type", + "attendanceType": "Attendance Type", + "help": "Help", + "dear": "Dear", + "assistant": "For assistance, you can submit the request on the Saeed system or call the unified call center on 8310200" }; static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 9b00334..3aab5c7 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -512,5 +512,18 @@ abstract class LocaleKeys { static const noWinner = 'noWinner'; static const myTeam = 'myTeam'; static const youCanPlayDemo = 'youCanPlayDemo'; + static const qualification = 'qualification'; + static const esteblishmentName = 'esteblishmentName'; + static const gradeDescription = 'gradeDescription'; + static const type = 'type'; + static const status = 'status'; + static const leaveType = 'leaveType'; + static const attendanceType = 'attendanceType'; + static const help = 'help'; + static const dear = 'dear'; + static const assistant = 'assistant'; + static const employee_leaves_calender = 'employee_leaves_calender'; + static const view_your_leave_information = 'view_your_leave_information'; + static const view_details = 'view_details'; } diff --git a/lib/models/employee_leaves_list.dart b/lib/models/employee_leaves_list.dart new file mode 100644 index 0000000..d42bc06 --- /dev/null +++ b/lib/models/employee_leaves_list.dart @@ -0,0 +1,45 @@ +// To parse this JSON data, do +// +// final employeeLeavesList = employeeLeavesListFromJson(jsonString); + +import 'dart:convert'; + +EmployeeLeavesList employeeLeavesListFromJson(String str) => EmployeeLeavesList.fromJson(json.decode(str)); + +String employeeLeavesListToJson(EmployeeLeavesList data) => json.encode(data.toJson()); + +class EmployeeLeavesList { + EmployeeLeavesList({ + this.absenceAttendanceTypeName, + this.dateEnd, + this.dateStart, + this.eventDate, + this.holidayType, + this.leaveType, + }); + + String? absenceAttendanceTypeName; + String? dateEnd; + String? dateStart; + String? eventDate; + String? holidayType; + String? leaveType; + + factory EmployeeLeavesList.fromJson(Map json) => EmployeeLeavesList( + absenceAttendanceTypeName: json["ABSENCE_ATTENDANCE_TYPE_NAME"], + dateEnd: json["DATE_END"], + dateStart: json["DATE_START"], + eventDate: json["EVENT_DATE"], + holidayType: json["HOLIDAY_TYPE"], + leaveType: json["LEAVE_TYPE"], + ); + + Map toJson() => { + "ABSENCE_ATTENDANCE_TYPE_NAME": absenceAttendanceTypeName, + "DATE_END": dateEnd, + "DATE_START": dateStart, + "EVENT_DATE": eventDate, + "HOLIDAY_TYPE": holidayType, + "LEAVE_TYPE": leaveType, + }; +} diff --git a/lib/models/generic_response_model.dart b/lib/models/generic_response_model.dart index ed00de4..c367d86 100644 --- a/lib/models/generic_response_model.dart +++ b/lib/models/generic_response_model.dart @@ -8,6 +8,7 @@ import 'package:mohem_flutter_app/models/dashboard/get_open_notifications_list.d import 'package:mohem_flutter_app/models/dashboard/list_menu.dart'; import 'package:mohem_flutter_app/models/dashboard/menu_entries.dart'; import 'package:mohem_flutter_app/models/dashboard/mohemm_itg_pending_task_responseitem.dart'; +import 'package:mohem_flutter_app/models/employee_leaves_list.dart'; import 'package:mohem_flutter_app/models/get_absence_collection_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_action_history_list_model.dart'; import 'package:mohem_flutter_app/models/get_approves_list_model.dart'; @@ -35,6 +36,7 @@ import 'package:mohem_flutter_app/models/get_stamp_ms_notification_body_list_mod import 'package:mohem_flutter_app/models/get_stamp_ns_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_time_card_summary_list_model.dart'; import 'package:mohem_flutter_app/models/get_user_item_type_list.dart'; +import 'package:mohem_flutter_app/models/hierarchy_lists.dart'; import 'package:mohem_flutter_app/models/leave_balance/calculate_absence_duration_model.dart'; import 'package:mohem_flutter_app/models/leave_balance/cancel_hr_transaction_list_model.dart'; import 'package:mohem_flutter_app/models/leave_balance/get_absence_attendance_types_list_model.dart'; @@ -73,6 +75,7 @@ import 'package:mohem_flutter_app/models/performance.dart'; import 'package:mohem_flutter_app/models/privilege_list_model.dart'; import 'package:mohem_flutter_app/models/profile/basic_details_cols_structions.dart'; import 'package:mohem_flutter_app/models/profile/basic_details_dff_structure.dart'; +import 'package:mohem_flutter_app/models/profile/employee_qualifications_list.dart'; import 'package:mohem_flutter_app/models/profile/get_address_dff_structure_list.dart'; import 'package:mohem_flutter_app/models/profile/get_contact_clos_structure_list.dart'; import 'package:mohem_flutter_app/models/profile/get_contact_details_list.dart'; @@ -196,6 +199,7 @@ class GenericResponseModel { List? getEmployeeBasicDetailsList; List? getEmployeeContactsList; List? getEmployeePhonesList; + List? getEmployeeQualificationsList; List? getEmployeeSubordinatesList; List? getFliexfieldStructureList; List? getHrCollectionNotificationBodyList; @@ -249,6 +253,7 @@ class GenericResponseModel { List? getTermDffStructureList; List? getTermNotificationBodyList; List? getTimeCardSummaryList; + List? getEmployeeLeavesList; List? getTicketsByEmployeeList; List? getTicketDetailsByEmployee; List? getTicketTransactions; @@ -378,269 +383,274 @@ class GenericResponseModel { String? ePharmacyGetItemOnHandList; bool? isActiveCode; bool? isSMSSent; - - GenericResponseModel( - {this.date, - this.languageID, - this.serviceName, - this.time, - this.androidLink, - this.authenticationTokenID, - this.data, - this.dataw, - this.dietType, - this.dietTypeID, - this.errorCode, - this.errorEndUserMessage, - this.errorEndUserMessageN, - this.errorMessage, - this.errorType, - this.foodCategory, - this.iOSLink, - this.isAuthenticated, - this.mealOrderStatus, - this.mealType, - this.messageStatus, - this.numberOfResultRecords, - this.patientBlodType, - this.successMsg, - this.successMsgN, - this.vidaUpdatedResponse, - this.addAttSuccessList, - this.addAttachmentList, - this.bCDomain, - this.bCLogo, - this.basicMemberInformation, - this.businessCardPrivilege, - this.calculateAbsenceDuration, - this.cancelHRTransactionLIst, - this.chatEmployeeLoginList, - this.companyBadge, - this.companyImage, - this.companyImageDescription, - this.companyImageURL, - this.companyMainCompany, - this.countryList, - this.createVacationRuleList, - this.deleteAttachmentList, - this.deleteVacationRuleList, - this.disableSessionList, - this.employeeQR, - this.forgetPasswordTokenID, - this.getAbsenceAttachmentsList, - this.getAbsenceAttendanceTypesList, - this.getAbsenceCollectionNotificationBodyList, - this.getAbsenceDffStructureList, - this.getAbsenceTransactionList, - this.getAccrualBalancesList, - this.getActionHistoryList, - this.getAddressDffStructureList, - this.getAddressNotificationBodyList, - this.getApprovesList, - this.getAttachementList, - this.getAttendanceTrackingList, - this.getBasicDetColsStructureList, - this.getBasicDetDffStructureList, - this.getBasicDetNtfBodyList, - this.getCEICollectionNotificationBodyList, - this.getCEIDFFStructureList, - this.getCEITransactionList, - this.getCcpTransactionsList, - this.getCcpTransactionsListNew, - this.getConcurrentProgramsList, - this.getContactColsStructureList, - this.getContactDetailsList, - this.getContactDffStructureList, - this.getContactNotificationBodyList, - this.getCountriesList, - this.getDayHoursTypeDetailsList, - this.getDeductionsList, - this.getDefaultValueList, - this.getEITCollectionNotificationBodyList, - this.getEITDFFStructureList, - this.getEITTransactionList, - this.getEarningsList, - this.getEmployeeAddressList, - this.getEmployeeBasicDetailsList, - this.getEmployeeContactsList, - this.getEmployeePhonesList, - this.getEmployeeSubordinatesList, - this.getFliexfieldStructureList, - this.getHrCollectionNotificationBodyList, - this.getHrTransactionList, - this.getItemCreationNtfBodyList, - this.getItemTypeNotificationsList, - this.getItemTypesList, - this.getLookupValuesList, - this.getMenuEntriesList, - this.getMoItemHistoryList, - this.getMoNotificationBodyList, - this.getNotificationButtonsList, - this.getNotificationReassignModeList, - this.getObjectValuesList, - this.getOpenMissingSwipesList, - this.getOpenNotificationsList, - this.getOpenNotificationsNumList, - this.getOpenPeriodDatesList, - this.getOrganizationsSalariesList, - this.getPaymentInformationList, - this.getPayslipList, - this.getPerformanceAppraisalList, - this.getPhonesNotificationBodyList, - this.getPoItemHistoryList, - this.getPoNotificationBodyList, - this.getPrNotificationBodyList, - this.getQuotationAnalysisList, - this.getRFCEmployeeListList, - this.getRespondAttributeValueList, - this.getSITCollectionNotificationBodyList, - this.getSITDFFStructureList, - this.getSITTransactionList, - this.getScheduleShiftsDetailsList, - this.getShiftTypesList, - this.getStampMsNotificationBodyList, - this.getStampNsNotificationBodyList, - this.getSubordinatesAttdStatusList, - this.getSubordinatesLeavesList, - this.getSubordinatesLeavesTotalVacationsList, - this.getSummaryOfPaymentList, - this.getSwipesList, - this.getTermColsStructureList, - this.getTermDffStructureList, - this.getTermNotificationBodyList, - this.getTimeCardSummaryList, - this.getTicketsByEmployeeList, - this.getTicketDetailsByEmployee, - this.getTicketTransactions, - this.getTicketTypes, - this.getSectionTopics, - this.getMowadhafhiProjects, - this.getProjectDepartments, - this.getDepartmentSections, - this.getPendingTransactionsFunctions, - this.getPendingTransactionsDetails, - this.getConcurrentProgramsModel, - this.getCCPTransactionsModel, - this.getCCPOutputModel, - this.getCCPDFFStructureModel, - this.getUserItemTypesList, - this.getVacationRulesList, - this.getVaccinationOnHandList, - this.getVaccinationsList, - this.getValueSetValuesList, - this.getWorkList, - this.hRCertificateTemplate, - this.imgURLsList, - this.insertApInv, - this.insertBooked, - this.insertEmpSwipesList, - this.insertJournal, - this.insertOrders, - this.intPortalGetEmployeeList, - this.isDeviceTokenEmpty, - this.isPasswordExpired, - this.isRegisterAllowed, - this.isRequriedValueSetEmpty, - this.isUserSMSExcluded, - this.itemOnHand, - this.languageAvailable, - this.listSupplier, - this.listUserAgreement, - this.listEITStrucrure, - this.listItemImagesDetails, - this.listItemMaster, - this.listMedicineDetails, - this.listMenu, - this.listNewEmployees, - this.listRadScreen, - this.logInTokenID, - this.memberInformationList, - this.memberLoginList, - this.mohemmGetBusinessCardEnabledList, - this.mohemmGetFavoriteReplacementsList, - this.mohemmGetMobileDeviceInfobyEmpInfoList, - this.mohemmGetMobileLoginInfoList, - this.mohemmGetPatientIDList, - this.mohemmITGResponseItem, - this.mohemmIsChangeIsActiveBusinessCardEnable, - this.mohemmIsInsertBusinessCardEnable, - this.mohemmWifiPassword, - this.mohemmWifiSSID, - this.notificationAction, - this.notificationGetRespondAttributesList, - this.notificationRespondRolesList, - this.oracleOutPutNumber, - this.pASSWORDEXPIREDMSG, - this.pCOUNTRYCODE, - this.pCOUNTRYNAME, - this.pDESCFLEXCONTEXTCODE, - this.pDESCFLEXCONTEXTNAME, - this.pForm, - this.pINFORMATION, - this.pMBLID, - this.pNUMOFSUBORDINATES, - this.pOPENNTFNUMBER, - this.pQUESTION, - this.pSESSIONID, - this.pSchema, - this.pharmacyStockAddPharmacyStockList, - this.pharmacyStockGetOnHandList, - this.privilegeList, - this.processTransactions, - this.registerUserNameList, - this.replacementList, - this.respondAttributesList, - this.respondRolesList, - this.resubmitAbsenceTransactionList, - this.resubmitEITTransactionList, - this.resubmitHrTransactionList, - this.sFHGetPoNotificationBodyList, - this.sFHGetPrNotificationBodyList, - this.startAbsenceApprovalProccess, - this.startAddressApprovalProcessList, - this.startBasicDetApprProcessList, - this.startCeiApprovalProcess, - this.startContactApprovalProcessList, - this.startEitApprovalProcess, - this.startHrApprovalProcessList, - this.startPhonesApprovalProcessList, - this.startSitApprovalProcess, - this.startTermApprovalProcessList, - this.submitAddressTransactionList, - this.submitBasicDetTransactionList, - this.submitCEITransactionList, - this.submitCcpTransactionList, - this.submitContactTransactionList, - this.submitEITTransactionList, - this.submitHrTransactionList, - this.submitPhonesTransactionList, - this.submitSITTransactionList, - this.submitTermTransactionList, - this.subordinatesOnLeavesList, - this.sumbitAbsenceTransactionList, - this.tokenID, - this.updateAttachmentList, - this.updateEmployeeImageList, - this.updateItemTypeSuccessList, - this.updateUserItemTypesList, - this.updateVacationRuleList, - this.vHREmployeeLoginList, - this.vHRGetEmployeeDetailsList, - this.vHRGetManagersDetailsList, - this.vHRGetProjectByCodeList, - this.vHRIsVerificationCodeValid, - this.validateAbsenceTransactionList, - this.validateEITTransactionList, - this.validatePhonesTransactionList, - this.vrItemTypesList, - this.wFLookUpList, - this.eLearningGETEMPLOYEEPROFILEList, - this.eLearningLOGINList, - this.eLearningValidateLoginList, - this.eLearningValidate_LoginList, - this.ePharmacyGetItemOnHandList, - this.isActiveCode, - this.isSMSSent}); + SupervisorHierarchyLists? supervisorHierarchyLists; + + GenericResponseModel({ + this.date, + this.languageID, + this.serviceName, + this.time, + this.androidLink, + this.authenticationTokenID, + this.data, + this.dataw, + this.dietType, + this.dietTypeID, + this.errorCode, + this.errorEndUserMessage, + this.errorEndUserMessageN, + this.errorMessage, + this.errorType, + this.foodCategory, + this.iOSLink, + this.isAuthenticated, + this.mealOrderStatus, + this.mealType, + this.messageStatus, + this.numberOfResultRecords, + this.patientBlodType, + this.successMsg, + this.successMsgN, + this.vidaUpdatedResponse, + this.addAttSuccessList, + this.addAttachmentList, + this.bCDomain, + this.bCLogo, + this.basicMemberInformation, + this.businessCardPrivilege, + this.calculateAbsenceDuration, + this.cancelHRTransactionLIst, + this.chatEmployeeLoginList, + this.companyBadge, + this.companyImage, + this.companyImageDescription, + this.companyImageURL, + this.companyMainCompany, + this.countryList, + this.createVacationRuleList, + this.deleteAttachmentList, + this.deleteVacationRuleList, + this.disableSessionList, + this.employeeQR, + this.forgetPasswordTokenID, + this.getAbsenceAttachmentsList, + this.getAbsenceAttendanceTypesList, + this.getAbsenceCollectionNotificationBodyList, + this.getAbsenceDffStructureList, + this.getAbsenceTransactionList, + this.getAccrualBalancesList, + this.getActionHistoryList, + this.getAddressDffStructureList, + this.getAddressNotificationBodyList, + this.getApprovesList, + this.getAttachementList, + this.getAttendanceTrackingList, + this.getBasicDetColsStructureList, + this.getBasicDetDffStructureList, + this.getBasicDetNtfBodyList, + this.getCEICollectionNotificationBodyList, + this.getCEIDFFStructureList, + this.getCEITransactionList, + this.getCcpTransactionsList, + this.getCcpTransactionsListNew, + this.getConcurrentProgramsList, + this.getContactColsStructureList, + this.getContactDetailsList, + this.getContactDffStructureList, + this.getContactNotificationBodyList, + this.getCountriesList, + this.getDayHoursTypeDetailsList, + this.getDeductionsList, + this.getDefaultValueList, + this.getEITCollectionNotificationBodyList, + this.getEITDFFStructureList, + this.getEITTransactionList, + this.getEarningsList, + this.getEmployeeAddressList, + this.getEmployeeBasicDetailsList, + this.getEmployeeContactsList, + this.getEmployeePhonesList, + this.getEmployeeQualificationsList, + this.getEmployeeSubordinatesList, + this.getFliexfieldStructureList, + this.getHrCollectionNotificationBodyList, + this.getHrTransactionList, + this.getItemCreationNtfBodyList, + this.getItemTypeNotificationsList, + this.getItemTypesList, + this.getLookupValuesList, + this.getMenuEntriesList, + this.getMoItemHistoryList, + this.getMoNotificationBodyList, + this.getNotificationButtonsList, + this.getNotificationReassignModeList, + this.getObjectValuesList, + this.getOpenMissingSwipesList, + this.getOpenNotificationsList, + this.getOpenNotificationsNumList, + this.getOpenPeriodDatesList, + this.getOrganizationsSalariesList, + this.getPaymentInformationList, + this.getPayslipList, + this.getPerformanceAppraisalList, + this.getPhonesNotificationBodyList, + this.getPoItemHistoryList, + this.getPoNotificationBodyList, + this.getPrNotificationBodyList, + this.getQuotationAnalysisList, + this.getRFCEmployeeListList, + this.getRespondAttributeValueList, + this.getSITCollectionNotificationBodyList, + this.getSITDFFStructureList, + this.getSITTransactionList, + this.getScheduleShiftsDetailsList, + this.getShiftTypesList, + this.getStampMsNotificationBodyList, + this.getStampNsNotificationBodyList, + this.getSubordinatesAttdStatusList, + this.getSubordinatesLeavesList, + this.getSubordinatesLeavesTotalVacationsList, + this.getSummaryOfPaymentList, + this.getSwipesList, + this.getTermColsStructureList, + this.getTermDffStructureList, + this.getTermNotificationBodyList, + this.getTimeCardSummaryList, + this.getEmployeeLeavesList, + this.getTicketsByEmployeeList, + this.getTicketDetailsByEmployee, + this.getTicketTransactions, + this.getTicketTypes, + this.getSectionTopics, + this.getMowadhafhiProjects, + this.getProjectDepartments, + this.getDepartmentSections, + this.getPendingTransactionsFunctions, + this.getPendingTransactionsDetails, + this.getConcurrentProgramsModel, + this.getCCPTransactionsModel, + this.getCCPOutputModel, + this.getCCPDFFStructureModel, + this.getUserItemTypesList, + this.getVacationRulesList, + this.getVaccinationOnHandList, + this.getVaccinationsList, + this.getValueSetValuesList, + this.getWorkList, + this.hRCertificateTemplate, + this.imgURLsList, + this.insertApInv, + this.insertBooked, + this.insertEmpSwipesList, + this.insertJournal, + this.insertOrders, + this.intPortalGetEmployeeList, + this.isDeviceTokenEmpty, + this.isPasswordExpired, + this.isRegisterAllowed, + this.isRequriedValueSetEmpty, + this.isUserSMSExcluded, + this.itemOnHand, + this.languageAvailable, + this.listSupplier, + this.listUserAgreement, + this.listEITStrucrure, + this.listItemImagesDetails, + this.listItemMaster, + this.listMedicineDetails, + this.listMenu, + this.listNewEmployees, + this.listRadScreen, + this.logInTokenID, + this.memberInformationList, + this.memberLoginList, + this.mohemmGetBusinessCardEnabledList, + this.mohemmGetFavoriteReplacementsList, + this.mohemmGetMobileDeviceInfobyEmpInfoList, + this.mohemmGetMobileLoginInfoList, + this.mohemmGetPatientIDList, + this.mohemmITGResponseItem, + this.mohemmIsChangeIsActiveBusinessCardEnable, + this.mohemmIsInsertBusinessCardEnable, + this.mohemmWifiPassword, + this.mohemmWifiSSID, + this.notificationAction, + this.notificationGetRespondAttributesList, + this.notificationRespondRolesList, + this.oracleOutPutNumber, + this.pASSWORDEXPIREDMSG, + this.pCOUNTRYCODE, + this.pCOUNTRYNAME, + this.pDESCFLEXCONTEXTCODE, + this.pDESCFLEXCONTEXTNAME, + this.pForm, + this.pINFORMATION, + this.pMBLID, + this.pNUMOFSUBORDINATES, + this.pOPENNTFNUMBER, + this.pQUESTION, + this.pSESSIONID, + this.pSchema, + this.pharmacyStockAddPharmacyStockList, + this.pharmacyStockGetOnHandList, + this.privilegeList, + this.processTransactions, + this.registerUserNameList, + this.replacementList, + this.respondAttributesList, + this.respondRolesList, + this.resubmitAbsenceTransactionList, + this.resubmitEITTransactionList, + this.resubmitHrTransactionList, + this.sFHGetPoNotificationBodyList, + this.sFHGetPrNotificationBodyList, + this.startAbsenceApprovalProccess, + this.startAddressApprovalProcessList, + this.startBasicDetApprProcessList, + this.startCeiApprovalProcess, + this.startContactApprovalProcessList, + this.startEitApprovalProcess, + this.startHrApprovalProcessList, + this.startPhonesApprovalProcessList, + this.startSitApprovalProcess, + this.startTermApprovalProcessList, + this.submitAddressTransactionList, + this.submitBasicDetTransactionList, + this.submitCEITransactionList, + this.submitCcpTransactionList, + this.submitContactTransactionList, + this.submitEITTransactionList, + this.submitHrTransactionList, + this.submitPhonesTransactionList, + this.submitSITTransactionList, + this.submitTermTransactionList, + this.subordinatesOnLeavesList, + this.sumbitAbsenceTransactionList, + this.tokenID, + this.updateAttachmentList, + this.updateEmployeeImageList, + this.updateItemTypeSuccessList, + this.updateUserItemTypesList, + this.updateVacationRuleList, + this.vHREmployeeLoginList, + this.vHRGetEmployeeDetailsList, + this.vHRGetManagersDetailsList, + this.vHRGetProjectByCodeList, + this.vHRIsVerificationCodeValid, + this.validateAbsenceTransactionList, + this.validateEITTransactionList, + this.validatePhonesTransactionList, + this.vrItemTypesList, + this.wFLookUpList, + this.eLearningGETEMPLOYEEPROFILEList, + this.eLearningLOGINList, + this.eLearningValidateLoginList, + this.eLearningValidate_LoginList, + this.ePharmacyGetItemOnHandList, + this.isActiveCode, + this.isSMSSent, + this.supervisorHierarchyLists, + }); GenericResponseModel.fromJson(Map json) { date = json['Date']; @@ -889,6 +899,12 @@ class GenericResponseModel { getEmployeePhonesList!.add(GetEmployeePhonesList.fromJson(v)); }); } + if (json['EmployeeQualificationsList'] != null) { + getEmployeeQualificationsList = []; + json['EmployeeQualificationsList'].forEach((v) { + getEmployeeQualificationsList!.add(EmployeeQualificationsList.fromJson(v)); + }); + } if (json['GetEmployeeSubordinatesList'] != null) { getEmployeeSubordinatesList = []; json['GetEmployeeSubordinatesList'].forEach((v) { @@ -1063,6 +1079,12 @@ class GenericResponseModel { getTimeCardSummaryList!.add(GetTimeCardSummaryList.fromJson(v)); }); } + if (json['EmployeeLeavesList'] != null) { + getEmployeeLeavesList = []; + json['EmployeeLeavesList'].forEach((v) { + getEmployeeLeavesList!.add(EmployeeLeavesList.fromJson(v)); + }); + } if (json['Mohemm_ITG_TicketsByEmployeeList'] != null) { getTicketsByEmployeeList = []; @@ -1291,7 +1313,7 @@ class GenericResponseModel { if (json['RespondRolesList'] != null) { respondRolesList = []; json['RespondRolesList'].forEach((v) { - // respondRolesList!.add(v); + // respondRolesList!.add(v); }); } resubmitAbsenceTransactionList = json['ResubmitAbsenceTransactionList']; @@ -1317,10 +1339,7 @@ class GenericResponseModel { submitAddressTransactionList = json['SubmitAddressTransactionList'] != null ? SubmitAddressTransaction.fromJson(json['SubmitAddressTransactionList']) : null; submitBasicDetTransactionList = json['SubmitBasicDetTransactionList'] != null ? SubmitBasicDetailsTransactionList.fromJson(json['SubmitBasicDetTransactionList']) : null; submitCEITransactionList = json['SubmitCEITransactionList']; - submitCcpTransactionList = json['SubmitCcpTransactionList'] != null - ? new SubmitCcpTransactionList.fromJson( - json['SubmitCcpTransactionList']) - : null; + submitCcpTransactionList = json['SubmitCcpTransactionList'] != null ? new SubmitCcpTransactionList.fromJson(json['SubmitCcpTransactionList']) : null; submitContactTransactionList = json['SubmitContactTransactionList'] != null ? SubmitContactTransactionList.fromJson(json['SubmitContactTransactionList']) : null; submitEITTransactionList = json['SubmitEITTransactionList'] != null ? SubmitEITTransactionList.fromJson(json['SubmitEITTransactionList']) : null; @@ -1380,6 +1399,8 @@ class GenericResponseModel { ePharmacyGetItemOnHandList = json['ePharmacy_GetItemOnHandList']; isActiveCode = json['isActiveCode']; isSMSSent = json['isSMSSent']; + supervisorHierarchyLists= json["SupervisorHierarchyLists"] == null ? null : SupervisorHierarchyLists.fromJson(json["SupervisorHierarchyLists"]); + } Map toJson() { @@ -1541,6 +1562,9 @@ class GenericResponseModel { if (this.getEmployeePhonesList != null) { data['GetEmployeePhonesList'] = this.getEmployeePhonesList!.map((v) => v.toJson()).toList(); } + if (this.getEmployeeQualificationsList != null) { + data['EmployeeQualificationsList'] = this.getEmployeeQualificationsList!.map((v) => v.toJson()).toList(); + } if (this.getEmployeeSubordinatesList != null) { data['GetEmployeeSubordinatesList'] = this.getEmployeeSubordinatesList!.map((v) => v.toJson()).toList(); } @@ -1651,6 +1675,10 @@ class GenericResponseModel { if (this.getTimeCardSummaryList != null) { data['GetTimeCardSummaryList'] = this.getTimeCardSummaryList!.map((v) => v.toJson()).toList(); } + + if (this.getEmployeeLeavesList != null) { + data['EmployeeLeavesList'] = this.getEmployeeLeavesList!.map((v) => v.toJson()).toList(); + } data['GetUserItemTypesList'] = this.getUserItemTypesList; if (this.getVacationRulesList != null) { data['GetVacationRulesList'] = this.getVacationRulesList!.map((v) => v.toJson()).toList(); @@ -1776,8 +1804,7 @@ class GenericResponseModel { data['SubmitCEITransactionList'] = this.submitCEITransactionList; if (this.submitCcpTransactionList != null) { - data['SubmitCcpTransactionList'] = - this.submitCcpTransactionList!.toJson(); + data['SubmitCcpTransactionList'] = this.submitCcpTransactionList!.toJson(); } data['SubmitContactTransactionList'] = this.submitContactTransactionList; @@ -1839,6 +1866,7 @@ class GenericResponseModel { data['ePharmacy_GetItemOnHandList'] = this.ePharmacyGetItemOnHandList; data['isActiveCode'] = this.isActiveCode; data['isSMSSent'] = this.isSMSSent; + data["SupervisorHierarchyLists"]= supervisorHierarchyLists?.toJson(); return data; } } diff --git a/lib/models/hierarchy_lists.dart b/lib/models/hierarchy_lists.dart new file mode 100644 index 0000000..17c1503 --- /dev/null +++ b/lib/models/hierarchy_lists.dart @@ -0,0 +1,71 @@ +class SupervisorHierarchyLists { + SupervisorHierarchyLists({ + this.subordinateHierarchyList, + this.supervisorHierarchyList, + }); + + List? subordinateHierarchyList; + List? supervisorHierarchyList; + + factory SupervisorHierarchyLists.fromJson(Map json) => SupervisorHierarchyLists( + subordinateHierarchyList: json["SubordinateHierarchyList"] == null ? [] : List.from(json["SubordinateHierarchyList"]!.map((x) => HierarchyList.fromJson(x))), + supervisorHierarchyList: json["SupervisorHierarchyList"] == null ? [] : List.from(json["SupervisorHierarchyList"]!.map((x) => HierarchyList.fromJson(x))), + ); + + Map toJson() => { + "SubordinateHierarchyList": subordinateHierarchyList == null ? [] : List.from(subordinateHierarchyList!.map((x) => x.toJson())), + "SupervisorHierarchyList": supervisorHierarchyList == null ? [] : List.from(supervisorHierarchyList!.map((x) => x.toJson())), + }; +} + +class HierarchyList { + HierarchyList({ + this.employeeEmailAddress, + this.employeeImage, + this.employeeMobileNumber, + this.employeeName, + this.employeeNumber, + this.employeeWorkNumber, + this.lvl, + this.numOfSubordinates, + this.organizationName, + this.positionName, + }); + + String? employeeEmailAddress; + dynamic employeeImage; + String? employeeMobileNumber; + String? employeeName; + String? employeeNumber; + String? employeeWorkNumber; + int? lvl; + int? numOfSubordinates; + String? organizationName; + String? positionName; + + factory HierarchyList.fromJson(Map json) => HierarchyList( + employeeEmailAddress: json["EMPLOYEE_EMAIL_ADDRESS"], + employeeImage: json["EMPLOYEE_IMAGE"], + employeeMobileNumber: json["EMPLOYEE_MOBILE_NUMBER"], + employeeName: json["EMPLOYEE_NAME"], + employeeNumber: json["EMPLOYEE_NUMBER"], + employeeWorkNumber: json["EMPLOYEE_WORK_NUMBER"], + lvl: json["LVL"], + numOfSubordinates: json["NUM_OF_SUBORDINATES"], + organizationName: json["ORGANIZATION_NAME"], + positionName: json["POSITION_NAME"], + ); + + Map toJson() => { + "EMPLOYEE_EMAIL_ADDRESS": employeeEmailAddress, + "EMPLOYEE_IMAGE": employeeImage, + "EMPLOYEE_MOBILE_NUMBER": employeeMobileNumber, + "EMPLOYEE_NAME": employeeName, + "EMPLOYEE_NUMBER": employeeNumber, + "EMPLOYEE_WORK_NUMBER": employeeWorkNumber, + "LVL": lvl, + "NUM_OF_SUBORDINATES": numOfSubordinates, + "ORGANIZATION_NAME": organizationName, + "POSITION_NAME": positionName, + }; +} diff --git a/lib/models/profile/employee_qualifications_list.dart b/lib/models/profile/employee_qualifications_list.dart new file mode 100644 index 0000000..d7d5476 --- /dev/null +++ b/lib/models/profile/employee_qualifications_list.dart @@ -0,0 +1,41 @@ +// To parse this JSON data, do +// +// final employeeQualificationsList = employeeQualificationsListFromJson(jsonString); + +import 'dart:convert'; + +EmployeeQualificationsList employeeQualificationsListFromJson(String str) => EmployeeQualificationsList.fromJson(json.decode(str)); + +String employeeQualificationsListToJson(EmployeeQualificationsList data) => json.encode(data.toJson()); + +class EmployeeQualificationsList { + EmployeeQualificationsList({ + this.establishment, + this.grade, + this.gradeDescription, + this.qualificationType, + this.status, + }); + + String? establishment; + String? grade; + String? gradeDescription; + String? qualificationType; + String? status; + + factory EmployeeQualificationsList.fromJson(Map json) => EmployeeQualificationsList( + establishment: json["ESTABLISHMENT"], + grade: json["GRADE"], + gradeDescription: json["GRADE_DESCRIPTION"], + qualificationType: json["QUALIFICATION_TYPE"], + status: json["STATUS"], + ); + + Map toJson() => { + "ESTABLISHMENT": establishment, + "GRADE": grade, + "GRADE_DESCRIPTION": gradeDescription, + "QUALIFICATION_TYPE": qualificationType, + "STATUS": status, + }; +} diff --git a/lib/ui/attendance/moe_monthly_attendance_screen.dart b/lib/ui/attendance/moe_monthly_attendance_screen.dart new file mode 100644 index 0000000..fef843c --- /dev/null +++ b/lib/ui/attendance/moe_monthly_attendance_screen.dart @@ -0,0 +1,331 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/painting.dart'; +import 'package:flutter_html/flutter_html.dart'; +import 'package:intl/intl.dart'; +import 'package:mohem_flutter_app/api/monthly_attendance_api_client.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/date_uitl.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/employee_leaves_list.dart'; +import 'package:mohem_flutter_app/models/get_day_hours_type_details_list_model.dart'; +import 'package:mohem_flutter_app/models/get_schedule_shifts_details_list_model.dart'; +import 'package:mohem_flutter_app/models/get_time_card_summary_list_model.dart'; +import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; +import 'package:mohem_flutter_app/widgets/circular_step_progress_bar.dart'; +import 'package:month_picker_dialog_2/month_picker_dialog_2.dart'; +import 'package:pie_chart/pie_chart.dart'; +import 'package:syncfusion_flutter_calendar/calendar.dart'; + +enum LeaveType { ABSENCE, BUSINESS_TRIP, HOLIDAY, NORMAL } + +class MoeMonthlyAttendanceScreen extends StatefulWidget { + @override + State createState() => _MoeMonthlyAttendanceScreenState(); +} + +class _MoeMonthlyAttendanceScreenState extends State { + DateTime currentDate = DateTime.now(); + int searchYear = DateTime.now().year; + final CalendarController _calendarController = CalendarController(); + + List employeeLeavesList = []; + + @override + void initState() { + super.initState(); + getLeavesData(currentDate); + // callTimeCardAndHourDetails(date.day, searchMonth, searchYear); + } + + void getLeavesData(DateTime date) async { + try { + Utils.showLoading(context); + String startDate = '${date.year}-${date.month}-${date.day}'; + int lastday = DateTime(date.year, date.month + 1, 0).day; + String endDate = '${date.year}-${date.month}-$lastday'; + employeeLeavesList = await MonthlyAttendanceApiClient().getEmployeeLeaves(startDate, endDate); + Utils.hideLoading(context); + _calendarController.displayDate = date; + setState(() {}); + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBarWidget( + context, + // title: LocaleKeys.mowadhafhiRequest.tr(), + title: "", + // showHomeButton: true, + ), + body: ListView( + scrollDirection: Axis.vertical, + children: [ + Column( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.attendance.tr().toText24(isBold: true, color: MyColors.grey3AColor), + Row( + children: [ + "${DateFormat("MMMM-yyyy").format(currentDate)}".toText16(color: MyColors.greyACColor), + const Icon(Icons.keyboard_arrow_down_rounded, color: MyColors.greyACColor), + ], + ).onPress(() async { + showMonthPicker( + context: context, + //locale: EasyLocalization.of(context)?.locale, + initialDate: currentDate, + firstDate: DateTime(searchYear - 2), + lastDate: DateTime.now(), + confirmText: Text(LocaleKeys.confirm.tr()), + cancelText: Text(LocaleKeys.cancel.tr()), + ).then((selectedDate) { + if (selectedDate != null) { + getLeavesData(selectedDate); + setState(() { + currentDate = selectedDate; + }); + } + }); + }), + 18.height, + AspectRatio(aspectRatio: 304 / 244, child: calendarWidget()), + ], + ).paddingOnly(left: 21, right: 21, top: 21), + ], + ), + ], + ), + ); + } + + Widget calendarWidget() { + return SfCalendar( + view: CalendarView.month, + showDatePickerButton: false, + controller: _calendarController, + backgroundColor: Colors.white, + headerHeight: 0, + viewNavigationMode: ViewNavigationMode.none, + todayHighlightColor: MyColors.grey3AColor, + showNavigationArrow: false, + showCurrentTimeIndicator: false, + showWeekNumber: false, + cellBorderColor: Colors.white, + onTap: (v) { + dynamic index = v.date?.day; + if (index != null) { + index = index - 1; + } + EmployeeLeavesList leaves = employeeLeavesList[index]; + if (leaves.leaveType != LeaveType.NORMAL.name) { + showModalBottomSheet( + context: context, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(25.0), + topRight: Radius.circular(25.0), + )), + isScrollControlled: true, + backgroundColor: MyColors.white, + builder: (_) { + return DraggableScrollableSheet( + maxChildSize: 0.75, + expand: false, + initialChildSize: 0.75, + builder: (_, controller) { + return Column( + children: [ + Container( + width: 49, + height: 7, + margin: const EdgeInsets.symmetric(vertical: 10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(25), + color: MyColors.darkGreyColor, + ), + ), + 16.height, + Container( + padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 40), + margin: const EdgeInsets.only(left: 20, right: 20), + decoration: BoxDecoration( + border: Border.all( + color: Colors.black, + ), + borderRadius: BorderRadius.circular(12)), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + DateUtil.getWeekDay(DateUtil.convertStringToDateTime(leaves.eventDate ?? "").weekday).toString().toText14(), + DateUtil.convertStringToDateTime(leaves.eventDate ?? "").day.toString().toText20(), + DateUtil.getMonth(DateUtil.convertStringToDateTime(leaves.eventDate ?? "").month).toString().toText14(), + DateUtil.convertStringToDateTime(leaves.eventDate ?? "").year.toString().toText14(), + ], + ), + ), + 6.height, + showText(LocaleKeys.leaveType.tr(), leaves.leaveType.toString()), + if (leaves.absenceAttendanceTypeName.toString().isNotEmpty) + const Divider( + color: MyColors.borderCEColor, + ), + if (leaves.absenceAttendanceTypeName.toString().isNotEmpty) showText(LocaleKeys.attendanceType.tr(), leaves.absenceAttendanceTypeName.toString()), + const Divider( + color: MyColors.borderCEColor, + ), + showText(LocaleKeys.startDateT.tr(), leaves.dateStart.toString()), + const Divider( + color: MyColors.borderCEColor, + ), + showText(LocaleKeys.endDate.tr(), leaves.dateEnd.toString()), + ], + ); + }, + ); + }, + ); + } + }, + selectionDecoration: BoxDecoration( + border: Border.all(color: MyColors.white, width: 1), + shape: BoxShape.circle, + ), + dataSource: MeetingDataSource(_getDataSource()), + // onTap: calendarTapped, + monthViewSettings: const MonthViewSettings( + dayFormat: 'EEE', + showTrailingAndLeadingDates: false, + showAgenda: false, + ), + viewHeaderStyle: const ViewHeaderStyle( + dayTextStyle: TextStyle(color: MyColors.grey3AColor, fontSize: 13, fontWeight: FontWeight.w600), + ), + monthCellBuilder: (build, details) { + LeaveType leaveType = LeaveType.NORMAL; + for (int i = 0; i < employeeLeavesList.length; i++) { + if (details.date.day == DateUtil.convertSimpleStringDateToDateddMMyyyy(employeeLeavesList[i].eventDate ?? "").day) { + if (employeeLeavesList[i].leaveType == LeaveType.ABSENCE.name) { + leaveType = LeaveType.ABSENCE; + } else if (employeeLeavesList[i].leaveType == LeaveType.BUSINESS_TRIP.name) { + leaveType = LeaveType.BUSINESS_TRIP; + } else if (employeeLeavesList[i].leaveType == LeaveType.HOLIDAY.name) { + leaveType = LeaveType.HOLIDAY; + } + } + } + return Container( + margin: const EdgeInsets.all(4), + decoration: BoxDecoration( + color: leaveType == LeaveType.ABSENCE + ? MyColors.redColor + : leaveType == LeaveType.BUSINESS_TRIP + ? MyColors.gradiantStartColor + : leaveType == LeaveType.HOLIDAY + ? MyColors.gradiantEndColor + : MyColors.white, + shape: BoxShape.circle, + border: Border.all( + color: leaveType == LeaveType.ABSENCE + ? MyColors.redColor + : leaveType == LeaveType.BUSINESS_TRIP + ? MyColors.gradiantStartColor + : leaveType == LeaveType.HOLIDAY + ? MyColors.gradiantEndColor + : MyColors.black, + width: 2, + ), + ), + alignment: Alignment.center, + child: Text( + "${details.date.day}", + style: TextStyle(fontSize: 13, fontWeight: FontWeight.w500, color: leaveType == LeaveType.NORMAL ? MyColors.black : MyColors.white), + ), + ); + }, + ); + } + + List _getDataSource() { + List meetings = []; + return meetings; + } + + Widget showText(String title, String value) { + return Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + value.toText18(color: MyColors.gradiantEndColor, isBold: true), + title.toText14(color: MyColors.greyACColor, isBold: false), + ], + ), + ); + } +} + +class MeetingDataSource extends CalendarDataSource { + MeetingDataSource(List source) { + appointments = source; + } + + @override + DateTime getStartTime(int index) { + return _getMeetingData(index).from; + } + + @override + DateTime getEndTime(int index) { + return _getMeetingData(index).to; + } + + @override + String getSubject(int index) { + return _getMeetingData(index).eventName; + } + + @override + Color getColor(int index) { + return _getMeetingData(index).background; + } + + @override + bool isAllDay(int index) { + return _getMeetingData(index).isAllDay; + } + + Meeting _getMeetingData(int index) { + dynamic meeting = appointments; + Meeting meetingData; + if (meeting is Meeting) { + meetingData = meeting; + } + return meeting; + } +} + +class Meeting { + Meeting(this.eventName, this.from, this.to, this.background, this.isAllDay); + + String eventName; + DateTime from; + DateTime to; + Color background; + bool isAllDay; +} diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index aaa515f..ca3eb69 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -393,6 +393,50 @@ class _DashboardScreenState extends State with WidgetsBindingOb ), ], ).paddingOnly(left: 21, right: 21, top: 7, bottom: 21), + if (env.monthlyAttendance) + InkWell( + child: Container( + width: double.infinity, + padding: EdgeInsets.all(12), + margin: EdgeInsets.symmetric(horizontal: 21), + decoration: const BoxDecoration( + color: MyColors.gradiantStartColor, + borderRadius: BorderRadius.all(Radius.circular(12)), + ), + child: Row( + children: [ + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.employee_leaves_calender.tr().toText18(isBold: true, color: Colors.white), + 2.height, + LocaleKeys.view_your_leave_information.tr().toText12(color: Colors.white), + 8.height, + Container( + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.4), + borderRadius: const BorderRadius.all(Radius.circular(12)), + ), + padding: EdgeInsets.all(8), + child: LocaleKeys.view_details.tr().toText14(color: Colors.white), + ), + ], + ), + ), + const Icon( + Icons.calendar_month, + color: Colors.white, + size: 80, + ), + ], + ), + ), + onTap: () { + Navigator.pushNamed(context, AppRoutes.monthlyAttendance); + }, + ), Visibility( visible: env.offersDiscount, child: Column( @@ -580,6 +624,7 @@ class _DashboardScreenState extends State with WidgetsBindingOb icon: Stack( alignment: Alignment.centerLeft, children: [ + SvgPicture.asset( "assets/icons/chat/chat.svg", color: currentIndex == 4 @@ -651,6 +696,16 @@ class _DashboardScreenState extends State with WidgetsBindingOb Navigator.pushNamed(context, AppRoutes.offersAndDiscountsDetails, arguments: getOffersDetailList); } + } + + + + + + + + + diff --git a/lib/ui/landing/widget/app_drawer.dart b/lib/ui/landing/widget/app_drawer.dart index 2b8e034..5512cf4 100644 --- a/lib/ui/landing/widget/app_drawer.dart +++ b/lib/ui/landing/widget/app_drawer.dart @@ -124,6 +124,12 @@ class _AppDrawerState extends State { // if (AppState().businessCardPrivilege) // menuItem("assets/images/drawer/view_business_card.svg", LocaleKeys.viewBusinessCard.tr(), "", closeDrawer: false, onPress: () => showMDialog(context, child: BusinessCardDialog())), // + menuItem("assets/images/support.png", LocaleKeys.help.tr(), "", closeDrawer: true, onPress: () { + Navigator.pushNamed(context, AppRoutes.help); + }), + menuItem("assets/images/support.png", "Hierarchy", "", closeDrawer: true, onPress: () { + Navigator.pushNamed(context, AppRoutes.hierarchy); + }), menuItem("assets/images/drawer/logout.svg", LocaleKeys.logout.tr(), "", color: MyColors.redA3Color, closeDrawer: false, onPress: performLogout), // menuItem("assets/images/drawer/logout.svg", LocaleKeys.logout.tr(), "", color: MyColors.redA3Color, closeDrawer: false, onPress: () {Navigator.pushNamed(context, AppRoutes.survey,); ], @@ -154,7 +160,8 @@ class _AppDrawerState extends State { Widget menuItem(String icon, String title, String routeName, {Color? color, bool closeDrawer = true, VoidCallback? onPress}) { return Row( children: [ - SvgPicture.asset(icon, height: 20, width: 20), + if (icon.contains("png")) Image.asset(icon, height: 20, width: 20), + if (icon.contains("svg")) SvgPicture.asset(icon, height: 20, width: 20), 9.width, title.toText14(color: color, textAlign: AppState().isArabic(context) ? TextAlign.right : null).expanded, ], diff --git a/lib/ui/landing/widget/services_widget.dart b/lib/ui/landing/widget/services_widget.dart index 926d87b..f023955 100644 --- a/lib/ui/landing/widget/services_widget.dart +++ b/lib/ui/landing/widget/services_widget.dart @@ -277,6 +277,4 @@ class ServicesWidget extends StatelessWidget { ], ); } -} - - +} \ No newline at end of file diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 3bb894d..b9cfce9 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -188,7 +188,10 @@ class _LoginScreenState extends State { if (isAppOpenBySystem == null) { isAppOpenBySystem = (ModalRoute.of(context)!.settings.arguments ?? true) as bool; if (!kReleaseMode) { - username.text = "1100313582"; + // username.text = "1100313582"; + // password.text = "moe123456"; + + username.text = "1002528733"; password.text = "moe123456"; // 1) Normal user : diff --git a/lib/ui/profile/basic_details.dart b/lib/ui/profile/basic_details.dart index 42ecf1d..ff4c904 100644 --- a/lib/ui/profile/basic_details.dart +++ b/lib/ui/profile/basic_details.dart @@ -12,6 +12,7 @@ import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/dashboard/menu_entries.dart'; import 'package:mohem_flutter_app/models/get_employee_basic_details.model.dart'; import 'package:mohem_flutter_app/models/member_information_list_model.dart'; +import 'package:mohem_flutter_app/models/profile/employee_qualifications_list.dart'; import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart'; import 'package:mohem_flutter_app/ui/profile/dynamic_screens/dynamic_input_basic_details_screen.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; @@ -35,6 +36,7 @@ class _BasicDetailsState extends State { String? employeeNo = ""; int correctOrNew = 1; List? getEmployeeBasicDetailsList; + List? getEmployeeQualificationsList; late MemberInformationListModel memberInformationList; GetMenuEntriesList menuEntries = GetMenuEntriesList(); @@ -60,6 +62,7 @@ class _BasicDetailsState extends State { try { Utils.showLoading(context); getEmployeeBasicDetailsList = await ProfileApiClient().getEmployeeBasicDetails(); + getEmployeeQualificationsList = await ProfileApiClient().getEmployeeQualifications(); Utils.hideLoading(context); setState(() {}); } catch (ex) { @@ -87,20 +90,60 @@ class _BasicDetailsState extends State { ? Utils.getNoDataWidget(context) : Column( crossAxisAlignment: CrossAxisAlignment.start, - children: getEmployeeBasicDetailsList! - .map((e) => Column( - children: [ - e.dISPLAYFLAG == "Y" - ? Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - "${e.sEGMENTPROMPT}".toText13(color: MyColors.lightGrayColor), - "${e.sEGMENTVALUEDSP}".toText16(isBold: true, color: MyColors.blackColor), - 12.height - ]) - : Container(), - ], - )) - .toList()) - .objectContainerView()) + children: [ + LocaleKeys.profile_basicDetails.tr().toText20(isBold:true), + 14.height, + ...getEmployeeBasicDetailsList! + .map((e) => Column( + children: [ + e.dISPLAYFLAG == "Y" + ? Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + "${e.sEGMENTPROMPT}".toText13(color: MyColors.lightGrayColor), + "${e.sEGMENTVALUEDSP}".toText16(isBold: true, color: MyColors.blackColor), + 12.height + ]) + : Container(), + ], + )) + .toList() + ]) + .objectContainerView()), + 20.height, + getEmployeeQualificationsList == null + ? const SizedBox() + : (getEmployeeQualificationsList!.isEmpty + ? Utils.getNoDataWidget(context) + : Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.qualification.tr().toText20(isBold:true), + 14.height, + ...getEmployeeQualificationsList! + .map((e) => SizedBox( + width: double.infinity, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocaleKeys.esteblishmentName.tr().toText13(color: MyColors.lightGrayColor), + "${e.establishment}".toText16(isBold: true, color: MyColors.blackColor), + 12.height, + LocaleKeys.grade.tr().toText13(color: MyColors.lightGrayColor), + "${e.grade}".toText16(isBold: true, color: MyColors.blackColor), + 12.height, + LocaleKeys.gradeDescription.tr().toText13(color: MyColors.lightGrayColor), + "${e.gradeDescription}".toText16(isBold: true, color: MyColors.blackColor), + 12.height, + LocaleKeys.type.tr().toText13(color: MyColors.lightGrayColor), + "${e.qualificationType}".toText16(isBold: true, color: MyColors.blackColor), + 12.height, + LocaleKeys.status.tr().toText13(color: MyColors.lightGrayColor), + "${e.status}".toText16(isBold: true, color: MyColors.blackColor), + ], + ), + )) + .toList() + ]) + .objectContainerView()) ], ), ), @@ -131,7 +174,7 @@ class _BasicDetailsState extends State { ); StatefulBuilder alert = StatefulBuilder(builder: (context, setState) { return AlertDialog( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(10.0))), + shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(10.0))), title: Text(LocaleKeys.confirm.tr()), content: Builder(builder: (context) { // Get available height and width of the build area of this widget. Make a choice depending on the size. @@ -143,7 +186,7 @@ class _BasicDetailsState extends State { LocaleKeys.selectType.tr(), style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), - Divider(), + const Divider(), Column( children: [ ListTile( diff --git a/lib/ui/profile/help_screen.dart b/lib/ui/profile/help_screen.dart new file mode 100644 index 0000000..9b096c3 --- /dev/null +++ b/lib/ui/profile/help_screen.dart @@ -0,0 +1,34 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; + +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; + +class HelpScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBarWidget( + context, + title: LocaleKeys.help.tr(), + ), + backgroundColor: MyColors.backgroundColor, + body: Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + (LocaleKeys.dear.tr() + " " + AppState().memberInformationList!.eMPLOYEENAME!).toText18(isBold: true), + 12.height, + LocaleKeys.assistant.tr().toText14(), + ], + ), + ), + ); + } +} diff --git a/lib/ui/profile/hierarchy_screen.dart b/lib/ui/profile/hierarchy_screen.dart new file mode 100644 index 0000000..6d81b8e --- /dev/null +++ b/lib/ui/profile/hierarchy_screen.dart @@ -0,0 +1,298 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:mohem_flutter_app/api/profile_api_client.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/hierarchy_lists.dart'; +import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class HierarchyScreen extends StatefulWidget { + @override + State createState() => _HierarchyScreenState(); +} + +class _HierarchyScreenState extends State { + SupervisorHierarchyLists? hierarchyList; + + @override + void initState() { + super.initState(); + getData("221142"); + } + + void getData(String selectedId) async { + Utils.showLoading(context); + try { + hierarchyList = await ProfileApiClient().getHierarchy(selectedId); + hierarchyList!.supervisorHierarchyList!.removeWhere((element) => element.lvl == 1); + hierarchyList!.supervisorHierarchyList = hierarchyList!.supervisorHierarchyList!.reversed.toList(); + // hierarchyList!.subordinateHierarchyList!.clear(); + setState(() {}); + Utils.hideLoading(context); + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBarWidget( + context, + title: LocaleKeys.profile_personalInformation.tr(), + ), + backgroundColor: MyColors.backgroundColor, + body: hierarchyList == null + ? const Center(child: SizedBox()) + : SizedBox( + height: double.infinity, + width: double.infinity, + child: SingleChildScrollView( + child: Column( + children: [ + ListView.builder( + itemBuilder: (BuildContext context, int index) { + return Row( + children: [ + SizedBox( + height: 78 + 12, + child: Stack( + children: [ + Align( + alignment: (index == 0) ? Alignment.bottomCenter : Alignment.topCenter, + child: SizedBox( + // height: index == 0 + // ? 40 + 6 + // : (index == hierarchyList!.supervisorHierarchyList!.length - 1) + // ? 40 + 6 + // : 78 + 6, + height: index == 0 + ? 40 + 6 + : (index == hierarchyList!.supervisorHierarchyList!.length - 1) + ? 40 + 6 + : 78 + 6 + 6, + child: Container( + height: double.infinity, + color: Colors.black, + width: 2, + ), + ), + ), + ], + ), + ), + const SizedBox( + width: 16, + child: Divider( + color: Colors.black, + thickness: 2, + ), + ), + Expanded( + child: Container( + width: double.infinity, + padding: const EdgeInsets.all(12), + margin: const EdgeInsets.only(top: 12), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: const BorderRadius.all(Radius.circular(12)), + border: Border.all(color: MyColors.lightGreyEDColor, width: 1), + ), + child: Row( + children: [ + hierarchyList?.supervisorHierarchyList![index].employeeImage == null + ? SvgPicture.asset( + "assets/images/user.svg", + height: 52, + width: 52, + ) + : CircleAvatar( + radius: 52 / 2, + backgroundImage: MemoryImage(Utils.dataFromBase64String(hierarchyList?.supervisorHierarchyList![index].employeeImage)), + backgroundColor: Colors.black, + ), + 12.width, + Expanded( + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + hierarchyList!.supervisorHierarchyList![index].employeeName.toString().toText14(isBold: true, maxlines: 1), + hierarchyList!.supervisorHierarchyList![index].positionName.toString().toText12(isBold: false, maxLine: 1), + ], + ), + ), + IconButton( + onPressed: () { + launch("tel://${hierarchyList!.supervisorHierarchyList![index].employeeMobileNumber}"); + }, + icon: Icon( + Icons.phone, + color: MyColors.gradiantEndColor, + ), + ), + ], + ), + ), + ], + ), + ), + ), + ], + ); + }, + itemCount: hierarchyList?.supervisorHierarchyList?.length ?? 0, + padding: const EdgeInsets.only(left: 12, right: 12, top: 12), + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + ), + ListView.builder( + itemBuilder: (BuildContext context, int index) { + return InkWell( + onTap: (hierarchyList!.subordinateHierarchyList![index].numOfSubordinates == 0) + ? null + : () { + getData(hierarchyList!.subordinateHierarchyList![index].employeeNumber.toString()); + }, + child: Padding( + padding: EdgeInsets.only( + left: AppState().isArabic(context) + ? 0 + : index == 0 + ? 28 + : 58, + right: !AppState().isArabic(context) + ? 0 + : index == 0 + ? 28 + : 58), + child: Row( + children: [ + SizedBox( + height: 78 + 12, + child: Stack( + children: [ + Align( + alignment: (index == 0) ? Alignment.topCenter : Alignment.topCenter, + child: SizedBox( + height: index == 0 + ? 40 + 6 + : (index == hierarchyList!.subordinateHierarchyList!.length - 1) + ? 40 + 6 + : 78 + 6 + 6, + child: Container( + height: double.infinity, + color: Colors.black, + width: 2, + ), + ), + ), + ], + ), + ), + const SizedBox( + width: 18, + child: Divider( + color: Colors.black, + thickness: 2, + ), + ), + Expanded( + child: Container( + width: double.infinity, + padding: const EdgeInsets.all(12), + margin: const EdgeInsets.only(top: 12), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: const BorderRadius.all(Radius.circular(12)), + border: Border.all(color: MyColors.lightGreyEDColor, width: 1), + ), + child: Row( + children: [ + hierarchyList?.subordinateHierarchyList![index].employeeImage == null + ? SvgPicture.asset( + "assets/images/user.svg", + height: 52, + width: 52, + ) + : CircleAvatar( + radius: 52 / 2, + backgroundImage: MemoryImage(Utils.dataFromBase64String(hierarchyList?.subordinateHierarchyList![index].employeeImage)), + backgroundColor: Colors.black, + ), + 12.width, + Expanded( + child: Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + hierarchyList!.subordinateHierarchyList![index].employeeName.toString().toText14(isBold: true, maxlines: 1), + hierarchyList!.subordinateHierarchyList![index].positionName.toString().toText12(isBold: false, maxLine: 1), + ], + ), + ), + 8.width, + Column( + children: [ + InkWell( + onTap: () { + launch("tel://${hierarchyList!.subordinateHierarchyList![index].employeeMobileNumber}"); + }, + child: const Padding( + padding: EdgeInsets.only(bottom: 10), + child: Icon( + Icons.phone, + color: MyColors.gradiantEndColor, + ), + ), + ), + if (hierarchyList!.subordinateHierarchyList![index].numOfSubordinates != 0) + Container( + decoration: const BoxDecoration( + color: MyColors.gradiantEndColor, + borderRadius: BorderRadius.all(Radius.circular(12)), + ), + width: 18, + height: 18, + alignment: Alignment.center, + child: hierarchyList!.subordinateHierarchyList![index].numOfSubordinates.toString().toTextAuto(isBold: true, color: Colors.white, fontSize: 10), + ), + ], + ), + ], + ), + ), + ], + ), + ), + ), + ], + ), + ), + ); + }, + itemCount: hierarchyList?.subordinateHierarchyList?.length ?? 0, + padding: const EdgeInsets.only(left: 12, right: 12, bottom: 12), + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/ui/profile/profile_screen.dart b/lib/ui/profile/profile_screen.dart index 6060cbf..cd45030 100644 --- a/lib/ui/profile/profile_screen.dart +++ b/lib/ui/profile/profile_screen.dart @@ -46,7 +46,7 @@ class _ProfileScreenState extends State { backgroundColor: const Color(0xffefefef), body: Stack( children: [ - memberInformationList!.eMPLOYEEIMAGE != null + memberInformationList.eMPLOYEEIMAGE != null ? Container( height: 300, margin: const EdgeInsets.only(top: 50),